diff options
author | megamage <none@none> | 2009-05-21 10:01:03 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-05-21 10:01:03 -0500 |
commit | 4ed847a6e329ebaa3a7951b5a44cbc6065dc7db2 (patch) | |
tree | 08ec6c31f54ed3adbd84f40d2b3eb123f5cd0d0f /src | |
parent | b372a5ba25361c8cb0792abe6e5221a3413fc40c (diff) |
*Implement spell effect wmo damage.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/GameObject.cpp | 65 | ||||
-rw-r--r-- | src/game/GameObject.h | 13 | ||||
-rw-r--r-- | src/game/GridNotifiers.h | 30 | ||||
-rw-r--r-- | src/game/Object.cpp | 2 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 4 | ||||
-rw-r--r-- | src/game/Spell.cpp | 29 | ||||
-rw-r--r-- | src/game/Spell.h | 2 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 16 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 5 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 1 |
10 files changed, 162 insertions, 5 deletions
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index a6292a9964b..9a415f8c991 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -168,6 +168,8 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER) m_charges = goinfo->spellcaster.charges; + else if(goinfo->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) + m_health = goinfo->destructibleBuilding.damagedHealth; //Notify the map's instance data. //Only works if you create the object in it, not if it is moves to that map. @@ -1399,6 +1401,69 @@ void GameObject::SendCustomAnim() SendMessageToSet(&data, true); } +bool GameObject::IsInRange(float x, float y, float z, float radius) const +{ + GameObjectDisplayInfoEntry const * info = sGameObjectDisplayInfoStore.LookupEntry(GetUInt32Value(GAMEOBJECT_DISPLAYID)); + if(!info) + return IsWithinDist3d(x, y, z, radius); + + float sinA = sin(GetOrientation()); + float cosA = cos(GetOrientation()); + float dx = x - GetPositionX(); + float dy = y - GetPositionY(); + float dz = z - GetPositionZ(); + float dist = sqrt(dx*dx + dy*dy); + float sinB = dx / dist; + float cosB = dy / dist; + dx = dist * (cosA * cosB + sinA * sinB); + dy = dist * (cosA * sinB - sinA * cosB); + return dx < info->maxX + radius && dx > info->minX - radius + && dy < info->maxY + radius && dy > info->minY - radius + && dz < info->maxZ + radius && dz > info->minZ - radius; +} + +void GameObject::TakenDamage(uint32 damage) +{ + if(!m_health) + return; + + if(m_health > damage) + { + m_health -= damage; + return; + } + + m_health = 0; + + if(HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED)) // from damaged to destroyed + { + RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); + SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); + SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->destructibleBuilding.destroyedDisplayId); + m_health = 0; + } + else // from undamaged to damaged + { + SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); + SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->destructibleBuilding.damagedDisplayId); + if(m_goInfo->destructibleBuilding.destroyedDisplayId) + { + m_health = m_goInfo->destructibleBuilding.destroyedHealth; + if(!m_health) + m_health = 1; + } + else + m_health = 0; + } +} + +void GameObject::Rebuild() +{ + RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED + GO_FLAG_DESTROYED); + SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->displayId); + m_health = m_goInfo->destructibleBuilding.damagedHealth; +} + // overwrite WorldObject function for proper name localization const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const { diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 37ccf1c6b8f..befe9c23a8b 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -346,10 +346,17 @@ struct GameObjectInfo //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING struct { - uint32 dmgPctState1; //0 + uint32 damagedHealth; //0 uint32 dmgPctState2; //1 uint32 state1Name; //2 uint32 state2Name; //3 + uint32 damagedDisplayId; //4 + uint32 destroyedHealth; //5 + uint32 unk6; + uint32 unk7; + uint32 unk8; + uint32 unk9; + uint32 destroyedDisplayId; //10 } destructibleBuilding; //34 GAMEOBJECT_TYPE_TRAPDOOR struct @@ -614,6 +621,9 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject void CastSpell(Unit *target, uint32 spell); void SendCustomAnim(); + bool IsInRange(float x, float y, float z, float radius) const; + void TakenDamage(uint32 damage); + void Rebuild(); protected: uint32 m_charges; // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) uint32 m_spellId; @@ -622,6 +632,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject LootState m_lootState; bool m_spawnedByDefault; time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction). + uint32 m_health; // For traps this: spell casting cooldown, for doors/buttons: reset time. std::list<uint32> m_SkillupList; diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index a9925f67406..b45f7f6d675 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -630,6 +630,24 @@ namespace Trinity NearestGameObjectFishingHole(NearestGameObjectFishingHole const&); }; + class NearestGameObjectCheck + { + public: + NearestGameObjectCheck(WorldObject const& obj) : i_obj(obj), i_range(999) {} + bool operator()(GameObject* go) + { + i_range = i_obj.GetDistance(go); // use found GO range as new range limit for next check + return true; + } + float GetLastRange() const { return i_range; } + private: + WorldObject const& i_obj; + float i_range; + + // prevent clone this object + NearestGameObjectCheck(NearestGameObjectCheck const&); + }; + // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO) class NearestGameObjectEntryInObjectRangeCheck { @@ -1042,6 +1060,18 @@ namespace Trinity uint32 entry; }; + class GameObjectInRangeCheck + { + public: + GameObjectInRangeCheck(float _x, float _y, float _z, float _range) : x(_x), y(_y), z(_z), range(_range) {} + bool operator() (GameObject* go) + { + return go->IsInRange(x, y, z, range); + } + private: + float x, y, z, range; + }; + class AllCreaturesOfEntryInRange { public: diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 634702daab1..554f11f0a95 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -634,7 +634,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask if( updateMask->GetBit( index ) ) { // send in current format (float as float, uint32 as uint32) - if ( index == GAMEOBJECT_DYNAMIC ) + if (false && index == GAMEOBJECT_DYNAMIC ) { if(IsActivateToQuest ) { diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index b11f86a7408..0eacd37dae2 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1178,7 +1178,9 @@ enum GameObjectFlags GO_FLAG_TRANSPORT = 0x00000008, //any kind of transport? Object can transport (elevator, boat, car) GO_FLAG_UNK1 = 0x00000010, // GO_FLAG_NODESPAWN = 0x00000020, //never despawn, typically for doors, they just change state - GO_FLAG_TRIGGERED = 0x00000040 //typically, summoned objects. Triggered by spell or other events + GO_FLAG_TRIGGERED = 0x00000040, //typically, summoned objects. Triggered by spell or other events + GO_FLAG_DAMAGED = 0x00000200, + GO_FLAG_DESTROYED = 0x00000400, }; enum TextEmotes diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index ac9eb8f5593..d23491f9d68 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2197,7 +2197,36 @@ void Spell::SetTargetMap(uint32 i, uint32 cur) break; case TARGET_OBJECT_AREA_SRC: // fix me case TARGET_OBJECT_AREA_DST: + { + float x, y, z; + if(cur == TARGET_OBJECT_AREA_SRC) + { + if(m_targets.HasSrc()) + { + x = m_targets.m_srcX; + y = m_targets.m_srcY; + z = m_targets.m_srcZ; + } + else + break; + } + else if(m_targets.HasDst()) + { + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + } + else + break; + + Trinity::GameObjectInRangeCheck check(x, y, z, radius + 50); + std::list<GameObject*> goList; + Trinity::GameObjectListSearcher<Trinity::GameObjectInRangeCheck> searcher(m_caster, goList, check); + m_caster->GetMap()->VisitGrid(x, y, radius, searcher); + for(std::list<GameObject*>::iterator itr = goList.begin(); itr != goList.end(); ++itr) + AddGOTarget(*itr, i); break; + } case TARGET_UNIT_PARTY_TARGET: m_targets.getUnitTarget()->GetPartyMember(unitList, radius); break; diff --git a/src/game/Spell.h b/src/game/Spell.h index ee045faa017..ef0e3266b4e 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -360,6 +360,8 @@ class Spell void EffectKillCredit(uint32 i); void EffectQuestFail(uint32 i); void EffectRedirectThreat(uint32 i); + void EffectWMODamage(uint32 i); + void EffectWMORepair(uint32 i); void EffectActivateRune(uint32 i); void EffectTitanGrip(uint32 i); void EffectEnchantItemPrismatic(uint32 i); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index ada90e881ae..a3f1a637f9a 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -151,8 +151,8 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK &Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER &Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT - &Spell::EffectUnused, // 87 SPELL_EFFECT_WMO_DAMAGE - &Spell::EffectUnused, // 88 SPELL_EFFECT_WMO_REPAIR + &Spell::EffectWMODamage, // 87 SPELL_EFFECT_WMO_DAMAGE + &Spell::EffectWMORepair, // 88 SPELL_EFFECT_WMO_REPAIR &Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE &Spell::EffectKillCredit, // 90 SPELL_EFFECT_KILL_CREDIT &Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash @@ -6485,6 +6485,18 @@ void Spell::EffectRedirectThreat(uint32 /*i*/) m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID()); } +void Spell::EffectWMODamage(uint32 /*i*/) +{ + if(gameObjTarget && gameObjTarget->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) + gameObjTarget->TakenDamage((uint32)damage); +} + +void Spell::EffectWMORepair(uint32 /*i*/) +{ + if(gameObjTarget && gameObjTarget->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) + gameObjTarget->Rebuild(); +} + void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties) { Unit *caster = m_originalCaster; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index e60931dc11e..08bf88e45da 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -85,6 +85,11 @@ SpellMgr::SpellMgr() case SPELL_EFFECT_138: EffectTargetType[i] = SPELL_REQUIRE_CASTER; break; + //case SPELL_EFFECT_WMO_DAMAGE: + //case SPELL_EFFECT_WMO_REPAIR: + //case SPELL_EFFECT_WMO_CHANGE: + // EffectTargetType[i] = SPELL_REQUIRE_GOBJECT; + // break; default: EffectTargetType[i] = SPELL_REQUIRE_UNIT; break; diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 66874f02b57..a313c525dc7 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -82,6 +82,7 @@ enum SpellEffectTargetTypes SPELL_REQUIRE_DEST, SPELL_REQUIRE_ITEM, SPELL_REQUIRE_CASTER, + SPELL_REQUIRE_GOBJECT, }; enum SpellSelectTargetTypes |