[10383] Store guid instaed pointer for first user of GAMEOBJECT_TYPE_SUMMONING_RITUAL

This is more safe way in pointer store comparison with.
LAso Some related code cleanups.
This commit is contained in:
VladimirMangos 2010-08-20 12:54:35 +04:00
parent b672913633
commit 0649b508e4
5 changed files with 81 additions and 71 deletions

View file

@ -50,11 +50,10 @@ GameObject::GameObject() : WorldObject()
m_respawnDelayTime = 25;
m_lootState = GO_NOT_READY;
m_spawnedByDefault = true;
m_usetimes = 0;
m_useTimes = 0;
m_spellId = 0;
m_cooldownTime = 0;
m_goInfo = NULL;
m_ritualOwner = NULL;
m_DBTableGuid = 0;
m_rotation = 0;
@ -219,8 +218,7 @@ void GameObject::Update(uint32 /*p_time*/)
if (m_respawnTime <= time(NULL)) // timer expired
{
m_respawnTime = 0;
m_SkillupList.clear();
m_usetimes = 0;
ClearAllUsesData();
switch (GetGoType())
{
@ -336,9 +334,9 @@ void GameObject::Update(uint32 /*p_time*/)
if (uint32 max_charges = goInfo->GetCharges())
{
if (m_usetimes >= max_charges)
if (m_useTimes >= max_charges)
{
m_usetimes = 0;
m_useTimes = 0;
SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed
}
}
@ -377,16 +375,11 @@ void GameObject::Update(uint32 /*p_time*/)
if(spellId)
{
std::set<uint32>::const_iterator it = m_unique_users.begin();
std::set<uint32>::const_iterator end = m_unique_users.end();
for (; it != end; it++)
{
if (Unit* owner = Unit::GetUnit(*this, uint64(*it)))
for (GuidsSet::const_iterator itr = m_UniqueUsers.begin(); itr != m_UniqueUsers.end(); ++itr)
if (Player* owner = GetMap()->GetPlayer(*itr))
owner->CastSpell(owner, spellId, false, NULL, NULL, GetGUID());
}
m_unique_users.clear();
m_usetimes = 0;
ClearAllUsesData();
}
SetGoState(GO_STATE_READY);
@ -451,7 +444,12 @@ void GameObject::Refresh()
void GameObject::AddUniqueUse(Player* player)
{
AddUse();
m_unique_users.insert(player->GetGUIDLow());
if (m_firstUser.IsEmpty())
m_firstUser = player->GetObjectGuid();
m_UniqueUsers.insert(player->GetObjectGuid());
}
void GameObject::Delete()
@ -1179,10 +1177,6 @@ void GameObject::Use(Unit* user)
GameObjectInfo const* info = GetGOInfo();
// ritual owner is set for GO's without owner (not summoned)
if (!m_ritualOwner && !owner)
m_ritualOwner = player;
if (owner)
{
if (owner->GetTypeId() != TYPEID_PLAYER)
@ -1201,8 +1195,16 @@ void GameObject::Use(Unit* user)
}
else
{
if (player != m_ritualOwner && (info->summoningRitual.castersGrouped && !player->IsInSameRaidWith(m_ritualOwner)))
if (!m_firstUser.IsEmpty() && player->GetObjectGuid() != m_firstUser && info->summoningRitual.castersGrouped)
{
if (Group* group = player->GetGroup())
{
if (!group->IsMember(m_firstUser))
return;
}
else
return;
}
spellCaster = player;
}
@ -1217,20 +1219,20 @@ void GameObject::Use(Unit* user)
triggered = true;
}
// full amount unique participants including original summoner
if (GetUniqueUseCount() == info->summoningRitual.reqParticipants)
{
spellCaster = m_ritualOwner ? m_ritualOwner : spellCaster;
// full amount unique participants including original summoner, need more
if (GetUniqueUseCount() < info->summoningRitual.reqParticipants)
return;
spellCaster = GetMap()->GetPlayer(m_firstUser);
spellId = info->summoningRitual.spellId;
if (spellId == 62330) // GO store nonexistent spell, replace by expected
{
spellId = 61993;
// spell have reagent and mana cost but it not expected use its
// it triggered spell in fact casted at currently channeled GO
spellId = 61993;
triggered = true;
}
// finish owners spell
if (owner)
@ -1239,18 +1241,9 @@ void GameObject::Use(Unit* user)
// can be deleted now, if
if (!info->summoningRitual.ritualPersistent)
SetLootState(GO_JUST_DEACTIVATED);
else
{
// reset ritual for this GO
m_ritualOwner = NULL;
m_unique_users.clear();
m_usetimes = 0;
}
}
else
{
return;
}
ClearAllUsesData();
// go to end function to spell casting
break;
@ -1576,3 +1569,13 @@ float GameObject::GetObjectBoundingRadius() const
return DEFAULT_WORLD_OBJECT_SIZE;
}
bool GameObject::IsInSkillupList(Player* player) const
{
return m_SkillupSet.find(player->GetObjectGuid()) != m_SkillupSet.end();
}
void GameObject::AddToSkillupList(Player* player)
{
m_SkillupSet.insert(player->GetObjectGuid());
}

