Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
example_creature.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/* ScriptData
7SDName: Example_Creature
8SD%Complete: 100
9SDComment: Short custom scripting example
10SDCategory: Script Examples
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "ScriptedGossip.h"
16#include "Player.h"
17
18// **** This script is designed as an example for others to build on ****
19// **** Please modify whatever you'd like to as this script is only for developement ****
20
21// **** Script Info* ***
22// This script is written in a way that it can be used for both friendly and hostile monsters
23// Its primary purpose is to show just how much you can really do with scripts
24// I recommend trying it out on both an agressive NPC and on friendly npc
25
26// **** Quick Info* ***
27// Functions with Handled Function marked above them are functions that are called automatically by the core
28// Functions that are marked Custom Function are functions I've created to simplify code
29
31{
32 //List of text id's. The text is stored in database, also in a localized version
33 //(if translation not exist for the textId, default english text will be used)
34 //Not required to define in this way, but simplify if changes are needed.
35 //These texts must be added to the creature texts of the npc for which the script is assigned.
36 SAY_AGGRO = 0, // "Let the games begin."
37 SAY_RANDOM = 1, // "I see endless suffering. I see torment. I see rage. I see everything.",
38 // "Muahahahaha",
39 // "These mortal infedels my lord, they have invaded your sanctum and seek to steal your secrets.",
40 // "You are already dead.",
41 // "Where to go? What to do? So many choices that all end in pain, end in death."
42 SAY_BERSERK = 2, // "$N, I sentance you to death!"
43 SAY_PHASE = 3, // "The suffering has just begun!"
44 SAY_DANCE = 4, // "I always thought I was a good dancer."
45 SAY_SALUTE = 5, // "Move out Soldier!"
46 SAY_EVADE = 6 // "Help $N! I'm under attack!"
47};
48
50{
51 // List of spells.
52 // Not required to define them in this way, but will make it easier to maintain in case spellId change
53 SPELL_BUFF = 25661,
54 SPELL_ONE = 12555,
56 SPELL_TWO = 10017,
57 SPELL_THREE = 26027,
58 SPELL_FRENZY = 23537,
60};
61
63{
64 // any other constants
66};
67
68//List of gossip item texts. Items will appear in the gossip window.
69#define GOSSIP_ITEM "I'm looking for a fight"
70
72{
73 public:
74 example_creature() : CreatureScript("example_creature") { }
75
77 {
78 // *** HANDLED FUNCTION ***
79 //This is the constructor, called only once when the Creature is first created
80 example_creatureAI(Creature* creature) : ScriptedAI(creature) { }
81
82 // *** CUSTOM VARIABLES ****
83 //These variables are for use only by this individual script.
84 //Nothing else will ever call them but us.
85
86 uint32 m_uiSayTimer; // Timer for random chat
87 uint32 m_uiRebuffTimer; // Timer for rebuffing
88 uint32 m_uiSpell1Timer; // Timer for spell 1 when in combat
89 uint32 m_uiSpell2Timer; // Timer for spell 1 when in combat
90 uint32 m_uiSpell3Timer; // Timer for spell 1 when in combat
91 uint32 m_uiBeserkTimer; // Timer until we go into Beserk (enraged) mode
92 uint32 m_uiPhase; // The current battle phase we are in
93 uint32 m_uiPhaseTimer; // Timer until phase transition
94
95 // *** HANDLED FUNCTION ***
96 //This is called after spawn and whenever the core decides we need to evade
98 {
99 m_uiPhase = 1; // Start in phase 1
100 m_uiPhaseTimer = 60000; // 60 seconds
101 m_uiSpell1Timer = 5000; // 5 seconds
102 m_uiSpell2Timer = urand(10000, 20000); // between 10 and 20 seconds
103 m_uiSpell3Timer = 19000; // 19 seconds
104 m_uiBeserkTimer = 120000; // 2 minutes
105
106 me->RestoreFaction();
107 }
108
109 // *** HANDLED FUNCTION ***
110 // Enter Combat called once per combat
112 {
113 //Say some stuff
114 Talk(SAY_AGGRO, who);
115 }
116
117 // *** HANDLED FUNCTION ***
118 // Attack Start is called when victim change (including at start of combat)
119 // By default, attack who and start movement toward the victim.
120 //void AttackStart(Unit* who) OVERRIDE
121 //{
122 // ScriptedAI::AttackStart(who);
123 //}
124
125 // *** HANDLED FUNCTION ***
126 // Called when going out of combat. Reset is called just after.
128 {
130 }
131
132 // *** HANDLED FUNCTION ***
133 //Our Receive emote function
134 void ReceiveEmote(Player* /*player*/, uint32 uiTextEmote) OVERRIDE
135 {
136 me->HandleEmoteCommand(uiTextEmote);
137
138 switch (uiTextEmote)
139 {
140 case TEXT_EMOTE_DANCE:
142 break;
145 break;
146 }
147 }
148
149 // *** HANDLED FUNCTION ***
150 //Update AI is called Every single map update (roughly once every 50ms if a player is within the grid)
152 {
153 //Out of combat timers
154 if (!me->GetVictim())
155 {
156 //Random Say timer
157 if (m_uiSayTimer <= uiDiff)
158 {
159 //Random switch between 5 outcomes
161
162 m_uiSayTimer = 45000; //Say something agian in 45 seconds
163 }
164 else
165 m_uiSayTimer -= uiDiff;
166
167 //Rebuff timer
168 if (m_uiRebuffTimer <= uiDiff)
169 {
171 m_uiRebuffTimer = 900000; //Rebuff agian in 15 minutes
172 }
173 else
174 m_uiRebuffTimer -= uiDiff;
175 }
176
177 //Return since we have no target
178 if (!UpdateVictim())
179 return;
180
181 //Spell 1 timer
182 if (m_uiSpell1Timer <= uiDiff)
183 {
184 //Cast spell one on our current target.
185 if (rand()%50 > 10)
187 else if (me->IsWithinDist(me->GetVictim(), 25.0f))
189
190 m_uiSpell1Timer = 5000;
191 }
192 else
193 m_uiSpell1Timer -= uiDiff;
194
195 //Spell 2 timer
196 if (m_uiSpell2Timer <= uiDiff)
197 {
198 //Cast spell two on our current target.
200 m_uiSpell2Timer = 37000;
201 }
202 else
203 m_uiSpell2Timer -= uiDiff;
204
205 //Beserk timer
206 if (m_uiPhase > 1)
207 {
208 //Spell 3 timer
209 if (m_uiSpell3Timer <= uiDiff)
210 {
211 //Cast spell one on our current target.
213
214 m_uiSpell3Timer = 19000;
215 }
216 else
217 m_uiSpell3Timer -= uiDiff;
218
219 if (m_uiBeserkTimer <= uiDiff)
220 {
221 //Say our line then cast uber death spell
222 Talk(SAY_BERSERK, me->GetVictim());
224
225 //Cast our beserk spell agian in 12 seconds if we didn't kill everyone
226 m_uiBeserkTimer = 12000;
227 }
228 else
229 m_uiBeserkTimer -= uiDiff;
230 }
231 else if (m_uiPhase == 1) //Phase timer
232 {
233 if (m_uiPhaseTimer <= uiDiff)
234 {
235 //Go to next phase
236 ++m_uiPhase;
239 }
240 else
241 m_uiPhaseTimer -= uiDiff;
242 }
243
245 }
246 };
247
249 {
250 return new example_creatureAI(creature);
251 }
252
253 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
254 {
256 player->SEND_GOSSIP_MENU(907, creature->GetGUID());
257
258 return true;
259 }
260
261 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
262 {
263 player->PlayerTalkClass->ClearMenus();
264 if (action == GOSSIP_ACTION_INFO_DEF+1)
265 {
266 player->CLOSE_GOSSIP_MENU();
267 //Set our faction to hostile towards all
268 creature->setFaction(FACTION_WORGEN);
269 creature->AI()->AttackStart(player);
270 }
271
272 return true;
273 }
274};
275
276//This is the actual function called only once durring InitScripts()
277//It must define all handled functions that are to be run in this script
279{
280 new example_creature();
281}
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ TEXT_EMOTE_DANCE
@ TEXT_EMOTE_SALUTE
@ SAY_BERSERK
#define SAY_AGGRO
@ SPELL_FRENZY
#define SPELL_BERSERK
@ SAY_RANDOM
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureScript(const char *name)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
void AddSC_example_creature()
@ SAY_AGGRO
@ SAY_SALUTE
@ SAY_EVADE
@ SAY_RANDOM
@ SAY_BERSERK
@ SAY_DANCE
@ SAY_PHASE
@ SPELL_ONE_ALT
@ SPELL_ONE
@ SPELL_THREE
@ SPELL_TWO
@ SPELL_BUFF
@ SPELL_FRENZY
@ SPELL_BERSERK
#define GOSSIP_ITEM
@ FACTION_WORGEN
Creature * me
ScriptedAI(Creature *creature)
void ReceiveEmote(Player *, uint32 uiTextEmote) OVERRIDE
void UpdateAI(uint32 uiDiff) OVERRIDE
== Triggered Actions Requested ==================