mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
[8205] Really use trap GO charges and avoid casting in despawned state.
* Drop horribale hack with stored charges amount, use instead GO info charges data as expected. * Count trap activations as charge uses if it have limited charges. * Check trap reactions only in ready spawned state.
This commit is contained in:
parent
349216d5d7
commit
39833b0069
3 changed files with 96 additions and 83 deletions
|
|
@ -50,7 +50,6 @@ GameObject::GameObject() : WorldObject()
|
|||
m_spawnedByDefault = true;
|
||||
m_usetimes = 0;
|
||||
m_spellId = 0;
|
||||
m_charges = 5;
|
||||
m_cooldownTime = 0;
|
||||
m_goInfo = NULL;
|
||||
|
||||
|
|
@ -156,10 +155,6 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
|
|||
|
||||
SetGoAnimProgress(animprogress);
|
||||
|
||||
// Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
|
||||
if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER)
|
||||
m_charges = goinfo->spellcaster.charges;
|
||||
|
||||
//Notify the map's instance data.
|
||||
//Only works if you create the object in it, not if it is moves to that map.
|
||||
//Normally non-players do not teleport to other maps.
|
||||
|
|
@ -282,99 +277,107 @@ void GameObject::Update(uint32 /*p_time*/)
|
|||
}
|
||||
}
|
||||
|
||||
// traps can have time and can not have
|
||||
GameObjectInfo const* goInfo = GetGOInfo();
|
||||
if(goInfo->type == GAMEOBJECT_TYPE_TRAP)
|
||||
if(isSpawned())
|
||||
{
|
||||
// traps
|
||||
Unit* owner = GetOwner();
|
||||
Unit* ok = NULL; // pointer to appropriate target if found any
|
||||
|
||||
if(m_cooldownTime >= time(NULL))
|
||||
return;
|
||||
|
||||
bool IsBattleGroundTrap = false;
|
||||
//FIXME: this is activation radius (in different casting radius that must be selected from spell data)
|
||||
//TODO: move activated state code (cast itself) to GO_ACTIVATED, in this place only check activating and set state
|
||||
float radius = goInfo->trap.radius;
|
||||
if(!radius)
|
||||
// traps can have time and can not have
|
||||
GameObjectInfo const* goInfo = GetGOInfo();
|
||||
if(goInfo->type == GAMEOBJECT_TYPE_TRAP)
|
||||
{
|
||||
if(goInfo->trap.cooldown != 3) // cast in other case (at some triggering/linked go/etc explicit call)
|
||||
if(m_cooldownTime >= time(NULL))
|
||||
return;
|
||||
else
|
||||
{
|
||||
if(m_respawnTime > 0)
|
||||
break;
|
||||
|
||||
radius = goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3
|
||||
IsBattleGroundTrap = true;
|
||||
// traps
|
||||
Unit* owner = GetOwner();
|
||||
Unit* ok = NULL; // pointer to appropriate target if found any
|
||||
|
||||
bool IsBattleGroundTrap = false;
|
||||
//FIXME: this is activation radius (in different casting radius that must be selected from spell data)
|
||||
//TODO: move activated state code (cast itself) to GO_ACTIVATED, in this place only check activating and set state
|
||||
float radius = goInfo->trap.radius;
|
||||
if(!radius)
|
||||
{
|
||||
if(goInfo->trap.cooldown != 3) // cast in other case (at some triggering/linked go/etc explicit call)
|
||||
return;
|
||||
else
|
||||
{
|
||||
if(m_respawnTime > 0)
|
||||
break;
|
||||
|
||||
radius = goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3
|
||||
IsBattleGroundTrap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NeedDespawn = (goInfo->trap.charges != 0);
|
||||
CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY()));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
|
||||
CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY()));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
|
||||
// Note: this hack with search required until GO casting not implemented
|
||||
// search unfriendly creature
|
||||
if(owner && NeedDespawn) // hunter trap
|
||||
{
|
||||
MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius);
|
||||
MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(this,ok, u_check);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
|
||||
cell_lock->Visit(cell_lock, grid_object_checker, *GetMap());
|
||||
|
||||
// or unfriendly player/pet
|
||||
if(!ok)
|
||||
// Note: this hack with search required until GO casting not implemented
|
||||
// search unfriendly creature
|
||||
if(owner && goInfo->trap.charges > 0) // hunter trap
|
||||
{
|
||||
TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
|
||||
MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius);
|
||||
MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(this,ok, u_check);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
|
||||
cell_lock->Visit(cell_lock, grid_object_checker, *GetMap());
|
||||
|
||||
// or unfriendly player/pet
|
||||
if(!ok)
|
||||
{
|
||||
TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
|
||||
cell_lock->Visit(cell_lock, world_object_checker, *GetMap());
|
||||
}
|
||||
}
|
||||
else // environmental trap
|
||||
{
|
||||
// environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support
|
||||
|
||||
// affect only players
|
||||
Player* p_ok = NULL;
|
||||
MaNGOS::AnyPlayerInObjectRangeCheck p_check(this, radius);
|
||||
MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck> checker(this,p_ok, p_check);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
|
||||
cell_lock->Visit(cell_lock, world_object_checker, *GetMap());
|
||||
ok = p_ok;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
Unit *caster = owner ? owner : ok;
|
||||
|
||||
caster->CastSpell(ok, goInfo->trap.spellId, true, 0, 0, GetGUID());
|
||||
m_cooldownTime = time(NULL) + 4; // 4 seconds
|
||||
|
||||
// count charges
|
||||
if(goInfo->trap.charges > 0)
|
||||
AddUse();
|
||||
|
||||
if(IsBattleGroundTrap && ok->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
//BattleGround gameobjects case
|
||||
if(((Player*)ok)->InBattleGround())
|
||||
if(BattleGround *bg = ((Player*)ok)->GetBattleGround())
|
||||
bg->HandleTriggerBuff(GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
else // environmental trap
|
||||
|
||||
if(uint32 max_charges = goInfo->GetCharges())
|
||||
{
|
||||
// environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support
|
||||
|
||||
// affect only players
|
||||
Player* p_ok = NULL;
|
||||
MaNGOS::AnyPlayerInObjectRangeCheck p_check(this, radius);
|
||||
MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck> checker(this,p_ok, p_check);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
|
||||
cell_lock->Visit(cell_lock, world_object_checker, *GetMap());
|
||||
ok = p_ok;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
Unit *caster = owner ? owner : ok;
|
||||
|
||||
caster->CastSpell(ok, goInfo->trap.spellId, true, 0, 0, GetGUID());
|
||||
m_cooldownTime = time(NULL) + 4; // 4 seconds
|
||||
|
||||
if(NeedDespawn)
|
||||
SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed
|
||||
|
||||
if(IsBattleGroundTrap && ok->GetTypeId() == TYPEID_PLAYER)
|
||||
if (m_usetimes >= max_charges)
|
||||
{
|
||||
//BattleGround gameobjects case
|
||||
if(((Player*)ok)->InBattleGround())
|
||||
if(BattleGround *bg = ((Player*)ok)->GetBattleGround())
|
||||
bg->HandleTriggerBuff(GetGUID());
|
||||
m_usetimes = 0;
|
||||
SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_charges && m_usetimes >= m_charges)
|
||||
SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed
|
||||
|
||||
break;
|
||||
}
|
||||
case GO_ACTIVATED:
|
||||
|
|
|
|||
|
|
@ -442,6 +442,17 @@ struct GameObjectInfo
|
|||
}
|
||||
}
|
||||
|
||||
uint32 GetCharges() const // despawn at uses amount
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case GAMEOBJECT_TYPE_TRAP: return trap.charges;
|
||||
case GAMEOBJECT_TYPE_GUARDPOST: return guardpost.charges;
|
||||
case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.charges;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetLinkedGameObjectEntry() const
|
||||
{
|
||||
switch(type)
|
||||
|
|
@ -663,7 +674,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
|||
bool isActiveObject() const { return false; }
|
||||
uint64 GetRotation() const { return m_rotation; }
|
||||
protected:
|
||||
uint32 m_charges; // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
|
||||
uint32 m_spellId;
|
||||
time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()),
|
||||
uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "8204"
|
||||
#define REVISION_NR "8205"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue