This commit is contained in:
SecretsOTheP
2014-02-13 12:02:37 -05:00
26 changed files with 960 additions and 1069 deletions
+17 -21
View File
@@ -1212,6 +1212,10 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
case SE_CriticalMend:
newbon->CriticalMend += base1;
break;
case SE_HealRate:
newbon->HealRate += base1;
break;
}
}
}
@@ -1603,10 +1607,6 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
newbon->MeleeMitigation -= effect_value;
break;
case SE_IncreaseHitDmgTaken:
newbon->MeleeMitigation += effect_value;
break;
case SE_CriticalHitChance:
{
@@ -2773,12 +2773,12 @@ uint8 Mob::IsFocusEffect(uint16 spell_id,int effect_index, bool AA,uint32 aa_eff
case SE_TriggerOnCast:
//return focusTriggerOnCast;
return 0; //This is calculated as an actual bonus
case SE_SpellVulnerability:
case SE_FcSpellVulnerability:
return focusSpellVulnerability;
case SE_BlockNextSpellFocus:
//return focusBlockNextSpell;
return 0; //This is calculated as an actual bonus
case SE_Twincast:
case SE_FcTwincast:
return focusTwincast;
case SE_SympatheticProc:
return focusSympatheticProc;
@@ -2792,24 +2792,26 @@ uint8 Mob::IsFocusEffect(uint16 spell_id,int effect_index, bool AA,uint32 aa_eff
return focusFcDamageAmtIncoming;
case SE_FcHealAmtIncoming:
return focusFcHealAmtIncoming;
case SE_HealRate2:
return focusHealRate;
case SE_FcHealPctIncoming:
return focusFcHealPctIncoming;
case SE_FcBaseEffects:
return focusFcBaseEffects;
case SE_IncreaseNumHits:
case SE_FcIncreaseNumHits:
return focusIncreaseNumHits;
case SE_FcLimitUse:
return focusFcLimitUse;
case SE_FcMute:
return focusFcMute;
case SE_FcTimerRefresh:
return focusFcTimerRefresh;
case SE_FcStunTimeMod:
return focusFcStunTimeMod;
case SE_CriticalHealRate:
return focusCriticalHealRate;
case SE_AdditionalHeal2:
return focusAdditionalHeal2;
case SE_AdditionalHeal:
return focusAdditionalHeal;
case SE_FcHealPctCritIncoming:
return focusFcHealPctCritIncoming;
case SE_FcHealAmt:
return focusFcHealAmt;
case SE_FcHealAmtCrit:
return focusFcHealAmtCrit;
}
return 0;
}
@@ -3115,12 +3117,6 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
aabonuses.MeleeMitigation = effect_value;
break;
case SE_IncreaseHitDmgTaken:
spellbonuses.MeleeMitigation = effect_value;
itembonuses.MeleeMitigation = effect_value;
aabonuses.MeleeMitigation = effect_value;
break;
case SE_CriticalHitChance:
{
for(int e = 0; e < HIGHEST_SKILL+1; e++)
+93 -129
View File
@@ -6736,7 +6736,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id)
if((spell.classes[(GetClass()%16) - 1]) < base1)
LimitFound = true;
break;
case SE_LimitCastTime:
case SE_LimitCastTimeMin:
if (spell.cast_time < base1)
LimitFound = true;
break;
@@ -6782,7 +6782,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id)
}
break;
case SE_LimitManaCost:
case SE_LimitManaMin:
if(spell.mana < base1)
LimitFound = true;
break;
@@ -6800,7 +6800,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id)
}
break;
case SE_CombatSkills:
case SE_LimitCombatSkills:
// 1 is for disciplines only
if(base1 == 1 && !IsDiscipline(spell_id))
LimitFound = true;
@@ -6817,13 +6817,13 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id)
break;
case SE_LimitSpellSkill:
case SE_LimitCastingSkill:
LimitSpellSkill = true;
if(base1 == spell.skill)
SpellSkill_Found = true;
break;
case SE_LimitExcludeSkill:{
case SE_LimitSpellSubclass:{
int16 spell_skill = spell.skill * -1;
if(base1 == spell_skill)
LimitFound = true;
@@ -6941,7 +6941,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id)
}
break;
}
case SE_SpellVulnerability:
case SE_FcSpellVulnerability:
{
if(type == focusSpellVulnerability)
{
@@ -6958,7 +6958,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id)
}
break;
}
case SE_Twincast:
case SE_FcTwincast:
{
if(type == focusTwincast)
{
@@ -7010,37 +7010,30 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id)
break;
}
case SE_CriticalHealRate:
{
if (type == focusCriticalHealRate)
case SE_FcHealAmtIncoming:
if(type == focusFcHealAmtIncoming)
value = base1;
break;
}
case SE_AdditionalHeal:
{
if(type == focusAdditionalHeal)
case SE_FcHealPctCritIncoming:
if (type == focusFcHealPctCritIncoming)
value = base1;
break;
}
case SE_AdditionalHeal2:
{
if(type == focusAdditionalHeal2)
case SE_FcHealAmtCrit:
if(type == focusFcHealAmtCrit)
value = base1;
break;
}
case SE_HealRate2:
{
if(type == focusHealRate)
case SE_FcHealAmt:
if(type == focusFcHealAmt)
value = base1;
break;
case SE_FcHealPctIncoming:
if(type == focusFcHealPctIncoming)
value = base1;
break;
}
case SE_FcBaseEffects:
{
@@ -7057,7 +7050,7 @@ int16 Bot::CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id)
break;
}
case SE_IncreaseNumHits:
case SE_FcIncreaseNumHits:
{
if(type == focusIncreaseNumHits)
value = base1;
@@ -7338,7 +7331,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
return(0);
break;
case SE_LimitCastTime:
case SE_LimitCastTimeMin:
if (spells[spell_id].cast_time < (uint16)focus_spell.base[i])
return(0);
break;
@@ -7398,7 +7391,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
}
break;
case SE_LimitManaCost:
case SE_LimitManaMin:
if(spell.mana < focus_spell.base[i])
return 0;
break;
@@ -7413,7 +7406,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
break;
case SE_CombatSkills:
case SE_LimitCombatSkills:
// 1 is for disciplines only
if(focus_spell.base[i] == 1 && !IsDiscipline(spell_id))
return 0;
@@ -7429,13 +7422,13 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
return 0;
break;
case SE_LimitSpellSkill:
case SE_LimitCastingSkill:
LimitSpellSkill = true;
if(focus_spell.base[i] == spell.skill)
SpellSkill_Found = true;
break;
case SE_LimitExcludeSkill:{
case SE_LimitSpellSubclass:{
int16 spell_skill = spell.skill * -1;
if(focus_spell.base[i] == spell_skill)
return 0;
@@ -7602,7 +7595,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
break;
}
case SE_SpellVulnerability:
case SE_FcSpellVulnerability:
{
if(bottype == BotfocusSpellVulnerability)
{
@@ -7619,7 +7612,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
}
break;
}
case SE_Twincast:
case SE_FcTwincast:
{
if(bottype == BotfocusTwincast)
{
@@ -7660,45 +7653,30 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
break;
}
case SE_FcDamageAmtIncoming:
{
if(bottype == BotfocusFcDamageAmtIncoming)
case SE_FcHealAmtIncoming:
if(bottype == BotfocusFcHealAmtIncoming)
value = focus_spell.base[i];
break;
}
case SE_CriticalHealRate:
{
if (bottype == BotfocusCriticalHealRate)
case SE_FcHealPctCritIncoming:
if (bottype == BotfocusFcHealPctCritIncoming)
value = focus_spell.base[i];
break;
}
case SE_AdditionalHeal:
{
if(bottype == BotfocusAdditionalHeal)
case SE_FcHealAmtCrit:
if(bottype == BotfocusFcHealAmtCrit)
value = focus_spell.base[i];
break;
}
case SE_AdditionalHeal2:
{
if(bottype == BotfocusAdditionalHeal2)
case SE_FcHealAmt:
if(bottype == BotfocusFcHealAmt)
value = focus_spell.base[i];
break;
}
case SE_HealRate2:
{
if(bottype == BotfocusHealRate)
case SE_FcHealPctIncoming:
if(bottype == BotfocusFcHealPctIncoming)
value = focus_spell.base[i];
break;
}
case SE_FcBaseEffects:
{
@@ -7715,7 +7693,7 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
break;
}
case SE_IncreaseNumHits:
case SE_FcIncreaseNumHits:
{
if(bottype == BotfocusIncreaseNumHits)
value = focus_spell.base[i];
@@ -9119,23 +9097,6 @@ void Bot::SetAttackTimer() {
}
}
int32 Bot::Additional_SpellDmg(uint16 spell_id, bool bufftick)
{
int32 spell_dmg = 0;
spell_dmg += GetBotFocusEffect(BotfocusFcDamageAmtCrit, spell_id);
spell_dmg += GetBotFocusEffect(BotfocusFcDamageAmt, spell_id);
//For DOTs you need to apply the damage over the duration of the dot to each tick (this is how live did it)
if (bufftick){
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
return spell_dmg /= duration;
else
return 0;
}
return spell_dmg;
}
int32 Bot::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
if (spells[spell_id].targettype == ST_Self)
@@ -9196,7 +9157,7 @@ int32 Bot::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
value -= GetBotFocusEffect(BotfocusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellDmg(spell_id, itembonuses.SpellDmg, value)*ratio/100;
value += GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s delivers a critical blast! (%d)", GetName(), -value);
@@ -9220,70 +9181,73 @@ int32 Bot::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
value -= GetBotFocusEffect(BotfocusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellDmg(spell_id, itembonuses.SpellDmg, value);
value += GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
return value;
}
int32 Bot::Additional_Heal(uint16 spell_id)
{
int32 heal_amt = 0;
int32 Bot::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
if (target == nullptr)
target = this;
heal_amt += GetBotFocusEffect(BotfocusAdditionalHeal, spell_id);
heal_amt += GetBotFocusEffect(BotfocusAdditionalHeal2, spell_id);
if (heal_amt){
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
return heal_amt /= duration;
}
return heal_amt;
}
int32 Bot::GetActSpellHealing(uint16 spell_id, int32 value) {
int32 modifier = 100;
int16 heal_amt = 0;
modifier += GetBotFocusEffect(BotfocusImprovedHeal, spell_id);
modifier += GetBotFocusEffect(BotfocusFcBaseEffects, spell_id);
heal_amt += Additional_Heal(spell_id);
int chance = 0;
int32 value_BaseEffect = 0;
int16 chance = 0;
int8 modifier = 1;
bool Critical = false;
value_BaseEffect = value + (value*GetBotFocusEffect(BotfocusFcBaseEffects, spell_id)/100);
value = value_BaseEffect;
value += int(value_BaseEffect*GetBotFocusEffect(BotfocusImprovedHeal, spell_id)/100);
// Instant Heals
if(spells[spell_id].buffduration < 1) {
uint8 botlevel = GetLevel();
uint8 botclass = GetClass();
// Formula = HealAmt * (casttime + recastime) / 7; Cant trigger off spell less than 5 levels below and cant heal more than the spell itself.
if(this->itembonuses.HealAmt && spells[spell_id].classes[(botclass%16) - 1] >= botlevel - 5) {
heal_amt = this->itembonuses.HealAmt * (spells[spell_id].cast_time + spells[spell_id].recast_time) / 7000;
if(heal_amt > value)
heal_amt = value;
}
// Check for buffs that affect the healrate of the target and critical heal rate of target
if(GetTarget()) {
value += value * GetHealRate(spell_id) / 100;
chance += GetCriticalHealRate(spell_id);
}
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
//Live AA - Healing Gift, Theft of Life
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
if (spellbonuses.CriticalHealDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
if(chance && (MakeRandomInt(0,99) < chance)) {
Critical = true;
modifier = 2; //At present time no critical heal amount modifier SPA exists.
}
value *= modifier;
value += GetBotFocusEffect(BotfocusFcHealAmtCrit, spell_id) * modifier;
value += GetBotFocusEffect(BotfocusFcHealAmt, spell_id);
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
if(MakeRandomInt(0,99) < chance) {
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), ((value * modifier / 50) + heal_amt*2));
return ((value * modifier / 50) + heal_amt*2);
}
else{
return ((value * modifier / 100) + heal_amt);
}
if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier;
value += value*target->GetHealRate(spell_id, this)/100;
if (Critical)
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), value);
return value;
}
// Hots
//Heal over time spells. [Heal Rate and Additional Healing effects do not increase this value]
else {
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
if(MakeRandomInt(0,99) < chance)
return ((value * modifier / 50) + heal_amt*2);
chance = itembonuses.CriticalHealOverTime + spellbonuses.CriticalHealOverTime + aabonuses.CriticalHealOverTime;
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
if (spellbonuses.CriticalRegenDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay);
if(chance && (MakeRandomInt(0,99) < chance))
return (value * 2);
}
return ((value * modifier / 100) + heal_amt);
return value;
}
int32 Bot::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
+7 -8
View File
@@ -86,13 +86,14 @@ public:
BotfocusSwarmPetDuration,
BotfocusReduceRecastTime,
BotfocusBlockNextSpell,
BotfocusHealRate,
BotfocusFcHealPctIncoming,
BotfocusFcDamageAmtIncoming,
BotfocusFcHealAmtIncoming,
BotfocusFcBaseEffects,
BotfocusIncreaseNumHits,
BotfocusCriticalHealRate,
BotfocusAdditionalHeal2,
BotfocusAdditionalHeal,
BotfocusFcHealPctCritIncoming,
BotfocusFcHealAmt,
BotfocusFcHealAmtCrit,
};
enum BotTradeType { // types of trades a bot can do
@@ -301,10 +302,8 @@ public:
// Mob Spell Virtual Override Methods
virtual void SpellProcess();
int32 Additional_SpellDmg(uint16 spell_id, bool bufftick = false);
int32 Additional_Heal(uint16 spell_id);
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target);
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value);
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
virtual int32 GetActSpellCost(uint16 spell_id, int32 cost);
virtual float GetActSpellRange(uint16 spell_id, float range);
+4 -3
View File
@@ -427,7 +427,6 @@ Client::~Client() {
eqs->Close();
eqs->ReleaseFromUse();
//entity_list.RemoveClient(this);
UninitializeBuffSlots();
}
@@ -1083,10 +1082,12 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
{
// Emotes for Underfoot and later.
// crash protection -- cheater
if (strlen(message) > 512)
message[1023] = '\0';
size_t msg_len = strlen(message);
if (msg_len > 512)
message[512] = '\0';
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Emote, 4 + strlen(message) + strlen(GetName()) + 2);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Emote, 4 + msg_len + strlen(GetName()) + 2);
Emote_Struct* es = (Emote_Struct*)outapp->pBuffer;
char *Buffer = (char *)es;
Buffer += 4;
+2 -4
View File
@@ -472,11 +472,9 @@ public:
inline virtual int16 GetDelayDeath() const { return aabonuses.DelayDeath + spellbonuses.DelayDeath + itembonuses.DelayDeath + 11; }
int32 Additional_SpellDmg(uint16 spell_id, bool bufftick = false);
int32 Additional_Heal(uint16 spell_id);
float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);
int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob *target = nullptr);
int32 GetActSpellHealing(uint16 spell_id, int32 value);
int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
int32 GetActSpellCost(uint16 spell_id, int32);
int32 GetActSpellDuration(uint16 spell_id, int32);
int32 GetActSpellCasttime(uint16 spell_id, int32);
+3
View File
@@ -7361,6 +7361,8 @@ void Client::Handle_OP_Emote(const EQApplicationPacket *app)
// Calculate new packet dimensions
Emote_Struct* in = (Emote_Struct*)app->pBuffer;
in->message[1023] = '\0';
const char* name = GetName();
uint32 len_name = strlen(name);
uint32 len_msg = strlen(in->message);
@@ -11624,6 +11626,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app)
}
GMSearchCorpse_Struct *gmscs = (GMSearchCorpse_Struct *)app->pBuffer;
gmscs->Name[63] = '\0';
char errbuf[MYSQL_ERRMSG_SIZE];
char* Query = 0;
+8 -6
View File
@@ -71,19 +71,20 @@ typedef enum { //focus types
focusSwarmPetDuration,
focusReduceRecastTime,
focusBlockNextSpell,
focusHealRate,
focusFcHealPctIncoming,
focusFcDamageAmtIncoming,
focusFcHealAmtIncoming,
focusFcBaseEffects,
focusIncreaseNumHits,
focusFcLimitUse,
focusFcMute,
focusFcTimerRefresh,
focusFcStunTimeMod,
focusCriticalHealRate,
focusAdditionalHeal2,
focusAdditionalHeal,
focusFcHealPctCritIncoming,
focusFcHealAmt,
focusFcHealAmtCrit,
} focusType; //Any new FocusType needs to be added to the Mob::IsFocus function
#define HIGHEST_FOCUS focusAdditionalHeal //Should always be last focusType in enum
#define HIGHEST_FOCUS focusFcHealAmtCrit //Should always be last focusType in enum
enum {
SPECATK_SUMMON = 1,
@@ -120,7 +121,8 @@ enum {
LEASH = 32,
TETHER = 33,
DESTRUCTIBLE_OBJECT = 34,
NO_HARM_FROM_CLIENT = 35
NO_HARM_FROM_CLIENT = 35,
MAX_SPECIAL_ATTACK = 36
};
typedef enum { //fear states
+78 -122
View File
@@ -40,23 +40,6 @@ float Client::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
}
int32 Client::Additional_SpellDmg(uint16 spell_id, bool bufftick)
{
int32 spell_dmg = 0;
spell_dmg += GetFocusEffect(focusFcDamageAmtCrit, spell_id);
spell_dmg += GetFocusEffect(focusFcDamageAmt, spell_id);
//For DOTs you need to apply the damage over the duration of the dot to each tick (this is how live did it)
if (bufftick){
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
return spell_dmg /= duration;
else
return 0;
}
return spell_dmg;
}
int32 NPC::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
//Quest scale all NPC spell damage via $npc->SetSpellFocusDMG(value)
@@ -138,7 +121,7 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellDmg(spell_id, itembonuses.SpellDmg, value)*ratio/100;
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s delivers a critical blast! (%d)", GetName(), -value);
@@ -162,7 +145,7 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellDmg(spell_id, itembonuses.SpellDmg, value);
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
return value;
}
@@ -184,7 +167,7 @@ int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
if (chance > 0 && (MakeRandomInt(1, 100) <= chance)) {
int32 ratio = 100;
int32 ratio = 200;
ratio += itembonuses.DotCritDmgIncrease + spellbonuses.DotCritDmgIncrease + aabonuses.DotCritDmgIncrease;
value = value_BaseEffect*ratio/100;
@@ -199,8 +182,11 @@ int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
int(GetFocusEffect(focusFcDamageAmtCrit, spell_id)*ratio/100) +
GetFocusEffect(focusFcDamageAmt, spell_id);
if (extra_dmg)
extra_dmg /= CalcBuffDuration(this, this, spell_id);
if (extra_dmg) {
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
extra_dmg /= duration;
}
value -= extra_dmg;
@@ -220,41 +206,18 @@ int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
GetFocusEffect(focusFcDamageAmtCrit, spell_id) +
GetFocusEffect(focusFcDamageAmt, spell_id);
if (extra_dmg)
extra_dmg /= CalcBuffDuration(this, this, spell_id);
if (extra_dmg) {
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
extra_dmg /= duration;
}
value -= extra_dmg;
return value;
}
/*
int32 modifier = 100;
int16 spell_dmg = 0;
int16 critChance = 0;
int32 ratio = 0;
modifier += GetFocusEffect(focusImprovedDamage, spell_id);
critChance += itembonuses.CriticalDoTChance + spellbonuses.CriticalDoTChance + aabonuses.CriticalDoTChance;
ratio += itembonuses.DotCritDmgIncrease + spellbonuses.DotCritDmgIncrease + aabonuses.DotCritDmgIncrease;
spell_dmg += Additional_SpellDmg(spell_id,true);
if (spellbonuses.CriticalDotDecay)
critChance += GetDecayEffectValue(spell_id, SE_CriticalDotDecay);
if (critChance > 0){
if (MakeRandomInt(0, 99) < critChance){
modifier += modifier*ratio/100;
return (((value*modifier/100)-spell_dmg)*2);
}
}
return ((value*modifier/100)-spell_dmg);
*/
int32 Mob::GetExtraSpellDmg(uint16 spell_id, int32 extra_spell_dmg, int32 base_spell_dmg)
int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg)
{
int total_cast_time = 0;
@@ -264,105 +227,98 @@ int32 Mob::GetExtraSpellDmg(uint16 spell_id, int32 extra_spell_dmg, int32 base_s
total_cast_time = spells[spell_id].recovery_time + spells[spell_id].cast_time;
if (total_cast_time > 0 && total_cast_time <= 2500)
extra_spell_dmg = extra_spell_dmg*25/100;
extra_spell_amt = extra_spell_amt*25/100;
else if (total_cast_time > 2500 && total_cast_time < 7000)
extra_spell_dmg = extra_spell_dmg*(0.167*((total_cast_time - 1000)/1000));
extra_spell_amt = extra_spell_amt*(0.167*((total_cast_time - 1000)/1000));
else
extra_spell_dmg = extra_spell_dmg * total_cast_time / 7000;
extra_spell_amt = extra_spell_amt * total_cast_time / 7000;
extra_spell_dmg = -extra_spell_dmg;
if(extra_spell_dmg*2 < base_spell_dmg)
if(extra_spell_amt*2 < base_spell_dmg)
return 0;
return extra_spell_dmg;
return extra_spell_amt;
}
//Scale all NPC spell healing via SetSpellFocusHeal(value)
int32 NPC::GetActSpellHealing(uint16 spell_id, int32 value) {
int32 NPC::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
int32 modifier = 100;
modifier += SpellFocusHeal;
//Scale all NPC spell healing via SetSpellFocusHeal(value)
// Check for buffs that affect the healrate of the target
if(this->GetTarget())
{
value += value * GetHealRate(spell_id) / 100;
}
value += value*SpellFocusHeal/100;
return (value * modifier / 100);
if (target) {
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
value += value*target->GetHealRate(spell_id, this)/100;
}
return value;
}
int32 Client::Additional_Heal(uint16 spell_id)
{
int32 heal_amt = 0;
int32 Client::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
if (target == nullptr)
target = this;
heal_amt += GetFocusEffect(focusAdditionalHeal, spell_id);
heal_amt += GetFocusEffect(focusAdditionalHeal2, spell_id);
heal_amt -= GetFocusEffect(focusFcHealAmtIncoming, spell_id);
if (heal_amt){
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
return heal_amt /= duration;
}
return heal_amt;
}
int32 Client::GetActSpellHealing(uint16 spell_id, int32 value) {
int32 modifier = 100;
int16 heal_amt = 0;
modifier += GetFocusEffect(focusImprovedHeal, spell_id);
modifier += GetFocusEffect(focusFcBaseEffects, spell_id);
heal_amt += Additional_Heal(spell_id);
int chance = 0;
int32 value_BaseEffect = 0;
int16 chance = 0;
int8 modifier = 1;
bool Critical = false;
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
value = value_BaseEffect;
value += int(value_BaseEffect*GetFocusEffect(focusImprovedHeal, spell_id)/100);
// Instant Heals
if(spells[spell_id].buffduration < 1)
{
// Formula = HealAmt * (casttime + recastime) / 7; Cant trigger off spell less than 5 levels below and cant heal more than the spell itself.
if(this->itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) {
heal_amt = this->itembonuses.HealAmt * (spells[spell_id].cast_time + spells[spell_id].recast_time) / 7000;
if(heal_amt > value)
heal_amt = value;
}
if(spells[spell_id].buffduration < 1) {
// Check for buffs that affect the healrate of the target and critical heal rate of target
if(GetTarget()){
value += value * GetHealRate(spell_id) / 100;
chance += GetCriticalHealRate(spell_id);
}
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
//Live AA - Healing Gift, Theft of Life
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
if (spellbonuses.CriticalRegenDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
if (spellbonuses.CriticalHealDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
if(chance && (MakeRandomInt(0,99) < chance)) {
Critical = true;
modifier = 2; //At present time no critical heal amount modifier SPA exists.
}
value *= modifier;
value += GetFocusEffect(focusFcHealAmtCrit, spell_id) * modifier;
value += GetFocusEffect(focusFcHealAmt, spell_id);
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier;
if(MakeRandomInt(0,99) < chance) {
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), ((value * modifier / 50) + heal_amt*2));
return ((value * modifier / 50) + heal_amt*2);
}
else{
return ((value * modifier / 100) + heal_amt);
}
value += value*target->GetHealRate(spell_id, this)/100;
if (Critical)
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), value);
return value;
}
// Hots
//Heal over time spells. [Heal Rate and Additional Healing effects do not increase this value]
else {
chance += itembonuses.CriticalHealOverTime + spellbonuses.CriticalHealOverTime + aabonuses.CriticalHealOverTime;
chance = itembonuses.CriticalHealOverTime + spellbonuses.CriticalHealOverTime + aabonuses.CriticalHealOverTime;
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
if (spellbonuses.CriticalRegenDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay);
if(MakeRandomInt(0,99) < chance)
return ((value * modifier / 50) + heal_amt*2);
if(chance && (MakeRandomInt(0,99) < chance))
return (value * 2);
}
return ((value * modifier / 100) + heal_amt);
return value;
}
int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
{
// Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
+4 -4
View File
@@ -2031,12 +2031,12 @@ bool EntityList::RemoveMob(uint16 delete_id)
auto it = mob_list.find(delete_id);
if (it != mob_list.end()) {
if (npc_list.find(delete_id) != npc_list.end())
if (npc_list.count(delete_id))
entity_list.RemoveNPC(delete_id);
else if (client_list.find(delete_id) != client_list.end())
else if (client_list.count(delete_id))
entity_list.RemoveClient(delete_id);
safe_delete(it->second);
if (corpse_list.find(delete_id) == corpse_list.end())
if (!corpse_list.count(delete_id))
free_ids.push(it->first);
mob_list.erase(it);
return true;
@@ -2054,7 +2054,7 @@ bool EntityList::RemoveMob(Mob *delete_mob)
while (it != mob_list.end()) {
if (it->second == delete_mob) {
safe_delete(it->second);
if (corpse_list.find(it->first) == corpse_list.end())
if (!corpse_list.count(it->first))
free_ids.push(it->first);
mob_list.erase(it);
return true;
+71 -28
View File
@@ -1057,17 +1057,27 @@ void Client::LeaveGroup() {
isgrouped = false;
}
void Group::HealGroup(uint32 heal_amt, Mob* caster)
void Group::HealGroup(uint32 heal_amt, Mob* caster, int32 range)
{
if (!caster)
return;
if (!range)
range = 200;
float distance;
float range2 = range*range;
int numMem = 0;
unsigned int gi = 0;
for(; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
numMem += 1;
distance = caster->DistNoRoot(*members[gi]);
if(distance <= range2){
numMem += 1;
}
}
}
@@ -1075,23 +1085,38 @@ void Group::HealGroup(uint32 heal_amt, Mob* caster)
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
//members[gi]->SetHP(members[gi]->GetHP() + heal_amt);
members[gi]->HealDamage(heal_amt, caster);
members[gi]->SendHPUpdate();
distance = caster->DistNoRoot(*members[gi]);
if(distance <= range2){
members[gi]->HealDamage(heal_amt, caster);
members[gi]->SendHPUpdate();
}
}
}
}
void Group::BalanceHP(int32 penalty)
void Group::BalanceHP(int32 penalty, int32 range, Mob* caster)
{
if (!caster)
return;
if (!range)
range = 200;
int dmgtaken = 0, numMem = 0;
float distance;
float range2 = range*range;
unsigned int gi = 0;
for(; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
dmgtaken += (members[gi]->GetMaxHP() - members[gi]->GetHP());
numMem += 1;
distance = caster->DistNoRoot(*members[gi]);
if(distance <= range2){
dmgtaken += (members[gi]->GetMaxHP() - members[gi]->GetHP());
numMem += 1;
}
}
}
@@ -1100,27 +1125,42 @@ void Group::BalanceHP(int32 penalty)
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
if((members[gi]->GetMaxHP() - dmgtaken) < 1){ //this way the ability will never kill someone
members[gi]->SetHP(1); //but it will come darn close
members[gi]->SendHPUpdate();
}
else{
members[gi]->SetHP(members[gi]->GetMaxHP() - dmgtaken);
members[gi]->SendHPUpdate();
distance = caster->DistNoRoot(*members[gi]);
if(distance <= range2){
if((members[gi]->GetMaxHP() - dmgtaken) < 1){ //this way the ability will never kill someone
members[gi]->SetHP(1); //but it will come darn close
members[gi]->SendHPUpdate();
}
else{
members[gi]->SetHP(members[gi]->GetMaxHP() - dmgtaken);
members[gi]->SendHPUpdate();
}
}
}
}
}
void Group::BalanceMana(int32 penalty)
void Group::BalanceMana(int32 penalty, int32 range, Mob* caster)
{
if (!caster)
return;
if (!range)
range = 200;
float distance;
float range2 = range*range;
int manataken = 0, numMem = 0;
unsigned int gi = 0;
for(; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
manataken += (members[gi]->GetMaxMana() - members[gi]->GetMana());
numMem += 1;
if(members[gi]){
distance = caster->DistNoRoot(*members[gi]);
if(distance <= range2){
manataken += (members[gi]->GetMaxMana() - members[gi]->GetMana());
numMem += 1;
}
}
}
@@ -1129,15 +1169,18 @@ void Group::BalanceMana(int32 penalty)
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
if((members[gi]->GetMaxMana() - manataken) < 1){
members[gi]->SetMana(1);
if (members[gi]->IsClient())
members[gi]->CastToClient()->SendManaUpdate();
}
else{
members[gi]->SetMana(members[gi]->GetMaxMana() - manataken);
if (members[gi]->IsClient())
members[gi]->CastToClient()->SendManaUpdate();
distance = caster->DistNoRoot(*members[gi]);
if(distance <= range2){
if((members[gi]->GetMaxMana() - manataken) < 1){
members[gi]->SetMana(1);
if (members[gi]->IsClient())
members[gi]->CastToClient()->SendManaUpdate();
}
else{
members[gi]->SetMana(members[gi]->GetMaxMana() - manataken);
if (members[gi]->IsClient())
members[gi]->CastToClient()->SendManaUpdate();
}
}
}
}
+3 -3
View File
@@ -86,9 +86,9 @@ public:
uint16 GetAvgLevel();
bool LearnMembers();
void VerifyGroup();
void BalanceHP(int32 penalty);
void BalanceMana(int32 penalty);
void HealGroup(uint32 heal_amt, Mob* caster);
void BalanceHP(int32 penalty, int32 range = 0, Mob* caster = nullptr);
void BalanceMana(int32 penalty, int32 range = 0, Mob* caster = nullptr);
void HealGroup(uint32 heal_amt, Mob* caster, int32 range = 0);
inline void SetGroupAAs(GroupLeadershipAA_Struct *From) { memcpy(&LeaderAbilities, From, sizeof(GroupLeadershipAA_Struct)); }
inline void GetGroupAAs(GroupLeadershipAA_Struct *Into) { memcpy(Into, &LeaderAbilities, sizeof(GroupLeadershipAA_Struct)); }
void UpdateGroupAAs();
+54 -71
View File
@@ -2771,22 +2771,6 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) {
return realTotal + realTotal2 + realTotal3;
}
int32 Merc::Additional_SpellDmg(uint16 spell_id, bool bufftick)
{
int32 spell_dmg = 0;
spell_dmg += GetFocusEffect(focusFcDamageAmtCrit, spell_id);
spell_dmg += GetFocusEffect(focusFcDamageAmt, spell_id);
//For DOTs you need to apply the damage over the duration of the dot to each tick (this is how live did it)
if (bufftick){
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
return spell_dmg /= duration;
else
return 0;
}
return spell_dmg;
}
int32 Merc::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
@@ -2836,7 +2820,7 @@ int32 Merc::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellDmg(spell_id, itembonuses.SpellDmg, value)*ratio/100;
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
value = (value * GetSpellScale() / 100);
@@ -2862,76 +2846,75 @@ int32 Merc::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellDmg(spell_id, itembonuses.SpellDmg, value);
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
value = (value * GetSpellScale() / 100);
return value;
}
int32 Merc::Additional_Heal(uint16 spell_id)
{
int32 heal_amt = 0;
int32 Merc::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
if (target == nullptr)
target = this;
heal_amt += GetFocusEffect(focusAdditionalHeal, spell_id);
heal_amt += GetFocusEffect(focusAdditionalHeal2, spell_id);
heal_amt += GetFocusEffect(focusFcHealAmtIncoming, spell_id);
if (heal_amt){
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
return heal_amt /= duration;
}
return heal_amt;
}
int32 Merc::GetActSpellHealing(uint16 spell_id, int32 value) {
int32 modifier = 100;
int16 heal_amt = 0;
modifier += GetFocusEffect(focusImprovedHeal, spell_id);
modifier += GetFocusEffect(focusFcBaseEffects, spell_id);
heal_amt += Additional_Heal(spell_id);
int chance = 0;
int32 value_BaseEffect = 0;
int16 chance = 0;
int8 modifier = 1;
bool Critical = false;
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
value = value_BaseEffect;
value += int(value_BaseEffect*GetFocusEffect(focusImprovedHeal, spell_id)/100);
// Instant Heals
if(spells[spell_id].buffduration < 1)
{
// Formula = HealAmt * (casttime + recastime) / 7; Cant trigger off spell less than 5 levels below and cant heal more than the spell itself.
if(this->itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) {
heal_amt = this->itembonuses.HealAmt * (spells[spell_id].cast_time + spells[spell_id].recast_time) / 7000;
if(heal_amt > value)
heal_amt = value;
}
if(spells[spell_id].buffduration < 1) {
// Check for buffs that affect the healrate of the target and critical heal rate of target
if(GetTarget()){
value += value * GetHealRate(spell_id) / 100;
chance += GetCriticalHealRate(spell_id);
}
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
//Live AA - Healing Gift, Theft of Life
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
if (spellbonuses.CriticalHealDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
if(chance && (MakeRandomInt(0,99) < chance)) {
Critical = true;
modifier = 2; //At present time no critical heal amount modifier SPA exists.
}
value *= modifier;
value += GetFocusEffect(focusFcHealAmtCrit, spell_id) * modifier;
value += GetFocusEffect(focusFcHealAmt, spell_id);
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier;
if(MakeRandomInt(0,99) < chance) {
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), ((value * modifier / 50) + heal_amt*2));
heal_amt = ((value * modifier / 50) + heal_amt*2);
}
else{
heal_amt = ((value * modifier / 100) + heal_amt);
}
value += value*target->GetHealRate(spell_id, this)/100;
if (Critical)
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), value);
return value;
}
// Hots
//Heal over time spells. [Heal Rate and Additional Healing effects do not increase this value]
else {
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
if(MakeRandomInt(0,99) < chance)
heal_amt = ((value * modifier / 50) + heal_amt*2);
chance = itembonuses.CriticalHealOverTime + spellbonuses.CriticalHealOverTime + aabonuses.CriticalHealOverTime;
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
if (spellbonuses.CriticalRegenDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay);
if(chance && (MakeRandomInt(0,99) < chance))
return (value * 2);
}
heal_amt = (heal_amt * GetHealScale() / 100);
return heal_amt;
return value;
}
int32 Merc::GetActSpellCost(uint16 spell_id, int32 cost)
+1 -3
View File
@@ -77,10 +77,8 @@ public:
Corpse* GetGroupMemberCorpse();
// Merc Spell Casting Methods
int32 Additional_SpellDmg(uint16 spell_id, bool bufftick = false);
int32 Additional_Heal(uint16 spell_id);
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value);
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
virtual int32 GetActSpellCost(uint16 spell_id, int32 cost);
int8 GetChanceToCastBySpellType(int16 spellType);
+50 -117
View File
@@ -385,16 +385,6 @@ Mob::Mob(const char* in_name,
Mob::~Mob()
{
// Our Entity ID is set to 0 in NPC::Death. This leads to mobs hanging around for a while in
// the entity list, even after they have been destroyed. Use our memory pointer to remove the mob
// if our EntityID is 0.
//
/*if(GetID() > 0)
entity_list.RemoveMob(GetID());
else
entity_list.RemoveMob(this);*/
AI_Stop();
if (GetPet()) {
if (GetPet()->Charmed())
@@ -402,8 +392,6 @@ Mob::~Mob()
else
SetPet(0);
}
ClearSpecialAbilities();
EQApplicationPacket app;
CreateDespawnPacket(&app, !IsCorpse());
@@ -3336,7 +3324,7 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id)
int buff_count = GetMaxTotalSlots();
for(int i = 0; i < buff_count; i++)
{
if(IsEffectInSpell(buffs[i].spellid, SE_Twincast))
if(IsEffectInSpell(buffs[i].spellid, SE_FcTwincast))
{
int32 focus = CalcFocusEffect(focusTwincast, buffs[i].spellid, spell_id);
if(focus > 0)
@@ -3378,7 +3366,7 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
int buff_count = GetMaxTotalSlots();
for(int i = 0; i < buff_count; i++) {
if((IsValidSpell(buffs[i].spellid) && IsEffectInSpell(buffs[i].spellid, SE_SpellVulnerability))){
if((IsValidSpell(buffs[i].spellid) && IsEffectInSpell(buffs[i].spellid, SE_FcSpellVulnerability))){
int32 focus = caster->CalcFocusEffect(focusSpellVulnerability, buffs[i].spellid, spell_id);
@@ -3429,37 +3417,19 @@ int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used)
return skilldmg_mod;
}
int16 Mob::GetHealRate(uint16 spell_id)
{
Mob* target = GetTarget();
int16 Mob::GetHealRate(uint16 spell_id, Mob* caster) {
int16 heal_rate = 0;
if (target){
heal_rate = target->itembonuses.HealRate + target->spellbonuses.HealRate;
if (target->IsClient())
heal_rate += target->CastToClient()->GetFocusEffect(focusHealRate, spell_id);
if(heal_rate < -99)
heal_rate = -99;
}
heal_rate += itembonuses.HealRate + spellbonuses.HealRate + aabonuses.HealRate;
heal_rate += GetFocusIncoming(focusFcHealPctIncoming, SE_FcHealPctIncoming, caster, spell_id);
if(heal_rate < -99)
heal_rate = -99;
return heal_rate;
}
int16 Mob::GetCriticalHealRate(uint16 spell_id)
{
Mob* target = GetTarget();
int16 critical_heal_rate = 0;
if (target && target->IsClient())
critical_heal_rate = target->CastToClient()->GetFocusEffect(focusCriticalHealRate, spell_id);
return critical_heal_rate;
}
bool Mob::TryFadeEffect(int slot)
{
if(IsValidSpell(buffs[slot].spellid))
@@ -4669,7 +4639,7 @@ int8 Mob::GetDecayEffectValue(uint16 spell_id, uint16 spelleffect) {
if (!IsValidSpell(spell_id))
return false;
int spell_level = spells[spell_id].classes[(GetClass()%16) - 1];
int spell_level = spells[spell_id].classes[(GetClass()%16) - 1];
int effect_value = 0;
int lvlModifier = 100;
@@ -4679,15 +4649,15 @@ int8 Mob::GetDecayEffectValue(uint16 spell_id, uint16 spelleffect) {
for (int i = 0; i < EFFECT_COUNT; i++){
if(spells[buffs[slot].spellid].effectid[i] == spelleffect) {
int critchance = spells[buffs[slot].spellid].base[i];
int critchance = spells[buffs[slot].spellid].base[i];
int decay = spells[buffs[slot].spellid].base2[i];
int lvldiff = spell_level - spells[buffs[slot].spellid].max[i];
int lvldiff = spell_level - spells[buffs[slot].spellid].max[i];
if(lvldiff > 0 && decay > 0)
{
lvlModifier -= decay*lvldiff;
lvlModifier -= decay*lvldiff;
if (lvlModifier > 0){
critchance = (critchance*lvlModifier)/100;
critchance = (critchance*lvlModifier)/100;
effect_value += critchance;
}
}
@@ -4907,111 +4877,74 @@ bool Mob::HasSpellEffect(int effectid)
}
int Mob::GetSpecialAbility(int ability) {
if (SpecialAbilities.count(ability))
return SpecialAbilities.at(ability).level;
return 0;
}
int Mob::GetSpecialAbilityParam(int ability, int param) {
if(param >= MAX_SPECIAL_ATTACK_PARAMS || param < 0) {
if(ability >= MAX_SPECIAL_ATTACK || ability < 0) {
return 0;
}
auto iter = SpecialAbilities.find(ability);
if(iter != SpecialAbilities.end()) {
return iter->second.params[param];
return SpecialAbilities[ability].level;
}
int Mob::GetSpecialAbilityParam(int ability, int param) {
if(param >= MAX_SPECIAL_ATTACK_PARAMS || param < 0 || ability >= MAX_SPECIAL_ATTACK || ability < 0) {
return 0;
}
return 0;
return SpecialAbilities[ability].params[param];
}
void Mob::SetSpecialAbility(int ability, int level) {
auto iter = SpecialAbilities.find(ability);
if(iter != SpecialAbilities.end()) {
SpecialAbility spec = iter->second;
spec.level = level;
SpecialAbilities[ability] = spec;
} else {
SpecialAbility spec;
memset(&spec, 0, sizeof spec);
spec.level = level;
spec.timer = nullptr;
SpecialAbilities[ability] = spec;
}
}
void Mob::SetSpecialAbilityParam(int ability, int param, int value) {
if(param >= MAX_SPECIAL_ATTACK_PARAMS || param < 0) {
if(ability >= MAX_SPECIAL_ATTACK || ability < 0) {
return;
}
auto iter = SpecialAbilities.find(ability);
if(iter != SpecialAbilities.end()) {
SpecialAbility spec = iter->second;
spec.params[param] = value;
SpecialAbilities[ability] = spec;
} else {
SpecialAbility spec;
memset(&spec, 0, sizeof spec);
spec.params[param] = value;
spec.timer = nullptr;
SpecialAbilities[ability] = spec;
SpecialAbilities[ability].level = level;
}
void Mob::SetSpecialAbilityParam(int ability, int param, int value) {
if(param >= MAX_SPECIAL_ATTACK_PARAMS || param < 0 || ability >= MAX_SPECIAL_ATTACK || ability < 0) {
return;
}
SpecialAbilities[ability].params[param] = value;
}
void Mob::StartSpecialAbilityTimer(int ability, uint32 time) {
auto iter = SpecialAbilities.find(ability);
if(iter != SpecialAbilities.end()) {
SpecialAbility spec = iter->second;
if(spec.timer) {
spec.timer->Start(time);
} else {
spec.timer = new Timer(time);
spec.timer->Start();
}
if (ability >= MAX_SPECIAL_ATTACK || ability < 0) {
return;
}
SpecialAbilities[ability] = spec;
if(SpecialAbilities[ability].timer) {
SpecialAbilities[ability].timer->Start(time);
} else {
SpecialAbility spec;
memset(&spec, 0, sizeof spec);
spec.timer = new Timer(time);
spec.timer->Start();
SpecialAbilities[ability] = spec;
SpecialAbilities[ability].timer = new Timer(time);
SpecialAbilities[ability].timer->Start();
}
}
void Mob::StopSpecialAbilityTimer(int ability) {
auto iter = SpecialAbilities.find(ability);
if(iter != SpecialAbilities.end()) {
SpecialAbility spec = iter->second;
if(spec.timer) {
delete spec.timer;
spec.timer = nullptr;
}
SpecialAbilities[ability] = spec;
if (ability >= MAX_SPECIAL_ATTACK || ability < 0) {
return;
}
safe_delete(SpecialAbilities[ability].timer);
}
Timer *Mob::GetSpecialAbilityTimer(int ability) {
auto iter = SpecialAbilities.find(ability);
if(iter != SpecialAbilities.end()) {
return iter->second.timer;
if (ability >= MAX_SPECIAL_ATTACK || ability < 0) {
return nullptr;
}
return nullptr;
return SpecialAbilities[ability].timer;
}
void Mob::ClearSpecialAbilities() {
auto iter = SpecialAbilities.begin();
while(iter != SpecialAbilities.end()) {
if(iter->second.timer) {
delete iter->second.timer;
for(int a = 0; a < MAX_SPECIAL_ATTACK; ++a) {
SpecialAbilities[a].level = 0;
safe_delete(SpecialAbilities[a].timer);
for(int p = 0; p < MAX_SPECIAL_ATTACK_PARAMS; ++p) {
SpecialAbilities[a].params[p] = 0;
}
++iter;
}
SpecialAbilities.clear();
}
void Mob::ProcessSpecialAbilities(const std::string str) {
+17 -5
View File
@@ -40,6 +40,18 @@ public:
enum eStandingPetOrder { SPO_Follow, SPO_Sit, SPO_Guard };
struct SpecialAbility {
SpecialAbility() {
level = 0;
timer = nullptr;
for(int i = 0; i < MAX_SPECIAL_ATTACK_PARAMS; ++i) {
params[i] = 0;
}
}
~SpecialAbility() {
safe_delete(timer);
}
int level;
Timer *timer;
int params[MAX_SPECIAL_ATTACK_PARAMS];
@@ -172,7 +184,7 @@ public:
void NegateSpellsBonuses(uint16 spell_id);
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false) { return range;}
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr) { return value; }
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value) { return value; }
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr) { return value; }
virtual int32 GetActSpellCost(uint16 spell_id, int32 cost){ return cost;}
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration){ return duration;}
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
@@ -548,10 +560,10 @@ public:
void TrySympatheticProc(Mob *target, uint32 spell_id);
bool TryFadeEffect(int slot);
uint16 GetSpellEffectResistChance(uint16 spell_id);
int16 GetHealRate(uint16 spell_id);
int16 GetCriticalHealRate(uint16 spell_id);
int16 GetHealRate(uint16 spell_id, Mob* caster = nullptr);
int32 GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining);
int32 GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill = false, uint16 skill=0);
int32 GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spell_id);
int16 GetSkillDmgTaken(const SkillUseTypes skill_used);
void DoKnockback(Mob *caster, uint32 pushback, uint32 pushup);
int16 CalcResistChanceBonus();
@@ -574,7 +586,7 @@ public:
bool DoHPToManaCovert(uint16 mana_cost = 0);
int32 ApplySpellEffectiveness(Mob* caster, int16 spell_id, int32 value, bool IsBard = false);
int8 GetDecayEffectValue(uint16 spell_id, uint16 spelleffect);
int32 GetExtraSpellDmg(uint16 spell_id, int32 extra_spell_dmg, int32 base_spell_dmg);
int32 GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg);
void ModSkillDmgTaken(SkillUseTypes skill_num, int value);
int16 GetModSkillDmgTaken(const SkillUseTypes skill_num);
@@ -1177,7 +1189,7 @@ protected:
void InsertQuestGlobal(int charid, int npcid, int zoneid, const char *name, const char *value, int expdate);
uint16 emoteid;
std::map<int, SpecialAbility> SpecialAbilities;
SpecialAbility SpecialAbilities[MAX_SPECIAL_ATTACK];
bool bEnraged;
bool destructibleobject;
-4
View File
@@ -353,7 +353,6 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
NPC::~NPC()
{
//entity_list.RemoveNPC(GetID());
AI_Stop();
if(proximity != nullptr) {
@@ -361,9 +360,6 @@ NPC::~NPC()
safe_delete(proximity);
}
//clear our spawn limit record if we had one.
//entity_list.LimitRemoveNPC(this);
safe_delete(NPCTypedata_ours);
{
+1 -1
View File
@@ -110,7 +110,7 @@ public:
int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
int32 GetActSpellHealing(uint16 spell_id, int32 value);
int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
inline void SetSpellFocusDMG(int32 NewSpellFocusDMG) {SpellFocusDMG = NewSpellFocusDMG;}
inline void SetSpellFocusHeal(int32 NewSpellFocusHeal) {SpellFocusHeal = NewSpellFocusHeal;}
int32 SpellFocusDMG;
+69 -26
View File
@@ -461,11 +461,17 @@ uint32 Raid::GetTotalRaidDamage(Mob* other)
return total;
}
void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid)
void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, int32 range)
{
if (!caster)
return;
if (!range)
range = 200;
float distance;
float range2 = range*range;
int numMem = 0;
unsigned int gi = 0;
for(; gi < MAX_RAID_MEMBERS; gi++)
@@ -473,7 +479,10 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid)
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
numMem += 1;
distance = caster->DistNoRoot(*members[gi].member);
if(distance <= range2){
numMem += 1;
}
}
}
}
@@ -484,25 +493,41 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid)
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
members[gi].member->SetHP(members[gi].member->GetHP() + heal_amt);
members[gi].member->SendHPUpdate();
distance = caster->DistNoRoot(*members[gi].member);
if(distance <= range2){
members[gi].member->SetHP(members[gi].member->GetHP() + heal_amt);
members[gi].member->SendHPUpdate();
}
}
}
}
}
void Raid::BalanceHP(int32 penalty, uint32 gid)
void Raid::BalanceHP(int32 penalty, uint32 gid, int32 range, Mob* caster)
{
if (!caster)
return;
if (!range)
range = 200;
int dmgtaken = 0, numMem = 0;
int gi = 0;
float distance;
float range2 = range*range;
for(; gi < MAX_RAID_MEMBERS; gi++)
{
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
dmgtaken += (members[gi].member->GetMaxHP() - members[gi].member->GetHP());
numMem += 1;
distance = caster->DistNoRoot(*members[gi].member);
if(distance <= range2){
dmgtaken += (members[gi].member->GetMaxHP() - members[gi].member->GetHP());
numMem += 1;
}
}
}
}
@@ -514,21 +539,33 @@ void Raid::BalanceHP(int32 penalty, uint32 gid)
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
if((members[gi].member->GetMaxHP() - dmgtaken) < 1){//this way the ability will never kill someone
members[gi].member->SetHP(1); //but it will come darn close
members[gi].member->SendHPUpdate();
}
else{
members[gi].member->SetHP(members[gi].member->GetMaxHP() - dmgtaken);
members[gi].member->SendHPUpdate();
distance = caster->DistNoRoot(*members[gi].member);
if(distance <= range2){
if((members[gi].member->GetMaxHP() - dmgtaken) < 1){//this way the ability will never kill someone
members[gi].member->SetHP(1); //but it will come darn close
members[gi].member->SendHPUpdate();
}
else{
members[gi].member->SetHP(members[gi].member->GetMaxHP() - dmgtaken);
members[gi].member->SendHPUpdate();
}
}
}
}
}
}
void Raid::BalanceMana(int32 penalty, uint32 gid)
void Raid::BalanceMana(int32 penalty, uint32 gid, int32 range, Mob* caster)
{
if (!caster)
return;
if (!range)
range = 200;
float distance;
float range2 = range*range;
int manataken = 0, numMem = 0;
int gi = 0;
for(; gi < MAX_RAID_MEMBERS; gi++)
@@ -536,8 +573,11 @@ void Raid::BalanceMana(int32 penalty, uint32 gid)
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
manataken += (members[gi].member->GetMaxMana() - members[gi].member->GetMana());
numMem += 1;
distance = caster->DistNoRoot(*members[gi].member);
if(distance <= range2){
manataken += (members[gi].member->GetMaxMana() - members[gi].member->GetMana());
numMem += 1;
}
}
}
}
@@ -549,15 +589,18 @@ void Raid::BalanceMana(int32 penalty, uint32 gid)
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
if((members[gi].member->GetMaxMana() - manataken) < 1){
members[gi].member->SetMana(1);
if (members[gi].member->IsClient())
members[gi].member->CastToClient()->SendManaUpdate();
}
else{
members[gi].member->SetMana(members[gi].member->GetMaxMana() - manataken);
if (members[gi].member->IsClient())
members[gi].member->CastToClient()->SendManaUpdate();
distance = caster->DistNoRoot(*members[gi].member);
if(distance <= range2){
if((members[gi].member->GetMaxMana() - manataken) < 1){
members[gi].member->SetMana(1);
if (members[gi].member->IsClient())
members[gi].member->CastToClient()->SendManaUpdate();
}
else{
members[gi].member->SetMana(members[gi].member->GetMaxMana() - manataken);
if (members[gi].member->IsClient())
members[gi].member->CastToClient()->SendManaUpdate();
}
}
}
}
+3 -3
View File
@@ -147,9 +147,9 @@ public:
void CastGroupSpell(Mob* caster,uint16 spellid, uint32 gid);
void SplitExp(uint32 exp, Mob* other);
uint32 GetTotalRaidDamage(Mob* other);
void BalanceHP(int32 penalty, uint32 gid);
void BalanceMana(int32 penalty, uint32 gid);
void HealGroup(uint32 heal_amt, Mob* caster, uint32 gid);
void BalanceHP(int32 penalty, uint32 gid, int32 range = 0, Mob* caster = nullptr);
void BalanceMana(int32 penalty, uint32 gid, int32 range = 0, Mob* caster = nullptr);
void HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, int32 range = 0);
void SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter = nullptr);
void GroupBardPulse(Mob* caster, uint16 spellid, uint32 gid);
+4 -1
View File
@@ -502,8 +502,11 @@ void Spawn2::SpawnConditionChanged(const SpawnCondition &c, int16 old_value) {
break;
case SpawnCondition::DoRepopIfReady:
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our condition is now %s. Forcing a repop if repsawn timer is expired.", spawn2_id, new_state?"enabled":"disabled");
if(npcthis != nullptr)
if(npcthis != nullptr) {
_log(SPAWNS__CONDITIONS, "Spawn2 %d: Our npcthis is currently not null. The zone thinks it is %s. Forcing a depop.", spawn2_id, npcthis->GetName());
npcthis->Depop(false); //remove the current mob
npcthis = nullptr;
}
if(new_state) { // only get repawn timer remaining when the SpawnCondition is enabled.
timer_remaining = database.GetSpawnTimeLeft(spawn2_id,zone->GetInstanceID());
_log(SPAWNS__CONDITIONS,"Spawn2 %d: Our condition is now %s. The respawn timer_remaining is %d. Forcing a repop if it is <= 0.", spawn2_id, new_state?"enabled":"disabled", timer_remaining);
+410 -476
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2689,7 +2689,7 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2,
effect1 == SE_LimitMinDur ||
effect1 == SE_LimitInstant ||
effect1 == SE_LimitMinLevel ||
effect1 == SE_LimitCastTime)
effect1 == SE_LimitCastTimeMin)
continue;
/*