From a2ff999fd30a04e4954993f949b94024c50ffd5e Mon Sep 17 00:00:00 2001 From: balrok Date: Sun, 18 Oct 2009 21:01:55 +0200 Subject: [PATCH] [8676] implemented dead-visible creature flags_extra with this flag you can specify a creature to be only visible for dead players - this removes all hacks from spiritguides/spirithealers from code and allows some other special creatures i decided to not implement an extra deathstate cause actualy those creatures are almost equal to living ones --- sql/mangos.sql | 2 +- .../8676_01_mangos_creature_template.sql | 5 +++++ sql/updates/Makefile.am | 2 ++ src/game/AggressorAI.cpp | 2 +- src/game/Creature.cpp | 20 ++++--------------- src/game/Creature.h | 1 + src/game/ObjectGridLoader.cpp | 2 -- src/game/Player.cpp | 5 ++--- src/game/Spell.cpp | 6 +++--- src/game/SpellMgr.h | 3 +-- src/game/Unit.cpp | 3 ++- src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 13 files changed, 24 insertions(+), 31 deletions(-) create mode 100644 sql/updates/8676_01_mangos_creature_template.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 81acb176b..26d1b3c5f 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8618_01_mangos_spell_proc_event` bit(1) default NULL + `required_8676_01_mangos_creature_template` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- diff --git a/sql/updates/8676_01_mangos_creature_template.sql b/sql/updates/8676_01_mangos_creature_template.sql new file mode 100644 index 000000000..f0409da15 --- /dev/null +++ b/sql/updates/8676_01_mangos_creature_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8618_01_mangos_spell_proc_event required_8676_01_mangos_creature_template bit; + +-- set all spirithealer and spiritguides to be visible only for dead people +UPDATE creature_template SET flags_extra = flags_extra | 0x200 +WHERE npcflag & (16384 | 32768); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index af201b913..5137ff8d4 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -135,6 +135,7 @@ pkgdata_DATA = \ 8608_01_mangos_mangos_string.sql \ 8608_02_mangos_battleground_events.sql \ 8618_01_mangos_spell_proc_event.sql \ + 8676_01_mangos_creature_template.sql \ README ## Additional files to include when running 'make dist' @@ -250,4 +251,5 @@ EXTRA_DIST = \ 8608_01_mangos_mangos_string.sql \ 8608_02_mangos_battleground_events.sql \ 8618_01_mangos_spell_proc_event.sql \ + 8676_01_mangos_creature_template.sql \ README diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 9d436ef09..faa4e608d 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -46,7 +46,7 @@ AggressorAI::MoveInLineOfSight(Unit *u) if( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE ) return; - if( !m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() && + if( !(m_creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST) && !m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() && ( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) && u->isInAccessablePlaceFor(m_creature) ) { diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 0c227ff30..b666a0289 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -336,15 +336,6 @@ void Creature::Update(uint32 diff) break; case DEAD: { - if (isSpiritService()) - { - Unit::Update( diff ); - // do not allow the AI to be changed during update - m_AI_locked = true; - i_AI->UpdateAI(diff); - m_AI_locked = false; - break; // they don't should respawn - } if( m_respawnTime <= time(NULL) ) { DEBUG_LOG("Respawning..."); @@ -1563,10 +1554,7 @@ void Creature::setDeathState(DeathState s) RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); AddMonsterMoveFlag(MONSTER_MOVE_WALK); SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag); - if (!isSpiritService()) - Unit::setDeathState(ALIVE); - else - Unit::setDeathState(DEAD); + Unit::setDeathState(ALIVE); clearUnitState(UNIT_STAT_ALL_STATE); i_motionMaster.Clear(); SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); @@ -1761,7 +1749,7 @@ bool Creature::IsVisibleInGridForPlayer(Player* pl) const // Live player (or with not release body see live creatures or death creatures with corpse disappearing time > 0 if(pl->isAlive() || pl->GetDeathTimer() > 0) { - if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INVISIBLE) + if(GetCreatureInfo()->flags_extra & (CREATURE_FLAG_EXTRA_INVISIBLE | CREATURE_FLAG_EXTRA_GHOST)) return false; return (isAlive() || m_deathTimer > 0 || (m_isDeadByDefault && m_deathState == CORPSE)); } @@ -1778,8 +1766,8 @@ bool Creature::IsVisibleInGridForPlayer(Player* pl) const } } - // Dead player see Spirit Healer or Spirit Guide - if(isSpiritService()) + // Dead player see ghosts + if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST) return true; // and not see any other diff --git a/src/game/Creature.h b/src/game/Creature.h index f0025a9c6..d41364ce2 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -143,6 +143,7 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP CREATURE_FLAG_EXTRA_INVISIBLE = 0x00000080, // creature is always invisible for player (mostly trigger creatures) CREATURE_FLAG_EXTRA_NOT_TAUNTABLE = 0x00000100, // creature is immune to taunt auras and effect attack me + CREATURE_FLAG_EXTRA_GHOST = 0x00000200, // creature is only visible for dead players }; // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index 89f3fcfea..9c60cd2b1 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -102,8 +102,6 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair) Cell cell(cell_pair); obj->SetCurrentCell(cell); - if(obj->isSpiritService()) - obj->setDeathState(DEAD); } template diff --git a/src/game/Player.cpp b/src/game/Player.cpp index ed1232e8e..e7ac1ccf1 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2098,15 +2098,14 @@ Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask) return NULL; // player check - if(!CanInteractWithNPCs(!unit->isSpiritService())) + if(!CanInteractWithNPCs(!(unit->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST))) return NULL; // appropriate npc type if(npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask )) return NULL; - // alive or spirit healer - if(!unit->isAlive() && (!unit->isSpiritService() || isAlive() )) + if (isAlive() && !unit->isAlive()) return NULL; // not allow interaction under control, but allow with own pets diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 59dfc602f..9e56a833b 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3860,9 +3860,6 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_NOT_READY; } - if (IsDeathOnlySpell(m_spellInfo) && m_caster->isAlive()) - return SPELL_FAILED_TARGET_NOT_DEAD; - // only allow triggered spells if at an ended battleground if( !m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER) if(BattleGround * bg = ((Player*)m_caster)->GetBattleGround()) @@ -3933,6 +3930,9 @@ SpellCastResult Spell::CheckCast(bool strict) if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot))) return SPELL_FAILED_TARGET_AURASTATE; + if (IsDeathOnlySpell(m_spellInfo) && target->isAlive()) + return SPELL_FAILED_TARGET_NOT_DEAD; + // Target aura req check if need if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 342456f08..f8675224c 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -203,8 +203,7 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto) inline bool IsDeathOnlySpell(SpellEntry const *spellInfo) { return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_CAST_ON_DEAD - || spellInfo->Id == 2584 - || spellInfo->Id == 22011; + || spellInfo->Id == 2584; } inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index f6c9dc42d..6518b56c6 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9603,7 +9603,8 @@ bool Unit::isTargetableForAttack(bool inverseAlive /*=false*/) const if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)) return false; - if (!(isAlive() != inverseAlive)) + // target is dead or has ghost-flag + if ((!isAlive() || (GetTypeId() == TYPEID_UNIT && ((Creature *)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_GHOST)) != inverseAlive) return false; return IsInWorld() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 989bedd37..5f38308c8 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8675" + #define REVISION_NR "8676" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index ddf639c65..55c964243 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8596_01_characters_bugreport" - #define REVISION_DB_MANGOS "required_8618_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_8676_01_mangos_creature_template" #define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters" #endif // __REVISION_SQL_H__