Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
spell_archaeology.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "GameObject.h"
7#include "Map.h"
8#include "ObjectMgr.h"
9#include "Player.h"
10#include "ScriptMgr.h"
11#include "SpellScript.h"
12#include "Unit.h"
13
15{
16 SPELL_SURVEY = 80451,
17
21
22 SURVEY_OBJECT_SLOT = 1 // SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - SLOT1
23};
24
25// Retail ranges: red > 100yd, yellow 50-100yd, green < 50yd, find within ~8yd.
26static float const SURVEY_FIND_DISTANCE = 8.0f;
27static float const SURVEY_GREEN_DISTANCE = 50.0f;
28static float const SURVEY_YELLOW_DISTANCE = 100.0f;
29static int32 const SURVEY_TOOL_LIFETIME = 5; // seconds
30
31static uint32 GetSurveyToolEntry(float distance)
32{
33 if (distance <= SURVEY_GREEN_DISTANCE)
35 if (distance <= SURVEY_YELLOW_DISTANCE)
37 return GO_SURVEY_TOOL_RED;
38}
39
40static void ReplaceSurveyObjectSlot(Unit* caster, GameObject* go)
41{
42 if (uint64 guid = caster->m_ObjectSlot[SURVEY_OBJECT_SLOT])
43 {
44 if (GameObject* old = caster->GetMap()->GetGameObject(guid))
45 {
46 if (old->GetSpellId() == SPELL_SURVEY)
47 old->SetSpellId(0);
48 caster->RemoveGameObject(old, true);
49 }
51 }
52
53 if (!go)
54 return;
55
56 caster->AddGameObject(go);
58}
59
60static GameObject* SpawnSurveyGameObject(Player* player, uint32 entry, float x, float y, float z, float orientation, int32 lifetimeSecs)
61{
62 Map* map = player->GetMap();
63 if (!map)
64 return NULL;
65
66 GameObject* go = new GameObject();
67 if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map,
68 x, y, z, orientation, 0.0f, 0.0f, 0.0f, 0.0f, 0, GOState::GO_STATE_READY))
69 {
70 delete go;
71 return NULL;
72 }
73
74 go->SetRespawnTime(lifetimeSecs > 0 ? lifetimeSecs : 0);
76 go->SetOwnerGUID(player->GetGUID());
77 for (auto phase : player->GetPhases())
78 go->SetPhased(phase, false, true);
79
80 map->AddToMap(go);
81 return go;
82}
83
84// 80451 - Survey
85// DBC MiscValue is 1 (placeholder GO "unk name"); spawn the correct survey tool / find ourselves.
87{
88public:
89 spell_archaeology_survey() : SpellScriptLoader("spell_archaeology_survey") { }
90
92 {
94
95 float _findOrientation = 0.0f;
96
98 {
100 }
101
113
115 {
116 Player* player = GetCaster()->ToPlayer();
117 ResearchDigsite* digsite = player->GetCurrentResearchDigsite();
118 if (!digsite)
119 return;
120
121 ArchaeologyFindInfo const* find = digsite->GetArchaeologyFind();
122 if (!find)
123 return;
124
125 // Survey tool orientation only — do not turn the player toward the find.
126 _findOrientation = player->GetAngle(find->x, find->y);
127 }
128
130 {
131 PreventHitDefaultEffect(effIndex);
132
133 Player* player = GetCaster()->ToPlayer();
134 ResearchDigsite* digsite = player->GetCurrentResearchDigsite();
135 if (!digsite)
136 return;
137
138 ArchaeologyFindInfo const* find = digsite->GetArchaeologyFind();
139 if (!find)
140 {
141 player->SendSurveyCastInfo(digsite, false);
142 return;
143 }
144
145 float distance = player->GetDistance(find->x, find->y, find->z);
146 bool success = distance <= SURVEY_FIND_DISTANCE;
147 float orientation = _findOrientation;
148 if (!orientation)
149 orientation = player->GetAngle(find->x, find->y);
150
151 if (success)
152 {
153 // Clear previous survey tool; dig find is not tracked in the object slot.
154 ReplaceSurveyObjectSlot(player, NULL);
155
156 if (GameObject* go = SpawnSurveyGameObject(player, find->goEntry, find->x, find->y, find->z, orientation, 60))
157 {
158 // Finds are looted via Use/SendLoot; keep owner for archaeology credit checks.
159 go->SetSpellId(0);
160 }
161 }
162 else
163 {
164 float x, y, z;
166 uint32 toolEntry = GetSurveyToolEntry(distance);
167 if (GameObject* go = SpawnSurveyGameObject(player, toolEntry, x, y, z, orientation, SURVEY_TOOL_LIFETIME))
168 ReplaceSurveyObjectSlot(player, go);
169 }
170
171 player->SendSurveyCastInfo(digsite, success);
172 }
173
180 };
181
186};
187
std::int32_t int32
Definition Define.h:73
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ GO_STATE_READY
Definition GameObject.h:577
@ TYPEID_PLAYER
Definition Object.h:55
#define DEFAULT_WORLD_OBJECT_SIZE
Definition Object.h:29
@ HIGHGUID_GAMEOBJECT
#define sObjectMgr
Definition ObjectMgr.h:1617
SpellEffIndex
@ EFFECT_0
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
@ SKILL_ARCHAEOLOGY
SpellCastResult
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
#define SpellCheckCastFn(F)
#define SpellEffectFn(F, I, N)
#define SpellCastFn(F)
void SetOwnerGUID(uint64 owner)
Definition GameObject.h:665
bool Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit=0)
void SetRespawnTime(int32 respawn)
Definition GameObject.h:699
bool SetPhased(uint32 id, bool update, bool apply) OVERRIDE
void SetSpellId(uint32 id)
Definition GameObject.h:682
Definition Map.h:238
bool AddToMap(T *)
Definition Map.cpp:504
GameObject * GetGameObject(uint64 guid)
Definition Map.cpp:3184
uint64 GetGUID() const
Definition Object.h:119
Player * ToPlayer()
Definition Object.h:204
TypeID GetTypeId() const
Definition Object.h:131
ResearchDigsite * GetCurrentResearchDigsite()
Definition Player.cpp:23479
bool HasSkill(uint32 skill) const
Definition Player.cpp:6542
void SendSurveyCastInfo(ResearchDigsite *digsite, bool success)
Definition Player.cpp:23304
HookList< CheckCastHandler > OnCheckCast
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
HookList< CastHandler > BeforeCast
Unit * GetCaster()
SpellScriptLoader(const char *name)
Definition Unit.h:1367
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:1689
uint64 m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition Unit.h:2375
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:1671
Map * GetMap() const
Definition Object.h:740
std::set< uint32 > const & GetPhases() const
Definition Object.h:647
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0) const
Definition Object.cpp:3070
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1666
PrepareSpellScript(spell_archaeology_survey_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
static int32 const SURVEY_TOOL_LIFETIME
static float const SURVEY_GREEN_DISTANCE
static GameObject * SpawnSurveyGameObject(Player *player, uint32 entry, float x, float y, float z, float orientation, int32 lifetimeSecs)
void AddSC_archaeology_spell_scripts()
ArchaeologySurvey
@ SPELL_SURVEY
@ GO_SURVEY_TOOL_RED
@ SURVEY_OBJECT_SLOT
@ GO_SURVEY_TOOL_YELLOW
@ GO_SURVEY_TOOL_GREEN
static float const SURVEY_FIND_DISTANCE
static uint32 GetSurveyToolEntry(float distance)
static void ReplaceSurveyObjectSlot(Unit *caster, GameObject *go)
static float const SURVEY_YELLOW_DISTANCE
float GetAngle(Position const *pos) const
Definition Object.cpp:1860
ArchaeologyFindInfo const * GetArchaeologyFind() const
Definition Player.h:1243