aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/GameObject.cpp65
-rw-r--r--src/game/GameObject.h13
-rw-r--r--src/game/GridNotifiers.h30
-rw-r--r--src/game/Object.cpp2
-rw-r--r--src/game/SharedDefines.h4
-rw-r--r--src/game/Spell.cpp29
-rw-r--r--src/game/Spell.h2
-rw-r--r--src/game/SpellEffects.cpp16
-rw-r--r--src/game/SpellMgr.cpp5
-rw-r--r--src/game/SpellMgr.h1
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