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

View file

@ -364,7 +364,7 @@ void WorldSession::DoLootRelease(ObjectGuid lguid)
} }
else if (go->GetGoType() == GAMEOBJECT_TYPE_FISHINGHOLE) else if (go->GetGoType() == GAMEOBJECT_TYPE_FISHINGHOLE)
{ // The fishing hole used once more { // 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)) if (go->GetUseCount() >= urand(go->GetGOInfo()->fishinghole.minSuccessOpens,go->GetGOInfo()->fishinghole.maxSuccessOpens))
{ {
go->SetLootState(GO_JUST_DEACTIVATED); go->SetLootState(GO_JUST_DEACTIVATED);

View file

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

View file

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