aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/GameObject
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-10-22 02:07:59 +0200
committerShauren <shauren.trinity@gmail.com>2022-10-22 02:07:59 +0200
commit1011cb73c92ddb90589452f70a1dd33830689e32 (patch)
tree02de42791042a43b54069787799e352afe8ec17d /src/server/game/Entities/GameObject
parent29cfbedfb2af9ca6cf76c20b7e5fa17887418e8d (diff)
Core/GameObjects: Implemented gathering nodes (gameobject type 50)
Diffstat (limited to 'src/server/game/Entities/GameObject')
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp80
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/GameObject/GameObjectData.h118
3 files changed, 200 insertions, 0 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index f8abc8eba84..9f84d95d17e 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2913,6 +2913,56 @@ void GameObject::Use(Unit* user)
player->SendDirectMessage(gameObjectUILink.Write());
return;
}
+ case GAMEOBJECT_TYPE_GATHERING_NODE: //50
+ {
+ Player* player = user->ToPlayer();
+ if (!player)
+ return;
+
+ GameObjectTemplate const* info = GetGOInfo();
+ if (!m_personalLoot.count(player->GetGUID()))
+ {
+ if (info->gatheringNode.chestLoot)
+ {
+ Loot* loot = new Loot(GetMap(), GetGUID(), LOOT_CHEST, nullptr);
+ m_personalLoot[player->GetGUID()].reset(loot);
+
+ loot->FillLoot(info->gatheringNode.chestLoot, LootTemplates_Gameobject, player, true, false, GetLootMode(), GetMap()->GetDifficultyLootItemContext());
+ }
+
+ if (info->gatheringNode.triggeredEvent)
+ GameEvents::Trigger(info->gatheringNode.triggeredEvent, player, this);
+
+ // triggering linked GO
+ if (uint32 trapEntry = info->gatheringNode.linkedTrap)
+ TriggeringLinkedGameObject(trapEntry, player);
+
+ if (info->gatheringNode.xpDifficulty && info->gatheringNode.xpDifficulty < 10)
+ if (QuestXPEntry const* questXp = sQuestXPStore.LookupEntry(player->GetLevel()))
+ if (uint32 xp = Quest::RoundXPValue(questXp->Difficulty[info->gatheringNode.xpDifficulty]))
+ player->GiveXP(xp, nullptr);
+
+ spellId = info->gatheringNode.spell;
+ }
+
+ if (m_personalLoot.size() >= info->gatheringNode.MaxNumberofLoots)
+ {
+ SetGoState(GO_STATE_ACTIVE);
+ SetDynamicFlag(GO_DYNFLAG_LO_NO_INTERACT);
+ }
+
+ if (getLootState() != GO_ACTIVATED)
+ {
+ SetLootState(GO_ACTIVATED, player);
+ if (info->gatheringNode.ObjectDespawnDelay)
+ DespawnOrUnsummon(Seconds(info->gatheringNode.ObjectDespawnDelay));
+ }
+
+ // Send loot
+ if (Loot* loot = GetLootForPlayer(player))
+ player->SendLoot(*loot);
+ break;
+ }
default:
if (GetGoType() >= MAX_GAMEOBJECT_TYPE)
TC_LOG_ERROR("misc", "GameObject::Use(): unit (%s, name: %s) tries to use object (%s, name: %s) of unknown type (%u)",
@@ -3252,6 +3302,21 @@ void GameObject::OnLootRelease(Player* looter)
}
break;
}
+ case GAMEOBJECT_TYPE_GATHERING_NODE:
+ {
+ SetGoStateFor(GO_STATE_ACTIVE, looter);
+
+ UF::ObjectData::Base objMask;
+ UF::GameObjectData::Base goMask;
+ objMask.MarkChanged(&UF::ObjectData::DynamicFlags);
+
+ UpdateData udata(GetMapId());
+ BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), goMask.GetChangesMask(), looter);
+ WorldPacket packet;
+ udata.BuildPacket(&packet);
+ looter->SendDirectMessage(&packet);
+ break;
+ }
default:
break;
}
@@ -3541,6 +3606,9 @@ void GameObject::AfterRelocation()
float GameObject::GetInteractionDistance() const
{
+ if (GetGOInfo()->GetInteractRadiusOverride())
+ return float(GetGOInfo()->GetInteractRadiusOverride()) / 100.0f;
+
switch (GetGoType())
{
case GAMEOBJECT_TYPE_AREADAMAGE:
@@ -3780,6 +3848,18 @@ bool GameObject::CanInteractWithCapturePoint(Player const* target) const
|| m_goValue.CapturePoint.State == WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured;
}
+bool GameObject::MeetsInteractCondition(Player const* user) const
+{
+ if (!m_goInfo->GetConditionID1())
+ return true;
+
+ if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(m_goInfo->GetConditionID1()))
+ if (!ConditionMgr::IsPlayerMeetingCondition(user, playerCondition))
+ return false;
+
+ return true;
+}
+
std::unordered_map<ObjectGuid, GameObject::PerPlayerState>& GameObject::GetOrCreatePerPlayerStates()
{
if (!m_perPlayerState)
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 6341d9ecaea..8dd027eb207 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -381,6 +381,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void UpdateCapturePoint();
bool CanInteractWithCapturePoint(Player const* target) const;
+ bool MeetsInteractCondition(Player const* user) const;
+
void AIM_Destroy();
bool AIM_Initialize();
diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h
index 777b4e815fd..90dd21ad59a 100644
--- a/src/server/game/Entities/GameObject/GameObjectData.h
+++ b/src/server/game/Entities/GameObject/GameObjectData.h
@@ -839,6 +839,94 @@ struct GameObjectTemplate
}
}
+ uint32 GetConditionID1() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_DOOR: return door.conditionID1;
+ case GAMEOBJECT_TYPE_BUTTON: return button.conditionID1;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.conditionID1;
+ case GAMEOBJECT_TYPE_CHEST: return chest.conditionID1;
+ case GAMEOBJECT_TYPE_GENERIC: return generic.conditionID1;
+ case GAMEOBJECT_TYPE_TRAP: return trap.conditionID1;
+ case GAMEOBJECT_TYPE_CHAIR: return chair.conditionID1;
+ case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.conditionID1;
+ case GAMEOBJECT_TYPE_TEXT: return text.conditionID1;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.conditionID1;
+ case GAMEOBJECT_TYPE_CAMERA: return camera.conditionID1;
+ case GAMEOBJECT_TYPE_RITUAL: return ritual.conditionID1;
+ case GAMEOBJECT_TYPE_MAILBOX: return mailbox.conditionID1;
+ case GAMEOBJECT_TYPE_SPELLCASTER: return spellCaster.conditionID1;
+ case GAMEOBJECT_TYPE_FLAGSTAND: return flagStand.conditionID1;
+ case GAMEOBJECT_TYPE_AURA_GENERATOR: return auraGenerator.conditionID1;
+ case GAMEOBJECT_TYPE_GUILD_BANK: return guildbank.conditionID1;
+ case GAMEOBJECT_TYPE_NEW_FLAG: return newflag.conditionID1;
+ case GAMEOBJECT_TYPE_ITEM_FORGE: return itemForge.conditionID1;
+ case GAMEOBJECT_TYPE_GATHERING_NODE: return gatheringNode.conditionID1;
+ default: return 0;
+ }
+ }
+
+ uint32 GetInteractRadiusOverride() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_DOOR: return door.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_BUTTON: return button.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_CHEST: return chest.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_BINDER: return binder.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GENERIC: return generic.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_TRAP: return trap.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_CHAIR: return chair.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_TEXT: return text.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_TRANSPORT: return transport.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_AREADAMAGE: return areaDamage.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_CAMERA: return camera.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT: return moTransport.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_DUEL_ARBITER: return duelFlag.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_FISHINGNODE: return fishingNode.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_RITUAL: return ritual.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_MAILBOX: return mailbox.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GUARDPOST: return guardPost.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_SPELLCASTER: return spellCaster.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_MEETINGSTONE: return meetingStone.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_FLAGSTAND: return flagStand.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_FISHINGHOLE: return fishingHole.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_FLAGDROP: return flagDrop.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_CONTROL_ZONE: return controlZone.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_AURA_GENERATOR: return auraGenerator.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY: return dungeonDifficulty.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_BARBER_CHAIR: return barberChair.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING: return destructibleBuilding.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GUILD_BANK: return guildbank.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_TRAPDOOR: return trapdoor.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_NEW_FLAG: return newflag.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_NEW_FLAG_DROP: return newflagdrop.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GARRISON_BUILDING: return garrisonBuilding.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GARRISON_PLOT: return garrisonPlot.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_CAPTURE_POINT: return capturePoint.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_PHASEABLE_MO: return phaseableMO.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GARRISON_MONUMENT: return garrisonMonument.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GARRISON_SHIPMENT: return garrisonShipment.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GARRISON_MONUMENT_PLAQUE: return garrisonMonumentPlaque.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_ITEM_FORGE: return itemForge.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_UI_LINK: return UILink.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_KEYSTONE_RECEPTACLE: return KeystoneReceptacle.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GATHERING_NODE: return gatheringNode.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_CHALLENGE_MODE_REWARD: return challengeModeReward.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_SIEGEABLE_MO: return siegeableMO.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_PVP_REWARD: return pvpReward.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_PLAYER_CHOICE_CHEST: return playerChoiceChest.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_LEGENDARY_FORGE: return legendaryForge.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_GARR_TALENT_TREE: return garrTalentTree.InteractRadiusOverride;
+ case GAMEOBJECT_TYPE_WEEKLY_REWARD_CHEST: return weeklyRewardChest.InteractRadiusOverride;
+ default: return 0;
+ }
+ }
+
uint32 GetRequireLOS() const
{
switch (type)
@@ -911,6 +999,16 @@ struct GameObjectTemplate
}
}
+ uint32 GetNotInCombat() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_CHEST: return chest.notInCombat;
+ case GAMEOBJECT_TYPE_GATHERING_NODE: return gatheringNode.notInCombat;
+ default: return 0;
+ }
+ }
+
uint32 GetCharges() const // despawn at uses amount
{
switch (type)
@@ -984,6 +1082,26 @@ struct GameObjectTemplate
}
}
+ uint32 GetTrivialSkillHigh() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_CHEST: return chest.trivialSkillHigh;
+ case GAMEOBJECT_TYPE_GATHERING_NODE: return gatheringNode.trivialSkillHigh;
+ default: return 0;
+ }
+ }
+
+ uint32 GetTrivialSkillLow() const
+ {
+ switch (type)
+ {
+ case GAMEOBJECT_TYPE_CHEST: return chest.trivialSkillLow;
+ case GAMEOBJECT_TYPE_GATHERING_NODE: return gatheringNode.trivialSkillLow;
+ default: return 0;
+ }
+ }
+
uint32 GetCooldown() const // Cooldown preventing goober and traps to cast spell
{
switch (type)