View file

@ -667,20 +667,22 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
LootState getLootState() const { return m_lootState; }
void SetLootState(LootState s) { m_lootState = s; }
void AddToSkillupList(uint32 PlayerGuidLow) { m_SkillupList.push_back(PlayerGuidLow); }
bool IsInSkillupList(uint32 PlayerGuidLow) const
void AddToSkillupList(Player* player);
bool IsInSkillupList(Player* player) const;
void ClearSkillupList() { m_SkillupSet.clear(); }
void ClearAllUsesData()
{
for (std::list<uint32>::const_iterator i = m_SkillupList.begin(); i != m_SkillupList.end(); ++i)
if (*i == PlayerGuidLow) return true;
return false;
ClearSkillupList();
m_useTimes = 0;
m_firstUser.Clear();
m_UniqueUsers.clear();
}
void ClearSkillupList() { m_SkillupList.clear(); }
void AddUniqueUse(Player* player);
void AddUse() { ++m_usetimes; }
void AddUse() { ++m_useTimes; }
uint32 GetUseCount() const { return m_usetimes; }
uint32 GetUniqueUseCount() const { return m_unique_users.size(); }
uint32 GetUseCount() const { return m_useTimes; }
uint32 GetUniqueUseCount() const { return m_UniqueUsers.size(); }
void SaveRespawnTime();
@ -714,11 +716,16 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
bool m_spawnedByDefault;
time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction).
// For traps this: spell casting cooldown, for doors/buttons: reset time.
std::list<uint32> m_SkillupList;
Player* m_ritualOwner; // used for GAMEOBJECT_TYPE_SUMMONING_RITUAL where GO is not summoned (no owner)
std::set<uint32> m_unique_users;
uint32 m_usetimes;
typedef std::set<ObjectGuid> GuidsSet;
GuidsSet m_SkillupSet; // players that already have skill-up at GO use
uint32 m_useTimes; // amount uses/charges triggered
// collected only for GAMEOBJECT_TYPE_SUMMONING_RITUAL
ObjectGuid m_firstUser; // first GO user, in most used cases owner, but in some cases no, for example non-summoned multi-use GAMEOBJECT_TYPE_SUMMONING_RITUAL
GuidsSet m_UniqueUsers; // all players who use item, some items activated after specific amount unique uses
uint32 m_DBTableGuid; ///< For new or temporary gameobjects is 0 for saved it is lowguid
GameObjectInfo const* m_goInfo;

View file

@ -364,7 +364,7 @@ void WorldSession::DoLootRelease(ObjectGuid lguid)
}
else if (go->GetGoType() == GAMEOBJECT_TYPE_FISHINGHOLE)
{ // The fishing hole used once more
go->AddUse(); // if the max usage is reached, will be despawned in next tick
go->AddUse(); // if the max usage is reached, will be despawned at next tick
if (go->GetUseCount() >= urand(go->GetGOInfo()->fishinghole.minSuccessOpens,go->GetGOInfo()->fishinghole.maxSuccessOpens))
{
go->SetLootState(GO_JUST_DEACTIVATED);

View file

@ -3731,9 +3731,9 @@ void Spell::EffectOpenLock(SpellEffectIndex eff_idx)
if (gameObjTarget)
{
// Allow one skill-up until respawned
if (!gameObjTarget->IsInSkillupList(player->GetGUIDLow()) &&
if (!gameObjTarget->IsInSkillupList(player) &&
player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue))
gameObjTarget->AddToSkillupList(player->GetGUIDLow());
gameObjTarget->AddToSkillupList(player);
}
else if (itemTarget)
{

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10382"
#define REVISION_NR "10383"
#endif // __REVISION_NR_H__