Advertisement
Guest User

Creature script tutorial

a guest
Mar 19th, 2010
874
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.80 KB | None | 0 0
  1. #include "precompiled.h"
  2.  
  3. enum
  4. {
  5.     // Ez a lista az npc által mondott szövegeket tartalmazza. Minden egyes TextId-hez
  6.     // rendel egy nevet, ezzel konstansokat(állandókat) hozva létre. A listához adhatsz
  7.     // újat, törülhetsz belőle, és átírhatod a TextId-t, de fontos, hogy létező id-t adj meg.
  8.     SAY_AGGRO       = -1999900,
  9.     SAY_RANDOM_0    = -1999901,
  10.     SAY_RANDOM_1    = -1999902,
  11.     SAY_RANDOM_2    = -1999903,
  12.     SAY_RANDOM_3    = -1999904,
  13.     SAY_RANDOM_4    = -1999905,
  14.     SAY_BESERK      = -1999906,
  15.     SAY_PHASE       = -1999907,
  16.     SAY_DANCE       = -1999908,
  17.     SAY_SALUTE      = -1999909,
  18.  
  19.     // Az npc által használt spelleket tartalmazza. Szintén adhatsz hozzá, módosíthatod, törölheted.
  20.     SPELL_BUFF      = 25661,
  21.     SPELL_ONE       = 12555,
  22.     SPELL_ONE_ALT   = 24099,
  23.     SPELL_TWO       = 10017,
  24.     SPELL_THREE     = 26027,
  25.     SPELL_ENRAGE    = 23537,
  26.     SPELL_BESERK    = 32309,
  27.  
  28.     FACTION_WORGEN  = 24
  29. };
  30.  
  31. // Egy string (szöveg) típusú konstanst(állandót) hoz létre. Ez fog megjelenni a gossip menüben ha rákattintasz az npc-re.
  32. #define GOSSIP_ITEM     "I'm looking for a fight"
  33.  
  34. struct MANGOS_DLL_DECL test_npcAI : public ScriptedAI
  35. {
  36.     //Ez a konstruktora az eljárásnak, egyszer hívódik meg, amikor először spawn-olódik az npc.
  37.     test_npcAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
  38.  
  39.     // Ezek a kódban használt változók. Mindegyik 32 bites integer (szám) típusú.
  40.     // Különböző időzítők és más eljárások használják.
  41.  
  42.     uint32 m_uiSayTimer;                                   //Időzítő: random beszéd
  43.     uint32 m_uiRebuffTimer;                                //Időzítő: rebuff-hoz
  44.     uint32 m_uiSpell1Timer;                                //Időzítő: SPELL_ONE spellhez (csak combatban)
  45.     uint32 m_uiSpell2Timer;                                //Időzítő: SPELL_TWO spellhez (csak combatban)
  46.     uint32 m_uiSpell3Timer;                                //Időzítő: SPELL_THREE spellhez (csak combatban)
  47.     uint32 m_uiBeserkTimer;                                //Időzítő: az enrage-be való belépés időpontja
  48.     uint32 m_uiPhase;                                      //Időzítő: a phase-t (igen úgy mint egy boss :D) állítja
  49.     uint32 m_uiPhaseTimer;                                 //Időzítő: az egyes phase-k időtartamához kell
  50.  
  51.     //A konstruktor által meghívott funkció
  52.     void Reset()
  53.     {
  54.         // A timerek értékét ezredmásodpercben kell megadni
  55.         // Ha egy változót timernek használunk, akkor érdemes
  56.         // ebben az alakban megadni: m_uiIdeJonANevTimer
  57.  
  58.         m_uiPhase = 1;                                    //Phase-t beállítjuk 1-esre
  59.         m_uiRebuffTimer = 0;                              //0 másodperc, tehát azonnal végrehajtódik
  60.         m_uiPhaseTimer = 60000;                           //60 másodperc
  61.         m_uiSpell1Timer = 5000;                           //5 másodperc
  62.         m_uiSpell2Timer = 37000;                          //37 másodperc
  63.         m_uiSpell3Timer = 19000;                          //19 másodperc
  64.         m_uiBeserkTimer = 120000;                         //2 perc
  65.     }
  66.  
  67.     //Akkor hívódik meg, ha valaki megtámadja az npc-t
  68.     void Aggro(Unit* pWho)
  69.     {
  70.         //Kimondja a SAY_AGGRO nevű szöveget.
  71.         DoScriptText(SAY_AGGRO, m_creature);
  72.     }
  73.  
  74.     //Akkor hívódik meg, ha valaki küld egy emote üzenetet az npc-nek (pl.: /dance, /salute)
  75.     void ReceiveEmote(Player* pPlayer, uint32 uiTextEmote)
  76.     {
  77.         // Az emote lekezelése
  78.         m_creature->HandleEmoteCommand(uiTextEmote);
  79.        
  80.         // Megnézi, hogy mi az uiTextEmote értéke. Ha 34 akkor az elsőt,
  81.         // ha 78, akkor a másodikat hajtja végre.
  82.         switch(uiTextEmote)
  83.         {
  84.             case TEXTEMOTE_DANCE:
  85.                 DoScriptText(SAY_DANCE, m_creature);
  86.                 break;
  87.             case TEXTEMOTE_SALUTE:
  88.                 DoScriptText(SAY_SALUTE, m_creature);
  89.                 break;
  90.         }
  91.     }
  92.  
  93.     // Körübelül 100 ezredmásodpercenként hívódik meg, minden egyes map updatenél.
  94.     // Az uiDiff konstans a két update közti időintervallumot adja meg ezredmásodpercben.
  95.     void UpdateAI(const uint32 uiDiff)
  96.     {
  97.         // Ha az npc-t nem támadja senki
  98.         if (!m_creature->getVictim())
  99.         {
  100.             // Ha a Timer értéke kisebb, mint az uiDiff értéke
  101.             if (m_uiSayTimer < uiDiff)
  102.             {
  103.                 //Véletlenszerűen kiválaszt a 4 közül egyet.
  104.                 switch(urand(0, 4))
  105.                 {
  106.                     case 0: DoScriptText(SAY_RANDOM_0, m_creature); break;
  107.                     case 1: DoScriptText(SAY_RANDOM_1, m_creature); break;
  108.                     case 2: DoScriptText(SAY_RANDOM_2, m_creature); break;
  109.                     case 3: DoScriptText(SAY_RANDOM_3, m_creature); break;
  110.                     case 4: DoScriptText(SAY_RANDOM_4, m_creature); break;
  111.                 }
  112.  
  113.                 m_uiSayTimer = 45000; // Reseteljük a timert
  114.             }
  115.             else
  116.                 m_uiSayTimer -= uiDiff; // Ha a Timer értéke nagyobb mint az uiDiff,
  117.                                         // kivonjuk a Timerből az uiDiffet.
  118.                                         // Így szép lassan 0 lesz a Timer értéke.
  119.  
  120.             // Ez a timer az npc-re ad egy aura-t
  121.             if (m_uiRebuffTimer < uiDiff)
  122.             {
  123.                 DoCast(m_creature, SPELL_BUFF);
  124.                 m_uiRebuffTimer = 900000;                  // A Timer értékét 15 percre állítjuk, tehát az első
  125.             }                                              // alkalommal egyből végrehajtódik és utána 15 percenként
  126.             else
  127.                 m_uiRebuffTimer -= uiDiff;
  128.         }
  129.  
  130.         // Ha az npc-t nem támadja senki, kilép a funkcióból
  131.         if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
  132.             return;
  133.  
  134.         //Spell 1 timer
  135.         if (m_uiSpell1Timer < uiDiff)
  136.         {
  137.             //Használ egy spell-t a legnagyobb threattal rendelkező ellenségen
  138.             if (rand()%50 > 10)
  139.                 DoCast(m_creature->getVictim(), SPELL_ONE_ALT);
  140.             else if (m_creature->IsWithinDist(m_creature->getVictim(), 25.0f))
  141.                 DoCast(m_creature->getVictim(), SPELL_ONE);
  142.  
  143.             m_uiSpell1Timer = 5000;
  144.         }
  145.         else
  146.             m_uiSpell1Timer -= uiDiff;
  147.  
  148.         //Spell 2 timer
  149.         if (m_uiSpell2Timer < uiDiff)
  150.         {
  151.             //Használ egy spell-t a legnagyobb threattal rendelkező ellenségen
  152.             DoCast(m_creature->getVictim(), SPELL_TWO);
  153.             m_uiSpell2Timer = 37000;
  154.         }
  155.         else
  156.             m_uiSpell2Timer -= uiDiff;
  157.  
  158.         //Ellenőrizzük, hogy a phase nagyobb-e mint 1
  159.         if (m_uiPhase > 1)
  160.         {
  161.             //Ha a Timer lejárt
  162.             if (m_uiSpell3Timer < uiDiff)
  163.             {
  164.                 DoCast(m_creature->getVictim(), SPELL_THREE);
  165.  
  166.                 m_uiSpell3Timer = 19000;
  167.             }
  168.             else
  169.                 m_uiSpell3Timer -= uiDiff;
  170.  
  171.             if (m_uiBeserkTimer < uiDiff)
  172.             {
  173.                 //Káromkodunk egy ízeset, és castol az ellenségére egy ronda spellt.
  174.                 DoScriptText(SAY_BESERK, m_creature);
  175.                 DoCast(m_creature->getVictim(), SPELL_BESERK);
  176.  
  177.                 //Uújra és újra használja 12 másodpercenként, amíg ki nem nyír mindenkit.
  178.                 m_uiBeserkTimer = 12000;
  179.             }
  180.             else
  181.                 m_uiBeserkTimer -= uiDiff;
  182.         }
  183.    
  184.         // Ha a Phase értéke 1
  185.         else if (m_uiPhase == 1)                            
  186.         {
  187.             // És ha leját a Phase időzítője
  188.             if (m_uiPhaseTimer < uiDiff)
  189.             {
  190.                 // Ugrunk a következő phase-be.
  191.                 ++m_uiPhase;
  192.                 DoScriptText(SAY_PHASE, m_creature);
  193.                 // Az npc saját magára castolja az Enrage spelljét.
  194.                 DoCast(m_creature, SPELL_ENRAGE);
  195.             }
  196.             else
  197.                 m_uiPhaseTimer -= uiDiff;
  198.         }
  199.  
  200.         DoMeleeAttackIfReady();
  201.     }
  202. };
  203.  
  204. // Ez a GetAi metódus. Minden új creature meghívja, ha használni akarja a scriptet.
  205. CreatureAI* GetAI_test_npc(Creature* pCreature)
  206. {
  207.     return new test_npcAI(pCreature);
  208. }
  209.  
  210. // Akkor hívódik mag, amikor egy player, ráklikkel egy lehetőségre a gossip menüben.
  211. bool GossipSelect_test_npc(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
  212. {
  213.     // Ha ráklikkelnek az egyetlen lehetőségre a menüben. :D
  214.     if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
  215.     {
  216.         pPlayer->CLOSE_GOSSIP_MENU();
  217.         //Az npc fraction-ját semlegesről ellenségesre állítja.
  218.         pCreature->setFaction(FACTION_WORGEN);
  219.         //Megtámadja azt a playert, aki rákattintott a menüpontra.
  220.         pCreature->AI()->AttackStart(pPlayer);
  221.     }
  222.  
  223.     return true;
  224. }
  225.  
  226. // Akkor hívódik meg, amikor egy player, megnyitja a gossip menüt.
  227. bool GossipHello_test_npc(Player* pPlayer, Creature* pCreature)
  228. {
  229.     pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
  230.     pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID());
  231.  
  232.     return true;
  233. }
  234.  
  235. //Akkor szerver indulásánál kell egyszer, hogy initializálja a scriptet a core. (tudja, hogy létezik)
  236. void AddSC_test_npc()
  237. {
  238.     Script* newscript;
  239.  
  240.     newscript = new Script;
  241.     newscript->Name = "test_npc";
  242.     newscript->GetAI = &GetAI_test_npc;
  243.     newscript->pGossipHello = &GossipHello_test_npc;
  244.     newscript->pGossipSelect = &GossipSelect_test_npc;
  245.     newscript->RegisterSelf();
  246. }
  247.  
  248. // A "test_npc" script nevet úgy cserélheted le, hogy egyszerűen átírod mindenhol arra, amire szeretnéd.
  249. // Érdemes a fájl nevét is ennek beállítani. Tehát, ha "boss_malacka" a script neve,
  250. // akkor a fájlnév is legyen "boss_malacka.cpp".
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement