diff options
| author | Shauren <shauren.trinity@gmail.com> | 2022-10-22 02:07:59 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2022-10-22 02:07:59 +0200 |
| commit | 1011cb73c92ddb90589452f70a1dd33830689e32 (patch) | |
| tree | 02de42791042a43b54069787799e352afe8ec17d /src/server/game/Entities/GameObject | |
| parent | 29cfbedfb2af9ca6cf76c20b7e5fa17887418e8d (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.cpp | 80 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObjectData.h | 118 |
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) |
