aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormaximius <none@none>2009-08-07 12:12:42 -0700
committermaximius <none@none>2009-08-07 12:12:42 -0700
commitfe3ba612d94b715bbbbac944418be1188ad66339 (patch)
treedcfba651a684cd3f896988e361240f91c4b1d80f /src
parentbe74be36f6d170fd11b2df2ebfc20a9c2e40584a (diff)
*Emalon the Stormwatcher fully scripted, by Necroo (boss needs to be spawned and ScriptName needs to be updated)
*Added config options: DurabilityLoss.OnDeath and DurabilityLoss.InPvP, optimized Rate.RepairCost --HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/CMakeLists.txt1
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp4
-rw-r--r--src/bindings/scripts/VC80/80ScriptDev2.vcproj4
-rw-r--r--src/bindings/scripts/VC90/90ScriptDev2.vcproj4
-rw-r--r--src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp62
-rw-r--r--src/bindings/scripts/scripts/zone/vault_of_archavon/boss_emalon.cpp284
-rw-r--r--src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h9
-rw-r--r--src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp103
-rw-r--r--src/game/Player.cpp3
-rw-r--r--src/game/Unit.cpp6
-rw-r--r--src/game/World.cpp21
-rw-r--r--src/game/World.h3
-rw-r--r--src/trinitycore/trinitycore.conf.dist10
13 files changed, 478 insertions, 36 deletions
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