From 5ae74c5b589ff6530d0258bb77d32f4cba03020e Mon Sep 17 00:00:00 2001 From: raczman Date: Mon, 8 Jun 2009 20:19:13 +0200 Subject: [PATCH 1/6] Added readline support into CLI. Supports scrolling through past commands, and tab-completion for commands (no subcommands, sorry). Requires libreadline package to build from now on! for debian/ubuntu: apt-get install libreadline5-dev Linux only, windows users shouldnt notice any difference. --HG-- branch : trunk --- src/game/Chat.h | 4 +- src/trinitycore/CMakeLists.txt | 1 + src/trinitycore/CliRunnable.cpp | 88 +++++++++++++++++++++++++++------ 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/src/game/Chat.h b/src/game/Chat.h index a8dbb5b98a5..cb5070a354d 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -73,7 +73,7 @@ class ChatHandler int ParseCommands(const char* text); virtual char const* GetName() const; - + static ChatCommand* getCommandTable(); protected: explicit ChatHandler() : m_session(NULL) {} // for CLI subclass @@ -89,8 +89,6 @@ class ChatHandler bool ShowHelpForCommand(ChatCommand *table, const char* cmd); bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd); - ChatCommand* getCommandTable(); - bool HandleAccountCommand(const char* args); bool HandleAccountCreateCommand(const char* args); bool HandleAccountDeleteCommand(const char* args); diff --git a/src/trinitycore/CMakeLists.txt b/src/trinitycore/CMakeLists.txt index 2c7c4544577..0a9801c5a19 100644 --- a/src/trinitycore/CMakeLists.txt +++ b/src/trinitycore/CMakeLists.txt @@ -44,6 +44,7 @@ trinityconfig vmaps ZThread g3dlite +readline ${SCRIPT_LIB} ${MYSQL_LIBRARIES} ${POSTGRE_LIBS} diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp index 839358e7034..179ee4db80b 100644 --- a/src/trinitycore/CliRunnable.cpp +++ b/src/trinitycore/CliRunnable.cpp @@ -37,6 +37,56 @@ #include "Player.h" #include "Chat.h" +#if PLATFORM != WINDOWS +#include +#include + +char * command_finder(const char* text, int state) +{ + static int idx,len; + const char* ret; + ChatCommand *cmd = ChatHandler::getCommandTable(); + + if(!state) + { + idx = 0; + len = strlen(text); + } + + while(ret = cmd[idx].Name) + { + if(!cmd[idx].AllowConsole) + { + idx++; + continue; + } + + idx++; + //printf("Checking %s \n", cmd[idx].Name); + if (strncmp(ret, text, len) == 0) + return strdup(ret); + if(cmd[idx].Name == NULL) + break; + } + + return ((char*)NULL); + +} + +char ** cli_completion(const char * text, int start, int end) +{ + char ** matches; + matches = (char**)NULL; + + if(start == 0) + matches = rl_completion_matches((char*)text,&command_finder); + else + rl_bind_key('\t',rl_abort); + return (matches); +} + +#endif + void utf8print(const char* str) { #if PLATFORM == PLATFORM_WINDOWS @@ -316,10 +366,10 @@ void CliRunnable::run() WorldDatabase.ThreadStart(); // let thread do safe mySQL requests char commandbuf[256]; - + bool canflush = true; ///- Display the list of available CLI functions then beep sLog.outString(); - + rl_attempted_completion_function = cli_completion; if(sConfig.GetBoolDefault("BeepAtStart", true)) printf("\a"); // \a = Alert @@ -331,15 +381,16 @@ void CliRunnable::run() while (!World::IsStopped()) { fflush(stdout); - #ifdef linux - while (!kb_hit_return() && !World::IsStopped()) - // With this, we limit CLI to 10commands/second - usleep(100); - if (World::IsStopped()) - break; - #endif - char *command_str = fgets(commandbuf,sizeof(commandbuf),stdin); - if (command_str != NULL) + + char *command_str ; // = fgets(commandbuf,sizeof(commandbuf),stdin); + + #if PLATFORM == WINDOWS + command_str = fgets(commandbuf,sizeof(commandbuf),stdin); + #else + command_str = readline("TC>"); + rl_bind_key('\t',rl_complete); + #endif + if (command_str != NULL) { for(int x=0;command_str[x];x++) if(command_str[x]=='\r'||command_str[x]=='\n') @@ -351,23 +402,30 @@ void CliRunnable::run() if(!*command_str) { - printf("TC>"); + #if PLATFORM == WINDOWS + printf("TC>"); + #endif continue; } std::string command; if(!consoleToUtf8(command_str,command)) // convert from console encoding to utf8 { - printf("TC>"); + #if PLATFORM == WINDOWS + printf("TC>"); + #endif continue; } - + fflush(stdout); sWorld.QueueCliCommand(&utf8print,command.c_str()); - } + add_history(command.c_str()); + + } else if (feof(stdin)) { World::StopNow(SHUTDOWN_EXIT_CODE); } + } ///- End the database thread From 79c15a3d7550773dbb0debb17a5340016fea2bb5 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Mon, 8 Jun 2009 20:56:24 +0200 Subject: [PATCH 2/6] Remove unneeded query for renaming characters that are online, this is handled perfectly with the Player::SetAtLoginFlag and Player::SaveToDB functions already. --HG-- branch : trunk --- src/game/Level2.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index fc6e8a51a74..4caa6f29578 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -3102,7 +3102,6 @@ bool ChatHandler::HandleRenameCommand(const char* args) { PSendSysMessage(LANG_RENAME_PLAYER, target->GetName()); target->SetAtLoginFlag(AT_LOGIN_RENAME); - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow()); } else { From dbdd87ec8c10d3614abe451fbb554bcb35b6af69 Mon Sep 17 00:00:00 2001 From: raczman Date: Mon, 8 Jun 2009 23:04:49 +0200 Subject: [PATCH 3/6] Fix build on windows. --HG-- branch : trunk --- src/trinitycore/CliRunnable.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp index 179ee4db80b..8b4ed30cf80 100644 --- a/src/trinitycore/CliRunnable.cpp +++ b/src/trinitycore/CliRunnable.cpp @@ -369,7 +369,9 @@ void CliRunnable::run() bool canflush = true; ///- Display the list of available CLI functions then beep sLog.outString(); + #if PLATFORM != WINDOWS rl_attempted_completion_function = cli_completion; + #endif if(sConfig.GetBoolDefault("BeepAtStart", true)) printf("\a"); // \a = Alert @@ -417,8 +419,10 @@ void CliRunnable::run() continue; } fflush(stdout); + #if PLATFORM != WINDOWS sWorld.QueueCliCommand(&utf8print,command.c_str()); add_history(command.c_str()); + #endif } else if (feof(stdin)) From 6be9e51035ca3aa3732bd3a81d4a678bf4724741 Mon Sep 17 00:00:00 2001 From: Chaz Brown Date: Thu, 11 Jun 2009 06:29:35 -0400 Subject: [PATCH 4/6] Forgotten changes in characters.sql --HG-- branch : trunk --- sql/characters.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/characters.sql b/sql/characters.sql index bcb2b449c0f..17274932e18 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -197,10 +197,10 @@ CREATE TABLE `auctionhousebot` ( -- Data for table `auctionhousebot` -- -insert into `auctionhousebot`(`auctionhouse`,`name`,`minitems`,`maxitems`,`mintime`,`maxtime`,`percentgreytradegoods`,`percentwhitetradegoods`,`percentgreentradegoods`,`percentbluetradegoods`,`percentpurpletradegoods`,`percentorangetradegoods`,`percentyellowtradegoods`,`percentgreyitems`,`percentwhiteitems`,`percentgreenitems`,`percentblueitems`,`percentpurpleitems`,`percentorangeitems`,`percentyellowitems`,`minpricegrey`,`maxpricegrey`,`minpricewhite`,`maxpricewhite`,`minpricegreen`,`maxpricegreen`,`minpriceblue`,`maxpriceblue`,`minpricepurple`,`maxpricepurple`,`minpriceorange`,`maxpriceorange`,`minpriceyellow`,`maxpriceyellow`,`minbidpricegrey`,`maxbidpricegrey`,`minbidpricewhite`,`maxbidpricewhite`,`minbidpricegreen`,`maxbidpricegreen`,`minbidpriceblue`,`maxbidpriceblue`,`minbidpricepurple`,`maxbidpricepurple`,`minbidpriceorange`,`maxbidpriceorange`,`minbidpriceyellow`,`maxbidpriceyellow`,`maxstackgrey`,`maxstackwhite`,`maxstackgreen`,`maxstackblue`,`maxstackpurple`,`maxstackorange`,`maxstackyellow`,`buyerpricegrey`,`buyerpricewhite`,`buyerpricegreen`,`buyerpriceblue`,`buyerpricepurple`,`buyerpriceorange`,`buyerpriceyellow`,`buyerbiddinginterval`,`buyerbidsperinterval`) values -(2,'Alliance',0,0,8,24,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,1,5,12,15,20,22,1,1), -(6,'Horde',0,0,8,24,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,1,5,12,15,20,22,1,1), -(7,'Neutral',0,0,8,24,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,1,5,12,15,20,22,1,1); +insert into `auctionhousebot`(`auctionhouse`,`name`,`minitems`,`maxitems`,`percentgreytradegoods`,`percentwhitetradegoods`,`percentgreentradegoods`,`percentbluetradegoods`,`percentpurpletradegoods`,`percentorangetradegoods`,`percentyellowtradegoods`,`percentgreyitems`,`percentwhiteitems`,`percentgreenitems`,`percentblueitems`,`percentpurpleitems`,`percentorangeitems`,`percentyellowitems`,`minpricegrey`,`maxpricegrey`,`minpricewhite`,`maxpricewhite`,`minpricegreen`,`maxpricegreen`,`minpriceblue`,`maxpriceblue`,`minpricepurple`,`maxpricepurple`,`minpriceorange`,`maxpriceorange`,`minpriceyellow`,`maxpriceyellow`,`minbidpricegrey`,`maxbidpricegrey`,`minbidpricewhite`,`maxbidpricewhite`,`minbidpricegreen`,`maxbidpricegreen`,`minbidpriceblue`,`maxbidpriceblue`,`minbidpricepurple`,`maxbidpricepurple`,`minbidpriceorange`,`maxbidpriceorange`,`minbidpriceyellow`,`maxbidpriceyellow`,`maxstackgrey`,`maxstackwhite`,`maxstackgreen`,`maxstackblue`,`maxstackpurple`,`maxstackorange`,`maxstackyellow`,`buyerpricegrey`,`buyerpricewhite`,`buyerpricegreen`,`buyerpriceblue`,`buyerpricepurple`,`buyerpriceorange`,`buyerpriceyellow`,`buyerbiddinginterval`,`buyerbidsperinterval`) values +(2,'Alliance',0,0,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,1,5,12,15,20,22,1,1), +(6,'Horde',0,0,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,1,5,12,15,20,22,1,1), +(7,'Neutral',0,0,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,1,5,12,15,20,22,1,1); -- -- Table structure for table `bugreport` From 181a647af56086f81bdc7473c8fa7484f7650ee8 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Thu, 11 Jun 2009 20:17:44 +0200 Subject: [PATCH 5/6] * Add script for Razorfen Kraul, implements access to certain room after certain event. Script by ArticDevil, thank you. * Rename the 'Azeroth' filter to 'Eastern Kingdoms' in the script vcproj files --HG-- branch : trunk --- sql/updates/TC1_1569_world_scripts.sql | 3 + src/bindings/scripts/VC71/71ScriptDev2.vcproj | 8 ++ src/bindings/scripts/VC80/80ScriptDev2.vcproj | 8 ++ src/bindings/scripts/VC90/90ScriptDev2.vcproj | 8 ++ .../zone/razorfen_kraul/def_razorfen_kraul.h | 21 ++++ .../instance_razorfen_kraul.cpp | 119 ++++++++++++++++++ .../zone/razorfen_kraul/razorfen_kraul.cpp | 53 +++++++- 7 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 sql/updates/TC1_1569_world_scripts.sql create mode 100644 src/bindings/scripts/scripts/zone/razorfen_kraul/def_razorfen_kraul.h create mode 100644 src/bindings/scripts/scripts/zone/razorfen_kraul/instance_razorfen_kraul.cpp diff --git a/sql/updates/TC1_1569_world_scripts.sql b/sql/updates/TC1_1569_world_scripts.sql new file mode 100644 index 00000000000..afe0759e711 --- /dev/null +++ b/sql/updates/TC1_1569_world_scripts.sql @@ -0,0 +1,3 @@ +-- Razorfen Kraul +UPDATE `instance_template` SET `script` = 'instance_razorfen_kraul' WHERE `map` = '47' LIMIT 1; +UPDATE `creature_template` SET `ScriptName` = 'npc_deaths_head_ward_keeper' WHERE `entry` = '4625' LIMIT 1; \ No newline at end of file diff --git a/src/bindings/scripts/VC71/71ScriptDev2.vcproj b/src/bindings/scripts/VC71/71ScriptDev2.vcproj index e92d43e61c2..3fb0cd7ad8f 100644 --- a/src/bindings/scripts/VC71/71ScriptDev2.vcproj +++ b/src/bindings/scripts/VC71/71ScriptDev2.vcproj @@ -536,6 +536,14 @@ RelativePath="..\scripts\zone\razorfen_kraul\razorfen_kraul.cpp" > + + + + + + + + + + + + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DEF_RAZORFEN_KRAUL_H +#define DEF_RAZORFEN_KRAUL_H + +#define TYPE_WARD_KEEPERS 1 +#endif \ No newline at end of file diff --git a/src/bindings/scripts/scripts/zone/razorfen_kraul/instance_razorfen_kraul.cpp b/src/bindings/scripts/scripts/zone/razorfen_kraul/instance_razorfen_kraul.cpp new file mode 100644 index 00000000000..e7ede4b28d6 --- /dev/null +++ b/src/bindings/scripts/scripts/zone/razorfen_kraul/instance_razorfen_kraul.cpp @@ -0,0 +1,119 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Instance_Razorfen_Kraul +SD%Complete: +SDComment: +SDCategory: Razorfen Kraul +EndScriptData */ + +#include "precompiled.h" +#include "def_razorfen_kraul.h" + + +#define WARD_KEEPERS_NR 2 + +struct TRINITY_DLL_DECL instance_razorfen_kraul : public ScriptedInstance +{ + instance_razorfen_kraul(Map *map) : ScriptedInstance(map) {Initialize();}; + + uint64 DoorWardGUID; + uint32 WardCheck_Timer; + int WardKeeperAlive; + + void Initialize() + { + WardKeeperAlive = 1; + WardCheck_Timer = 4000; + DoorWardGUID = 0; + } + + Player* GetPlayerInMap() + { + Map::PlayerList const& players = instance->GetPlayers(); + + if (!players.isEmpty()) + { + for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* plr = itr->getSource()) + return plr; + } + } + debug_log("TSCR: Instance Razorfen Kraul: GetPlayerInMap, but PlayerList is empty!"); + return NULL; + } + + void OnObjectCreate(GameObject *go) + { + switch(go->GetEntry()) + { + case 21099: DoorWardGUID = go->GetGUID(); break; + } + } + + void HandleGameObject(uint64 guid, uint32 state) + { + Player *player = GetPlayerInMap(); + + if (!player || !guid) + { + debug_log("SD2: Instance Razorfen Kraul: HandleGameObject fail"); + return; + } + + if (GameObject *go = GameObject::GetGameObject(*player,guid)) + go->SetGoState(state); + } + + void Update(uint32 diff) + { + if (WardCheck_Timer < diff) + { + HandleGameObject(DoorWardGUID, WardKeeperAlive); + WardKeeperAlive = 0; + WardCheck_Timer = 4000; + }else + WardCheck_Timer -= diff; + } + + void SetData(uint32 type, uint32 data) + { + switch(type) + { + case TYPE_WARD_KEEPERS: + if (data == NOT_STARTED) + WardKeeperAlive = 1; + break; + } + } + +}; + +InstanceData* GetInstanceData_instance_razorfen_kraul(Map* map) +{ + return new instance_razorfen_kraul(map); +} + +void AddSC_instance_razorfen_kraul() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "instance_razorfen_kraul"; + newscript->GetInstanceData = &GetInstanceData_instance_razorfen_kraul; + newscript->RegisterSelf(); +} \ No newline at end of file diff --git a/src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp b/src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp index 39be57325d7..70d997c3c43 100644 --- a/src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp +++ b/src/bindings/scripts/scripts/zone/razorfen_kraul/razorfen_kraul.cpp @@ -27,6 +27,7 @@ EndContentData */ #include "precompiled.h" #include "../../npc/npc_escortAI.h" +#include "def_razorfen_kraul.h" #define SAY_READY -1047000 #define SAY_POINT -10470001 @@ -42,10 +43,11 @@ EndContentData */ #define QUEST_WILLIX_THE_IMPORTER 1144 #define ENTRY_BOAR 4514 +#define SPELL_QUILLBOAR_CHANNELING 7083 struct TRINITY_DLL_DECL npc_willixAI : public npc_escortAI { -npc_willixAI(Creature *c) : npc_escortAI(c) {} + npc_willixAI(Creature *c) : npc_escortAI(c) {} void WaypointReached(uint32 i) { @@ -137,6 +139,50 @@ bool QuestAccept_npc_willix(Player* player, Creature* creature, Quest const* que return true; } +struct TRINITY_DLL_DECL npc_deaths_head_ward_keeperAI : public ScriptedAI +{ + npc_deaths_head_ward_keeperAI(Creature *c) : ScriptedAI(c) + { + pInstance = ((ScriptedInstance*)c->GetInstanceData()); + Reset(); + } + + ScriptedInstance *pInstance; + uint32 QuillboarChanneling_Timer; + + void Reset() + { + QuillboarChanneling_Timer = 1500; + } + + void Aggro(Unit *who) + { + } + + void UpdateAI(const uint32 diff) + { + if (!m_creature->isAlive()) + return; + + if (pInstance) + pInstance->SetData(TYPE_WARD_KEEPERS, NOT_STARTED); + + if (QuillboarChanneling_Timer < diff) + { + if( m_creature->IsNonMeleeSpellCasted(false) ) + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, SPELL_QUILLBOAR_CHANNELING); + QuillboarChanneling_Timer = 1100; + }else QuillboarChanneling_Timer -= diff; + + } +}; + +CreatureAI* GetAI_npc_deaths_head_ward_keeper(Creature *_Creature) +{ + return new npc_deaths_head_ward_keeperAI(_Creature); +} + CreatureAI* GetAI_npc_willix(Creature *_Creature) { npc_willixAI* thisAI = new npc_willixAI(_Creature); @@ -201,5 +247,10 @@ void AddSC_razorfen_kraul() newscript->GetAI = &GetAI_npc_willix; newscript->pQuestAccept = &QuestAccept_npc_willix; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_deaths_head_ward_keeper"; + newscript->GetAI = &GetAI_npc_deaths_head_ward_keeper; + newscript->RegisterSelf(); } From a6d7f0805c5170036403c5902d77cdd0069b5ab3 Mon Sep 17 00:00:00 2001 From: Anubisss Date: Thu, 11 Jun 2009 21:43:48 +0200 Subject: [PATCH 6/6] *Add 2 missing filles to cmake. --HG-- branch : trunk --- src/bindings/scripts/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bindings/scripts/CMakeLists.txt b/src/bindings/scripts/CMakeLists.txt index 96e672f376b..188381b4778 100644 --- a/src/bindings/scripts/CMakeLists.txt +++ b/src/bindings/scripts/CMakeLists.txt @@ -242,6 +242,8 @@ SET(trinityscript_LIB_SRCS scripts/zone/onyxias_lair/boss_onyxia.cpp scripts/zone/orgrimmar/orgrimmar.cpp scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp + scripts/zone/razorfen_kraul/def_razorfen_kraul.h + scripts/zone/razorfen_kraul/instance_razorfen_kraul.cpp scripts/zone/razorfen_kraul/razorfen_kraul.cpp scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp