*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
This commit is contained in:
maximius
2009-08-07 12:12:42 -07:00
parent be74be36f6
commit fe3ba612d9
15 changed files with 489 additions and 36 deletions
+6
View File
@@ -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'),
+5
View File
@@ -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');
+1
View File
@@ -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
+4
View File
@@ -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();
@@ -2833,6 +2833,10 @@
RelativePath="..\scripts\zone\vault_of_archavon\boss_archavon.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\vault_of_archavon\boss_emalon.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\vault_of_archavon\def_vault_of_archavon.h"
>
@@ -2834,6 +2834,10 @@
RelativePath="..\scripts\zone\vault_of_archavon\boss_archavon.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\vault_of_archavon\boss_emalon.cpp"
>
</File>
<File
RelativePath="..\scripts\zone\vault_of_archavon\def_vault_of_archavon.h"
>
@@ -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();
if(pInstance)
pInstance->SetData(DATA_ARCHAVON_EVENT, NOT_STARTED);
}
void KilledUnit(Unit* Victim)
{
if(!(rand()%5))
DoScriptText(SAY_SLAY, me);
}
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
@@ -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();
}
@@ -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
@@ -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)
+1 -2
View File
@@ -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;
+3 -3
View File
@@ -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);
+21
View File
@@ -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)
{
+3
View File
@@ -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,
+10
View File
@@ -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