Skip to content

Commit

Permalink
[10383] Store guid instaed pointer for first user of GAMEOBJECT_TYPE_…
Browse files Browse the repository at this point in the history
…SUMMONING_RITUAL

This is more safe way in pointer store comparison with.
LAso Some related code cleanups.
  • Loading branch information
VladimirMangos committed Aug 20, 2010
1 parent bdbb94f commit 65c3249
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 68 deletions.
103 changes: 53 additions & 50 deletions src/game/GameObject.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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())
{
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand All @@ -1201,8 +1195,16 @@ void GameObject::Use(Unit* user)
}
else
{
if (player != m_ritualOwner && (info->summoningRitual.castersGrouped && !player->IsInSameRaidWith(m_ritualOwner)))
return;
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;
}
Expand All @@ -1217,40 +1219,31 @@ 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;

spellId = info->summoningRitual.spellId;
spellCaster = GetMap()->GetPlayer(m_firstUser);

if (spellId == 62330) // GO store nonexistent spell, replace by expected
{
// 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;
}
spellId = info->summoningRitual.spellId;

// finish owners spell
if (owner)
owner->FinishSpell(CURRENT_CHANNELED_SPELL);
if (spellId == 62330) // GO store nonexistent spell, replace by expected
spellId = 61993;

// 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;
}
}
// spell have reagent and mana cost but it not expected use its
// it triggered spell in fact casted at currently channeled GO
triggered = true;

// finish owners spell
if (owner)
owner->FinishSpell(CURRENT_CHANNELED_SPELL);

// can be deleted now, if
if (!info->summoningRitual.ritualPersistent)
SetLootState(GO_JUST_DEACTIVATED);
// reset ritual for this GO
else
{
return;
}
ClearAllUsesData();

// go to end function to spell casting
break;
Expand Down Expand Up @@ -1575,4 +1568,14 @@ float GameObject::GetObjectBoundingRadius() const
return fabs(dispEntry->unknown12) * GetObjectScale();

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());
}
35 changes: 21 additions & 14 deletions src/game/GameObject.h
Expand Up @@ -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
{
for (std::list<uint32>::const_iterator i = m_SkillupList.begin(); i != m_SkillupList.end(); ++i)
if (*i == PlayerGuidLow) return true;
return false;
void AddToSkillupList(Player* player);
bool IsInSkillupList(Player* player) const;
void ClearSkillupList() { m_SkillupSet.clear(); }
void ClearAllUsesData()
{
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();

Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/game/LootHandler.cpp
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/game/SpellEffects.cpp
Expand Up @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10382"
#define REVISION_NR "10383"
#endif // __REVISION_NR_H__

0 comments on commit 65c3249

Please sign in to comment.