diff options
-rw-r--r-- | sql/FULL/world_script_texts.sql | 6 | ||||
-rw-r--r-- | sql/updates/4807_script_texts.sql | 5 | ||||
-rw-r--r-- | src/bindings/scripts/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/bindings/scripts/ScriptMgr.cpp | 4 | ||||
-rw-r--r-- | src/bindings/scripts/VC80/80ScriptDev2.vcproj | 4 | ||||
-rw-r--r-- | src/bindings/scripts/VC90/90ScriptDev2.vcproj | 4 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp | 62 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/vault_of_archavon/boss_emalon.cpp | 284 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h | 9 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp | 103 | ||||
-rw-r--r-- | src/game/Player.cpp | 3 | ||||
-rw-r--r-- | src/game/Unit.cpp | 6 | ||||
-rw-r--r-- | src/game/World.cpp | 21 | ||||
-rw-r--r-- | src/game/World.h | 3 | ||||
-rw-r--r-- | src/trinitycore/trinitycore.conf.dist | 10 |
15 files changed, 489 insertions, 36 deletions
diff --git a/sql/FULL/world_script_texts.sql b/sql/FULL/world_script_texts.sql index 16f8c87f1eb..bb3da821bab 100644 --- a/sql/FULL/world_script_texts.sql +++ b/sql/FULL/world_script_texts.sql @@ -1713,6 +1713,12 @@ INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc1`, `content (-1585028, 'Do not... get too comfortable.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 12420, 1, 0, 0, 'kaelthas MT SAY_RECAST_GRAVITY'), (-1585029, 'My demise accomplishes nothing! The Master will have you! You will drown in your own blood! This world shall burn! Aaaghh!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 12421, 1, 0, 0, 'kaelthas MT SAY_DEATH'); +-- 1 590 000 VAULT OF ARCHAVON +INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) VALUES +(-1590000, 'Emalon the Storm Watcher overcharges a Tempest Minion!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 3, 0, 0, 'emalon EMOTE_OVERCHARGE_TEMPEST_MINION'), +(-1590001, 'A Tempest Minion appears to defend Emalon!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 3, 0, 0, 'emalon EMOTE_MINION_RESPAWN'), +(-1590002, 'Archavon the Stone Watcher goes into a berserker rage!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 2, 0, 0, 'archavon EMOTE_BERSERK'); + -- -1 615 000 OBSIDIAN SANCTUM INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) VALUES (-1615000,'I fear nothing! Least of all you!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,14111,1,0,0,'shadron SAY_SHADRON_AGGRO'), diff --git a/sql/updates/4807_script_texts.sql b/sql/updates/4807_script_texts.sql new file mode 100644 index 00000000000..573c44b2fed --- /dev/null +++ b/sql/updates/4807_script_texts.sql @@ -0,0 +1,5 @@ +DELETE FROM script_texts WHERE entry IN(-1590000,-1590001,-1590002); +INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) VALUES +(-1590000, 'Emalon the Storm Watcher overcharges a Tempest Minion!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 3, 0, 0, 'emalon EMOTE_OVERCHARGE_TEMPEST_MINION'), +(-1590001, 'A Tempest Minion appears to defend Emalon!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 3, 0, 0, 'emalon EMOTE_MINION_RESPAWN'), +(-1590002, 'Archavon the Stone Watcher goes into a berserker rage!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 2, 0, 0, 'archavon EMOTE_BERSERK'); diff --git a/src/bindings/scripts/CMakeLists.txt b/src/bindings/scripts/CMakeLists.txt index dab90812b59..b67d7cfe4aa 100644 --- a/src/bindings/scripts/CMakeLists.txt +++ b/src/bindings/scripts/CMakeLists.txt @@ -484,6 +484,7 @@ SET(trinityscript_LIB_SRCS scripts/zone/obsidian_sanctum/def_obsidian_sanctum.h scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp scripts/zone/vault_of_archavon/boss_archavon.cpp + scripts/zone/vault_of_archavon/boss_emalon.cpp scripts/zone/vault_of_archavon/def_vault_of_archavon.h scripts/zone/wintergrasp/wintergrasp.cpp scripts/zone/ulduar/ulduar/boss_algalon.cpp diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index 478c2b904f3..ae298061984 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -650,6 +650,8 @@ extern void AddSC_zuldrak(); //Dungeon //Vault of Archavon extern void AddSC_boss_archavon(); +extern void AddSC_boss_emalon(); +extern void AddSC_instance_archavon(); //Region extern void AddSC_wintergrasp(); @@ -1558,6 +1560,8 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf") //Dungeon //Vault of Archavon AddSC_boss_archavon(); + AddSC_boss_emalon(); + AddSC_instance_archavon(); //Region AddSC_wintergrasp(); diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj index d1d41523d36..e5eeda086ff 100644 --- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj +++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj @@ -2834,6 +2834,10 @@ > </File> <File + RelativePath="..\scripts\zone\vault_of_archavon\boss_emalon.cpp" + > + </File> + <File RelativePath="..\scripts\zone\vault_of_archavon\def_vault_of_archavon.h" > </File> diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj index 04645271404..7fe459734ed 100644 --- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj +++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj @@ -2835,6 +2835,10 @@ > </File> <File + RelativePath="..\scripts\zone\vault_of_archavon\boss_emalon.cpp" + > + </File> + <File RelativePath="..\scripts\zone\vault_of_archavon\def_vault_of_archavon.h" > </File> diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp index d963024d69e..51e6df5e023 100644 --- a/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp +++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp @@ -3,77 +3,77 @@ UPDATE `creature_template` SET `ScriptName`='boss_archavon' WHERE `entry`='31125 UPDATE `creature_template` SET `ScriptName`='mob_archavon_warder' WHERE `entry`='32353'; *** SQL END ***/ #include "precompiled.h" +#include "def_vault_of_archavon.h" -//These are patchwerk's yell -#define SAY_AGGRO1 -1533017 -#define SAY_AGGRO2 -1533018 -#define SAY_SLAY -1533019 -#define SAY_DEATH -1533020 - -#define EMOTE_BERSERK -1533021 -#define EMOTE_ENRAGE -1533022 +#define EMOTE_BERSERK -1590002 //Spells Archavon -#define SPELL_ROCK_SHARDS 58678 -#define SPELL_CRUSHING_LEAP HEROIC(58960,60894)//Instant (10-80yr range) -- Leaps at an enemy, inflicting 8000 Physical damage, knocking all nearby enemies away, and creating a cloud of choking debris. -#define SPELL_STOMP HEROIC(58663,60880) -#define SPELL_IMPALE HEROIC(58666,60882) //Lifts an enemy off the ground with a spiked fist, inflicting 47125 to 52875 Physical damage and 9425 to 10575 additional damage each second for 8 sec. -#define SPELL_BERSERK 47008 +#define SPELL_ROCK_SHARDS 58678 +#define SPELL_CRUSHING_LEAP HEROIC(58960,60894)//Instant (10-80yr range) -- Leaps at an enemy, inflicting 8000 Physical damage, knocking all nearby enemies away, and creating a cloud of choking debris. +#define SPELL_STOMP HEROIC(58663,60880) +#define SPELL_IMPALE HEROIC(58666,60882) //Lifts an enemy off the ground with a spiked fist, inflicting 47125 to 52875 Physical damage and 9425 to 10575 additional damage each second for 8 sec. +#define SPELL_BERSERK 47008 //Spells Archavon Warders -#define SPELL_ROCK_SHOWER HEROIC(60919,60923) -#define SPELL_SHIELD_CRUSH HEROIC(60897,60899) -#define SPELL_WHIRL HEROIC(60902,60916) +#define SPELL_ROCK_SHOWER HEROIC(60919,60923) +#define SPELL_SHIELD_CRUSH HEROIC(60897,60899) +#define SPELL_WHIRL HEROIC(60902,60916) //4 Warders spawned -#define ARCHAVON_WARDER 32353 //npc 32353 +#define ARCHAVON_WARDER 32353 //npc 32353 //Yell #define SAY_LEAP "Archavon the Stone Watcher lunges for $N!" //$N should be the target -#define EVENT_ROCK_SHARDS 1 //15s cd -#define EVENT_CHOKING_CLOUD 2 //30s cd +#define EVENT_ROCK_SHARDS 1 //15s cd +#define EVENT_CHOKING_CLOUD 2 //30s cd #define EVENT_STOMP 3 //45s cd #define EVENT_IMPALE 4 #define EVENT_BERSERK 5 //300s cd //mob -#define EVENT_ROCK_SHOWER 5 //set = 20s cd,unkown cd -#define EVENT_SHIELD_CRUSH 6 //set = 30s cd -#define EVENT_WHIRL 8 //set= 10s cd +#define EVENT_ROCK_SHOWER 5 //set = 20s cd,unkown cd +#define EVENT_SHIELD_CRUSH 6 //set = 30s cd +#define EVENT_WHIRL 8 //set= 10s cd struct TRINITY_DLL_DECL boss_archavonAI : public ScriptedAI { - boss_archavonAI(Creature *c) : ScriptedAI(c) {} + boss_archavonAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + ScriptedInstance* pInstance; EventMap events; void Reset() { events.Reset(); - } - void KilledUnit(Unit* Victim) - { - if(!(rand()%5)) - DoScriptText(SAY_SLAY, me); + if(pInstance) + pInstance->SetData(DATA_ARCHAVON_EVENT, NOT_STARTED); } + void KilledUnit(Unit* Victim){} + void JustDied(Unit* Killer) { - DoScriptText(SAY_DEATH, me); + if (pInstance) + pInstance->SetData(DATA_ARCHAVON_EVENT, DONE); } void EnterCombat(Unit *who) { - DoScriptText((rand()%2) ? SAY_AGGRO1 : SAY_AGGRO2, me); DoZoneInCombat(); events.ScheduleEvent(EVENT_ROCK_SHARDS, 15000); events.ScheduleEvent(EVENT_CHOKING_CLOUD, 30000); events.ScheduleEvent(EVENT_STOMP, 45000); events.ScheduleEvent(EVENT_BERSERK, 300000); - } + if(pInstance) + pInstance->SetData(DATA_ARCHAVON_EVENT, IN_PROGRESS); + } + // Below UpdateAI may need review/debug. void UpdateAI(const uint32 diff) { //Return since we have no target diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_emalon.cpp b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_emalon.cpp new file mode 100644 index 00000000000..80fe55ca996 --- /dev/null +++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_emalon.cpp @@ -0,0 +1,284 @@ +#include "precompiled.h" +#include "def_vault_of_archavon.h" + +#define EMOTE_OVERCHARGE_TEMPEST_MINION -1590000 +#define EMOTE_MINION_RESPAWN -1590001 + +//Spells Emalon +#define SPELL_CHAIN_LIGHTNING HEROIC(64213,64215) +#define SPELL_LIGHTNING_NOVA HEROIC(64216,65279) +#define SPELL_OVERCHARGE 64218 +#define SPELL_BERSERK 47008 + +//Spells Tempest Minions +#define SPELL_OVERCHARGED 64217 +#define SPELL_OVERCHARGED_BLAST 64219 +#define SPELL_SHOCK 64363 + +//4 Warders spawned +#define TEMPEST_MINIONS 33998 + +#define EVENT_CHAIN_LIGHTNING 1 //5s cd +#define EVENT_OVERCHARGE 2 //45s cd +#define EVENT_LIGHTNING_NOVA 3 //40s cd +#define EVENT_BERSERK 4 //360s cd +#define EVENT_SHOCK 5 //20s cd + +struct Location +{ + float x, y, z, o; +}; + +static Location MinionLocation[]= +{ + -231.713,-281.96,91.466,1.53213, + -205.585,-281.549,91.4661,1.75204, + -205.651,-296.394,91.4661,1.69549, + -232.235,-296.433,91.4998,1.44417 +}; + +struct TRINITY_DLL_DECL boss_emalonAI : public ScriptedAI +{ + boss_emalonAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance* pInstance; + EventMap events; + std::list<uint64> MinionList; + + void Reset() + { + events.Reset(); + DespawnAllMinions(); + SummonAllMinions(); + + if(pInstance) + pInstance->SetData(DATA_EMALON_EVENT, NOT_STARTED); + } + + void DespawnAllMinions() + { + if(!MinionList.empty()) + { + for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); itr++) + { + Unit *Minion = Unit::GetUnit(*m_creature, (*itr)); + if(Minion) + Minion->RemoveFromWorld(); + } + } + + MinionList.clear(); + } + + void JustSummoned(Creature *Summoned) + { + MinionList.push_back(Summoned->GetGUID()); + if(Unit* target = m_creature->getVictim()) + Summoned->AI()->AttackStart(target); + } + + void SummonAllMinions() + { + if(MinionList.empty()) + for(uint8 i = 0; i < 4; i++) + SummonMinion(m_creature, MinionLocation[i].x, MinionLocation[i].y, MinionLocation[i].z, MinionLocation[i].o); + } + + static void SummonMinion(Creature *Summoner, float x, float y, float z, float o) + { + Summoner->SummonCreature(TEMPEST_MINIONS, x, y, z, o, TEMPSUMMON_DEAD_DESPAWN, 0); + } + + void KilledUnit(Unit* Victim){} + + void JustDied(Unit* Killer) + { + DespawnAllMinions(); + if (pInstance) + pInstance->SetData(DATA_EMALON_EVENT, DONE); + } + + void EnterCombat(Unit *who) + { + if(!MinionList.empty()) + { + for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr) + { + Creature* Minion = (Unit::GetCreature(*m_creature, *itr)); + Minion->AI()->AttackStart(who); + } + } + + DoZoneInCombat(); + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5000); + events.ScheduleEvent(EVENT_OVERCHARGE, 45000); + events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 30000); + events.ScheduleEvent(EVENT_BERSERK, 360000); + events.ScheduleEvent(EVENT_SHOCK, 20000); + + if(pInstance) + pInstance->SetData(DATA_EMALON_EVENT, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if(!UpdateVictim()) + return; + + events.Update(diff); + + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while(uint32 eventId = events.ExecuteEvent()) + { + switch(eventId) + { + case EVENT_CHAIN_LIGHTNING: + if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_CHAIN_LIGHTNING); + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 20000); + return; + case EVENT_OVERCHARGE: + for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr) + { + Creature* Minion = (Unit::GetCreature(*m_creature, *itr)); + if(Minion && Minion->isAlive() && !Minion->HasAura(SPELL_OVERCHARGED)) + { + Minion->CastSpell(me, SPELL_OVERCHARGED, true); + Minion->SetHealth(Minion->GetMaxHealth()); + DoScriptText(EMOTE_OVERCHARGE_TEMPEST_MINION, m_creature); + events.ScheduleEvent(EVENT_OVERCHARGE, 45000); + return; + } + } + case EVENT_LIGHTNING_NOVA: + DoCast(me->getVictim(), SPELL_LIGHTNING_NOVA); + events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 25000); + return; + case EVENT_SHOCK: + for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr) + { + Creature* Minion = (Unit::GetCreature(*m_creature, *itr)); + if(Minion && Minion->isAlive()) + { + if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + { + Minion->CastSpell(target, SPELL_SHOCK, true); + events.ScheduleEvent(EVENT_SHOCK, 20000); + return; + } + } + } + case EVENT_BERSERK: + DoCast(m_creature, SPELL_BERSERK); + return; + } + } + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## Mob Tempest Minions +######*/ +struct TRINITY_DLL_DECL mob_tempest_minionsAI : public ScriptedAI +{ + mob_tempest_minionsAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + EmalonGUID = pInstance ? pInstance->GetData64(DATA_EMALON) : 0; + Emalon = Unit::GetCreature(*m_creature, EmalonGUID); + } + + ScriptedInstance* pInstance; + EventMap events; + uint64 EmalonGUID; + std::list<Creature*> MinionList; + Creature* Emalon; + uint32 SPELL_OVERCHARGED_Timer; + bool AlreadyOvercharged; + + void Reset() + { + events.Reset(); + AlreadyOvercharged = false; + SPELL_OVERCHARGED_Timer = 0; + } + + void EnterCombat(Unit *who) + { + DoZoneInCombat(); + if(Emalon) + Emalon->AI()->AttackStart(who); + } + + void JustDied(Unit* Killer) + { + m_creature->RemoveCorpse(); + m_creature->RemoveFromWorld(); + if(Emalon) + { + boss_emalonAI::SummonMinion(Emalon, Emalon->GetPositionX(), Emalon->GetPositionY(), Emalon->GetPositionZ(), Emalon->GetOrientation()); + DoScriptText(EMOTE_MINION_RESPAWN, m_creature); + } + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if(!UpdateVictim()) + return; + + if(Aura *OverchargedAura = m_creature->GetAura(SPELL_OVERCHARGED)) + { + if(OverchargedAura->GetStackAmount() < 10) + { + if (SPELL_OVERCHARGED_Timer < diff) + { + DoCast(me, SPELL_OVERCHARGED); + SPELL_OVERCHARGED_Timer = 2000; + }else SPELL_OVERCHARGED_Timer -=diff; + } + else + { + if(OverchargedAura->GetStackAmount() == 10 && (AlreadyOvercharged == false)) + { + DoCast(me,SPELL_OVERCHARGED_BLAST); + AlreadyOvercharged = true; + } + } + } + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_tempest_minions(Creature *_Creature) +{ + return new mob_tempest_minionsAI (_Creature); +} + +CreatureAI* GetAI_boss_emalon(Creature *_Creature) +{ + return new boss_emalonAI (_Creature); +} + +void AddSC_boss_emalon() +{ + Script *newscript; + + newscript = new Script; + newscript->Name="boss_emalon"; + newscript->GetAI = &GetAI_boss_emalon; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="mob_tempest_minions"; + newscript->GetAI = &GetAI_mob_tempest_minions; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h b/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h index f46ba447945..5b11d5729eb 100644 --- a/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h +++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h @@ -1,4 +1,13 @@ #ifndef DEF_ARCHAVON_H #define DEF_ARCHAVON_H +enum +{ + DATA_ARCHAVON = 1, + DATA_EMALON = 2, + + DATA_ARCHAVON_EVENT = 3, + DATA_EMALON_EVENT = 4 +}; + #endif diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp b/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp index dc725b2be66..e7f6f572a77 100644 --- a/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp +++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp @@ -1,9 +1,112 @@ #include "precompiled.h" #include "def_vault_of_archavon.h" +#define NUMBER_OF_ENCOUNTERS 2 + struct TRINITY_DLL_DECL instance_archavon : public ScriptedInstance { instance_archavon(Map *Map) : ScriptedInstance(Map) {Initialize();}; + + std::string strInstData; + uint64 Archavon; + uint64 Emalon; + uint32 Encounters[NUMBER_OF_ENCOUNTERS]; + + void Initialize() + { + Archavon = 0; + Emalon = 0; + + for(uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; i++) + Encounters[i] = NOT_STARTED; + } + + bool IsEncounterInProgress() const + { + for(uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; ++i) + if(Encounters[i] == IN_PROGRESS) + return true; + + return false; + } + + void OnCreatureCreate(Creature *creature, bool add) + { + switch(creature->GetEntry()) + { + case 31125: Archavon = creature->GetGUID(); break; + case 33993: Emalon = creature->GetGUID(); break; + } + } + + uint64 GetData64(uint32 identifier) + { + switch(identifier) + { + case DATA_ARCHAVON: return Archavon; + case DATA_EMALON: return Emalon; + } + return 0; + } + + uint32 GetData(uint32 identifier) + { + switch(identifier) + { + case DATA_ARCHAVON_EVENT: return Encounters[0]; + case DATA_EMALON_EVENT: return Encounters[1]; + } + return 0; + } + + void SetData(uint32 identifier, uint32 data) + { + switch(identifier) + { + case DATA_ARCHAVON_EVENT: Encounters[0] = data; break; + case DATA_EMALON_EVENT: Encounters[1] = data; break; + } + + if (data == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << Encounters[0] << " " << Encounters[1]; + + strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } + + std::string GetSaveData() + { + return strInstData; + } + + void Load(const char* chrIn) + { + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + loadStream >> Encounters[0] >> Encounters[1]; + + for(uint8 i = 1; i < NUMBER_OF_ENCOUNTERS; ++i) + { + if (Encounters[i] == IN_PROGRESS) + Encounters[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; + } }; InstanceData* GetInstanceData_instance_archavon(Map* map) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f648a5a3d3d..ed2f79f4b38 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -20,7 +20,6 @@ #include "Common.h" #include "Language.h" -#include "Config/ConfigEnv.h" #include "Database/DatabaseEnv.h" #include "Log.h" #include "Opcodes.h" @@ -4557,7 +4556,7 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g uint32 dmultiplier = dcost->multiplier[ItemSubClassToDurabilityMultiplierId(ditemProto->Class,ditemProto->SubClass)]; uint32 costs = uint32(LostDurability*dmultiplier*double(dQualitymodEntry->quality_mod)); - costs = uint32(costs * discountMod) * sConfig.GetFloatDefault("Rate.RepairCost", 1); + costs = uint32(costs * discountMod) * sWorld.getRate(RATE_REPAIRCOST); if (costs==0) //fix for ITEM_QUALITY_ARTIFACT costs = 1; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 58fe17783bc..bc43eefbb36 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -14016,10 +14016,10 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss) ((Player*)pVictim)->SetPvPDeath(player!=NULL); // only if not player and not controlled by player pet. And not at BG - if (durabilityLoss && !player && !((Player*)pVictim)->InBattleGround()) + if ( (durabilityLoss && !player && !((Player*)pVictim)->InBattleGround()) || ( player && sWorld.getConfig(CONFIG_DURABILITY_LOSS_IN_PVP) ) ) { - DEBUG_LOG("We are dead, loosing 10 percents durability"); - ((Player*)pVictim)->DurabilityLossAll(0.10f,false); + DEBUG_LOG("We are dead, losing %u percent durability", sWorld.getRate(RATE_DURABILITY_LOSS_ON_DEATH)); + ((Player*)pVictim)->DurabilityLossAll(sWorld.getRate(RATE_DURABILITY_LOSS_ON_DEATH),false); // durability lost message WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0); ((Player*)pVictim)->GetSession()->SendPacket(&data); diff --git a/src/game/World.cpp b/src/game/World.cpp index 4669590392c..450840f1714 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -469,6 +469,12 @@ void World::LoadConfigSettings(bool reload) rate_values[RATE_XP_KILL] = sConfig.GetFloatDefault("Rate.XP.Kill", 1.0f); rate_values[RATE_XP_QUEST] = sConfig.GetFloatDefault("Rate.XP.Quest", 1.0f); rate_values[RATE_XP_EXPLORE] = sConfig.GetFloatDefault("Rate.XP.Explore", 1.0f); + rate_values[RATE_REPAIRCOST] = sConfig.GetFloatDefault("Rate.RepairCost", 1.0f); + if(rate_values[RATE_REPAIRCOST] < 0.0f) + { + sLog.outError("Rate.RepairCost (%f) must be >=0. Using 0.0 instead.",rate_values[RATE_REPAIRCOST]); + rate_values[RATE_REPAIRCOST] = 0.0f; + } rate_values[RATE_REPUTATION_GAIN] = sConfig.GetFloatDefault("Rate.Reputation.Gain", 1.0f); rate_values[RATE_REPUTATION_LOWLEVEL_KILL] = sConfig.GetFloatDefault("Rate.Reputation.LowLevel.Kill", 1.0f); rate_values[RATE_REPUTATION_LOWLEVEL_QUEST] = sConfig.GetFloatDefault("Rate.Reputation.LowLevel.Quest", 1.0f); @@ -520,6 +526,19 @@ void World::LoadConfigSettings(bool reload) rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = NOMINAL_MELEE_RANGE; } + rate_values[RATE_DURABILITY_LOSS_ON_DEATH] = sConfig.GetFloatDefault("DurabilityLoss.OnDeath", 10.0f); + if(rate_values[RATE_DURABILITY_LOSS_ON_DEATH] < 0.0f) + { + sLog.outError("DurabilityLoss.OnDeath (%f) must be >=0. Using 0.0 instead.",rate_values[RATE_DURABILITY_LOSS_ON_DEATH]); + rate_values[RATE_DURABILITY_LOSS_ON_DEATH] = 0.0f; + } + if(rate_values[RATE_DURABILITY_LOSS_ON_DEATH] > 100.0f) + { + sLog.outError("DurabilityLoss.OnDeath (%f) must be <=100. Using 100.0 instead.",rate_values[RATE_DURABILITY_LOSS_ON_DEATH]); + rate_values[RATE_DURABILITY_LOSS_ON_DEATH] = 0.0f; + } + rate_values[RATE_DURABILITY_LOSS_ON_DEATH] = rate_values[RATE_DURABILITY_LOSS_ON_DEATH] / 100.0f; + rate_values[RATE_DURABILITY_LOSS_DAMAGE] = sConfig.GetFloatDefault("DurabilityLossChance.Damage",0.5f); if(rate_values[RATE_DURABILITY_LOSS_DAMAGE] < 0.0f) { @@ -547,6 +566,8 @@ void World::LoadConfigSettings(bool reload) ///- Read other configuration items from the config file + m_configs[CONFIG_DURABILITY_LOSS_IN_PVP] = sConfig.GetBoolDefault("DurabilityLoss.InPvP", false); + m_configs[CONFIG_COMPRESSION] = sConfig.GetIntDefault("Compression", 1); if(m_configs[CONFIG_COMPRESSION] < 1 || m_configs[CONFIG_COMPRESSION] > 9) { diff --git a/src/game/World.h b/src/game/World.h index 78d4c181b4a..d590a552f26 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -164,6 +164,7 @@ enum WorldConfigs CONFIG_SKILL_GAIN_DEFENSE, CONFIG_SKILL_GAIN_GATHERING, CONFIG_SKILL_GAIN_WEAPON, + CONFIG_DURABILITY_LOSS_IN_PVP, CONFIG_MAX_OVERSPEED_PINGS, CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY, CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL, @@ -279,6 +280,7 @@ enum Rates RATE_XP_KILL, RATE_XP_QUEST, RATE_XP_EXPLORE, + RATE_REPAIRCOST, RATE_REPUTATION_GAIN, RATE_REPUTATION_LOWLEVEL_KILL, RATE_REPUTATION_LOWLEVEL_QUEST, @@ -312,6 +314,7 @@ enum Rates RATE_CORPSE_DECAY_LOOTED, RATE_INSTANCE_RESET_TIME, RATE_TARGET_POS_RECALCULATION_RANGE, + RATE_DURABILITY_LOSS_ON_DEATH, RATE_DURABILITY_LOSS_DAMAGE, RATE_DURABILITY_LOSS_PARRY, RATE_DURABILITY_LOSS_ABSORB, diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index 44c1199c277..617d5baca62 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -1243,6 +1243,14 @@ Visibility.Distance.Grey.Object = 10 # Default: 0 - no decrease # 75 - in 2 times each 75 skill points # +# DurabilityLoss.InPvP +# If true, players take durability loss on death in PvP. +# Default: 0 (false) +# 1 (true) +# +# DurabilityLoss.OnDeath +# Durability loss percentage on death (10 - standard, 20 - double, 5 - half) +# # DurabilityLossChance.Damage # Chance lost one from equiped items durability point at damage apply or receive. # Default: 0.5 (100/0.5 = 200) Each 200 damage apply one from 19 possible equipped items @@ -1327,6 +1335,8 @@ SkillChance.Green = 25 SkillChance.Grey = 0 SkillChance.MiningSteps = 0 SkillChance.SkinningSteps = 0 +DurabilityLoss.InPvP = 0 +DurabilityLoss.OnDeath = 10 DurabilityLossChance.Damage = 0.5 DurabilityLossChance.Absorb = 0.5 DurabilityLossChance.Parry = 0.05 |