mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[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:
parent
b672913633
commit
0649b508e4
5 changed files with 81 additions and 71 deletions
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue