*Implement spell effect wmo damage.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-05-21 10:01:03 -05:00
parent b372a5ba25
commit 4ed847a6e3
10 changed files with 162 additions and 5 deletions
+65
View File
@@ -168,6 +168,8 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
// Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER) if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER)
m_charges = goinfo->spellcaster.charges; m_charges = goinfo->spellcaster.charges;
else if(goinfo->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
m_health = goinfo->destructibleBuilding.damagedHealth;
//Notify the map's instance data. //Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map. //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); 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 // overwrite WorldObject function for proper name localization
const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const
{ {
+12 -1
View File
@@ -346,10 +346,17 @@ struct GameObjectInfo
//33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
struct struct
{ {
uint32 dmgPctState1; //0 uint32 damagedHealth; //0
uint32 dmgPctState2; //1 uint32 dmgPctState2; //1
uint32 state1Name; //2 uint32 state1Name; //2
uint32 state2Name; //3 uint32 state2Name; //3
uint32 damagedDisplayId; //4
uint32 destroyedHealth; //5
uint32 unk6;
uint32 unk7;
uint32 unk8;
uint32 unk9;
uint32 destroyedDisplayId; //10
} destructibleBuilding; } destructibleBuilding;
//34 GAMEOBJECT_TYPE_TRAPDOOR //34 GAMEOBJECT_TYPE_TRAPDOOR
struct struct
@@ -614,6 +621,9 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
void CastSpell(Unit *target, uint32 spell); void CastSpell(Unit *target, uint32 spell);
void SendCustomAnim(); void SendCustomAnim();
bool IsInRange(float x, float y, float z, float radius) const;
void TakenDamage(uint32 damage);
void Rebuild();
protected: protected:
uint32 m_charges; // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) uint32 m_charges; // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
uint32 m_spellId; uint32 m_spellId;
@@ -622,6 +632,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
LootState m_lootState; LootState m_lootState;
bool m_spawnedByDefault; bool m_spawnedByDefault;
time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction). 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. // For traps this: spell casting cooldown, for doors/buttons: reset time.
std::list<uint32> m_SkillupList; std::list<uint32> m_SkillupList;
+30
View File
@@ -630,6 +630,24 @@ namespace Trinity
NearestGameObjectFishingHole(NearestGameObjectFishingHole const&); 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) // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO)
class NearestGameObjectEntryInObjectRangeCheck class NearestGameObjectEntryInObjectRangeCheck
{ {
@@ -1042,6 +1060,18 @@ namespace Trinity
uint32 entry; 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 class AllCreaturesOfEntryInRange
{ {
public: public:
+1 -1
View File
@@ -634,7 +634,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if( updateMask->GetBit( index ) ) if( updateMask->GetBit( index ) )
{ {
// send in current format (float as float, uint32 as uint32) // send in current format (float as float, uint32 as uint32)
if ( index == GAMEOBJECT_DYNAMIC ) if (false && index == GAMEOBJECT_DYNAMIC )
{ {
if(IsActivateToQuest ) if(IsActivateToQuest )
{ {
+3 -1
View File
@@ -1178,7 +1178,9 @@ enum GameObjectFlags
GO_FLAG_TRANSPORT = 0x00000008, //any kind of transport? Object can transport (elevator, boat, car) GO_FLAG_TRANSPORT = 0x00000008, //any kind of transport? Object can transport (elevator, boat, car)
GO_FLAG_UNK1 = 0x00000010, // GO_FLAG_UNK1 = 0x00000010, //
GO_FLAG_NODESPAWN = 0x00000020, //never despawn, typically for doors, they just change state 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 enum TextEmotes
+29
View File
@@ -2197,7 +2197,36 @@ void Spell::SetTargetMap(uint32 i, uint32 cur)
break; break;
case TARGET_OBJECT_AREA_SRC: // fix me case TARGET_OBJECT_AREA_SRC: // fix me
case TARGET_OBJECT_AREA_DST: 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; break;
}
case TARGET_UNIT_PARTY_TARGET: case TARGET_UNIT_PARTY_TARGET:
m_targets.getUnitTarget()->GetPartyMember(unitList, radius); m_targets.getUnitTarget()->GetPartyMember(unitList, radius);
break; break;
+2
View File
@@ -360,6 +360,8 @@ class Spell
void EffectKillCredit(uint32 i); void EffectKillCredit(uint32 i);
void EffectQuestFail(uint32 i); void EffectQuestFail(uint32 i);
void EffectRedirectThreat(uint32 i); void EffectRedirectThreat(uint32 i);
void EffectWMODamage(uint32 i);
void EffectWMORepair(uint32 i);
void EffectActivateRune(uint32 i); void EffectActivateRune(uint32 i);
void EffectTitanGrip(uint32 i); void EffectTitanGrip(uint32 i);
void EffectEnchantItemPrismatic(uint32 i); void EffectEnchantItemPrismatic(uint32 i);
+14 -2
View File
@@ -151,8 +151,8 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK &Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK
&Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER &Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER
&Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT &Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
&Spell::EffectUnused, // 87 SPELL_EFFECT_WMO_DAMAGE &Spell::EffectWMODamage, // 87 SPELL_EFFECT_WMO_DAMAGE
&Spell::EffectUnused, // 88 SPELL_EFFECT_WMO_REPAIR &Spell::EffectWMORepair, // 88 SPELL_EFFECT_WMO_REPAIR
&Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE &Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE
&Spell::EffectKillCredit, // 90 SPELL_EFFECT_KILL_CREDIT &Spell::EffectKillCredit, // 90 SPELL_EFFECT_KILL_CREDIT
&Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash &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()); 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) void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties)
{ {
Unit *caster = m_originalCaster; Unit *caster = m_originalCaster;
+5
View File
@@ -85,6 +85,11 @@ SpellMgr::SpellMgr()
case SPELL_EFFECT_138: case SPELL_EFFECT_138:
EffectTargetType[i] = SPELL_REQUIRE_CASTER; EffectTargetType[i] = SPELL_REQUIRE_CASTER;
break; break;
//case SPELL_EFFECT_WMO_DAMAGE:
//case SPELL_EFFECT_WMO_REPAIR:
//case SPELL_EFFECT_WMO_CHANGE:
// EffectTargetType[i] = SPELL_REQUIRE_GOBJECT;
// break;
default: default:
EffectTargetType[i] = SPELL_REQUIRE_UNIT; EffectTargetType[i] = SPELL_REQUIRE_UNIT;
break; break;
+1
View File
@@ -82,6 +82,7 @@ enum SpellEffectTargetTypes
SPELL_REQUIRE_DEST, SPELL_REQUIRE_DEST,
SPELL_REQUIRE_ITEM, SPELL_REQUIRE_ITEM,
SPELL_REQUIRE_CASTER, SPELL_REQUIRE_CASTER,
SPELL_REQUIRE_GOBJECT,
}; };
enum SpellSelectTargetTypes enum SpellSelectTargetTypes