mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-03 23:03:51 +00:00
[API] Apply spells with custom buff durations and adjust existing spell buff durations. (#1997)
* working * Update spell_effects.cpp * updates * disable_buff_overwrite * revert * update * working * update * updates * Update spells.cpp * getbuffstat done * Update perl_mob.cpp * [API] Apply spells with custom buff durations and adjust existing spell buff durations. * [API] Apply spells with custom buff durations and adjust existing spell buff durations. * [API] Apply spells with custom buff durations and adjust existing spell buff durations. * [API] Apply spells with custom buff durations and adjust existing spell buff durations. * https://github.com/EQEmu/Server/pull/1997 Lua added, thanks kinglykrab
This commit is contained in:
parent
5fd62d82db
commit
615f4a5304
@ -1264,8 +1264,9 @@ typedef enum {
|
||||
// LAST
|
||||
|
||||
|
||||
#define DF_Permanent 50
|
||||
#define DF_Aura 51
|
||||
#define DF_Permanent 50
|
||||
#define DF_Aura 51
|
||||
#define PERMANENT_BUFF_DURATION -1000 //this is arbitrary used when overriding spells regular buff duration to set it as permenant
|
||||
|
||||
// note this struct is historical, we don't actually need it to be
|
||||
// aligned to anything, but for maintaining it it is kept in the order that
|
||||
|
||||
@ -2448,6 +2448,36 @@ void Lua_Mob::SetSeeInvisibleUndeadLevel(uint8 invisible_level)
|
||||
self->SetSeeInvisibleUndead(invisible_level);
|
||||
}
|
||||
|
||||
void Lua_Mob::ApplySpellBuff(int spell_id) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ApplySpellBuff(spell_id, 0);
|
||||
}
|
||||
|
||||
void Lua_Mob::ApplySpellBuff(int spell_id, int duration) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ApplySpellBuff(spell_id, duration);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetBuffStatValueBySlot(uint8 slot, const char* identifier) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetBuffStatValueBySlot(slot, identifier);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetBuffStatValueBySpell(int spell_id, const char* identifier) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetBuffStatValueBySpell(spell_id, identifier);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetBuffDuration(int spell_id) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBuffDuration(spell_id, 0);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetBuffDuration(int spell_id, int duration) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBuffDuration(spell_id, duration);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_mob() {
|
||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||
.def(luabind::constructor<>())
|
||||
@ -2458,6 +2488,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("AddToHateList", (void(Lua_Mob::*)(Lua_Mob,int,int,bool))&Lua_Mob::AddToHateList)
|
||||
.def("AddToHateList", (void(Lua_Mob::*)(Lua_Mob,int,int,bool,bool))&Lua_Mob::AddToHateList)
|
||||
.def("AddToHateList", (void(Lua_Mob::*)(Lua_Mob,int,int,bool,bool,bool))&Lua_Mob::AddToHateList)
|
||||
.def("ApplySpellBuff", (void(Lua_Mob::*)(int))&Lua_Mob::ApplySpellBuff)
|
||||
.def("ApplySpellBuff", (void(Lua_Mob::*)(int, int))&Lua_Mob::ApplySpellBuff)
|
||||
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::Attack)
|
||||
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int))&Lua_Mob::Attack)
|
||||
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool))&Lua_Mob::Attack)
|
||||
@ -2595,6 +2627,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetBucketKey", (std::string(Lua_Mob::*)(void))&Lua_Mob::GetBucketKey)
|
||||
.def("GetBucketRemaining", (std::string(Lua_Mob::*)(std::string))&Lua_Mob::GetBucketRemaining)
|
||||
.def("GetBuffSlotFromType", &Lua_Mob::GetBuffSlotFromType)
|
||||
.def("GetBuffStatValueBySlot", (void(Lua_Mob::*)(uint8, const char*))& Lua_Mob::GetBuffStatValueBySlot)
|
||||
.def("GetBuffStatValueBySpell", (void(Lua_Mob::*)(int, const char*))&Lua_Mob::GetBuffStatValueBySpell)
|
||||
.def("GetCHA", &Lua_Mob::GetCHA)
|
||||
.def("GetCR", &Lua_Mob::GetCR)
|
||||
.def("GetCasterLevel", &Lua_Mob::GetCasterLevel)
|
||||
@ -2810,6 +2844,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("SetBodyType", (void(Lua_Mob::*)(int,bool))&Lua_Mob::SetBodyType)
|
||||
.def("SetBucket", (void(Lua_Mob::*)(std::string,std::string))&Lua_Mob::SetBucket)
|
||||
.def("SetBucket", (void(Lua_Mob::*)(std::string,std::string,std::string))&Lua_Mob::SetBucket)
|
||||
.def("SetBuffDuration", (void(Lua_Mob::*)(int))&Lua_Mob::SetBuffDuration)
|
||||
.def("SetBuffDuration", (void(Lua_Mob::*)(int, int))&Lua_Mob::SetBuffDuration)
|
||||
.def("SetCurrentWP", &Lua_Mob::SetCurrentWP)
|
||||
.def("SetDestructibleObject", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDestructibleObject)
|
||||
.def("SetDisableMelee", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDisableMelee)
|
||||
|
||||
@ -457,6 +457,12 @@ public:
|
||||
bool IsHorse();
|
||||
bool CanClassEquipItem(uint32 item_id);
|
||||
bool CanRaceEquipItem(uint32 item_id);
|
||||
void ApplySpellBuff(int spell_id);
|
||||
void ApplySpellBuff(int spell_id, int duration);
|
||||
int GetBuffStatValueBySlot(uint8 slot, const char* identifier);
|
||||
int GetBuffStatValueBySpell(int spell_id, const char* identifier);
|
||||
void SetBuffDuration(int spell_id);
|
||||
void SetBuffDuration(int spell_id, int duration);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
10
zone/mob.h
10
zone/mob.h
@ -349,8 +349,8 @@ public:
|
||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, bool from_casted_spell = false, uint32 aa_id = 0);
|
||||
void SendBeginCast(uint16 spell_id, uint32 casttime);
|
||||
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, int reflect_effectiveness = 0,
|
||||
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, int32 duration_override = 0);
|
||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1, int reflect_effectiveness = 0, int32 duration_override = 0);
|
||||
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, int32 duration_override = 0, bool disable_buff_overrwrite = false);
|
||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1, int reflect_effectiveness = 0, int32 duration_override = 0, bool disable_buff_overrwrite = false);
|
||||
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center,
|
||||
CastAction_type &CastAction, EQ::spells::CastingSlot slot, bool isproc = false);
|
||||
bool DoCastingChecksOnCaster(int32 spell_id);
|
||||
@ -406,7 +406,7 @@ public:
|
||||
bool IsAffectedByBuff(uint16 spell_id);
|
||||
bool IsAffectedByBuffByGlobalGroup(GlobalGroup group);
|
||||
void BuffModifyDurationBySpellID(uint16 spell_id, int32 newDuration);
|
||||
int AddBuff(Mob *caster, const uint16 spell_id, int duration = 0, int32 level_override = -1);
|
||||
int AddBuff(Mob *caster, const uint16 spell_id, int duration = 0, int32 level_override = -1, bool disable_buff_overrwrite = false);
|
||||
int CanBuffStack(uint16 spellid, uint8 caster_level, bool iFailIfOverwrite = false);
|
||||
int CalcBuffDuration(Mob *caster, Mob *target, uint16 spell_id, int32 caster_level_override = -1);
|
||||
void SendPetBuffsToClient();
|
||||
@ -461,6 +461,10 @@ public:
|
||||
void GetAppearenceEffects();
|
||||
void ClearAppearenceEffects();
|
||||
void SendSavedAppearenceEffects(Client *receiver);
|
||||
void SetBuffDuration(int32 spell_id, int32 duration);
|
||||
void ApplySpellBuff(int32 spell_id, int32 duration);
|
||||
int GetBuffStatValueBySpell(int32 spell_id, const char* stat_identifier);
|
||||
int GetBuffStatValueBySlot(uint8 slot, const char* stat_identifier);
|
||||
|
||||
//Basic Stats/Inventory
|
||||
virtual void SetLevel(uint8 in_level, bool command = false) { level = in_level; }
|
||||
|
||||
@ -5662,6 +5662,46 @@ XS(XS_Mob_GetSpellStat) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_GetBuffStatValueBySpell); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetBuffStatValueBySpell) {
|
||||
dXSARGS;
|
||||
if (items != 3)
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetBuffStatValueBySpell(THIS, int32 spell_id, string stat)"); // @categories Spells and Disciplines
|
||||
{
|
||||
Mob *THIS;
|
||||
int32 RETVAL;
|
||||
int32 spellid = (int32)SvIV(ST(1));
|
||||
Const_char *stat = (Const_char *)SvPV_nolen(ST(2));
|
||||
dXSTARG;
|
||||
VALIDATE_THIS_IS_MOB;
|
||||
|
||||
RETVAL = THIS->GetBuffStatValueBySpell(spellid, stat);
|
||||
XSprePUSH;
|
||||
PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_GetBuffStatValueBySlot); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetBuffStatValueBySlot) {
|
||||
dXSARGS;
|
||||
if (items != 3)
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetBuffStatValueBySlot(THIS, uint8 slot, string stat)"); // @categories Script Utility, Spells and Disciplines
|
||||
{
|
||||
Mob *THIS;
|
||||
int32 RETVAL;
|
||||
uint8 slot = (uint8)SvUV(ST(1));
|
||||
Const_char *stat = (Const_char *)SvPV_nolen(ST(2));
|
||||
dXSTARG;
|
||||
VALIDATE_THIS_IS_MOB;
|
||||
|
||||
RETVAL = THIS->GetBuffStatValueBySlot(slot, stat);
|
||||
XSprePUSH;
|
||||
PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_GetSpecialAbility); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetSpecialAbility) {
|
||||
dXSARGS;
|
||||
@ -6567,6 +6607,46 @@ XS(XS_Mob_GetHateRandomNPC) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_SetBuffDuration); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_SetBuffDuration) {
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 3)
|
||||
Perl_croak(aTHX_ "Usage: Mob::SetBuffDuration(THIS, spell_id, [int duration = 0])"); // @categories Script Utility, Spells and Disciplines
|
||||
{
|
||||
Mob *THIS;
|
||||
int spell_id = (int)SvIV(ST(1));
|
||||
int duration = 0;
|
||||
VALIDATE_THIS_IS_MOB;
|
||||
|
||||
if (items == 3) {
|
||||
duration = (int)SvIV(ST(2));
|
||||
}
|
||||
|
||||
THIS->SetBuffDuration(spell_id, duration);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Mob_ApplySpellBuff); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_ApplySpellBuff) {
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 3)
|
||||
Perl_croak(aTHX_ "Usage: Mob::ApplySpellBuff(THIS, spell_id, [int duration = 0])"); // @categories Script Utility, Spells and Disciplines
|
||||
{
|
||||
Mob *THIS;
|
||||
int spell_id = (int)SvIV(ST(1));
|
||||
int duration = 0;
|
||||
VALIDATE_THIS_IS_MOB;
|
||||
|
||||
if (items == 3) {
|
||||
duration = (int)SvIV(ST(2));
|
||||
}
|
||||
|
||||
THIS->ApplySpellBuff(spell_id, duration);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
XS(XS_Mob_CastToBot); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_CastToBot)
|
||||
@ -6622,6 +6702,7 @@ XS(boot_Mob) {
|
||||
newXSproto(strcpy(buf, "AddFeignMemory"), XS_Mob_AddFeignMemory, file, "$$");
|
||||
newXSproto(strcpy(buf, "AddNimbusEffect"), XS_Mob_AddNimbusEffect, file, "$$");
|
||||
newXSproto(strcpy(buf, "AddToHateList"), XS_Mob_AddToHateList, file, "$$;$$$$$");
|
||||
newXSproto(strcpy(buf, "ApplySpellBuff"), XS_Mob_ApplySpellBuff, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "Attack"), XS_Mob_Attack, file, "$$;$$");
|
||||
newXSproto(strcpy(buf, "BehindMob"), XS_Mob_BehindMob, file, "$;$$$");
|
||||
newXSproto(strcpy(buf, "BuffCount"), XS_Mob_BuffCount, file, "$");
|
||||
@ -6712,6 +6793,8 @@ XS(boot_Mob) {
|
||||
newXSproto(strcpy(buf, "GetBucketKey"), XS_Mob_GetBucketKey, file, "$");
|
||||
newXSproto(strcpy(buf, "GetBucketRemaining"), XS_Mob_GetBucketRemaining, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetBuffSlotFromType"), XS_Mob_GetBuffSlotFromType, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetBuffStatValueBySpell"), XS_Mob_GetBuffStatValueBySpell, file, "$$$");
|
||||
newXSproto(strcpy(buf, "GetBuffStatValueBySlot"), XS_Mob_GetBuffStatValueBySlot, file, "$$$");
|
||||
newXSproto(strcpy(buf, "GetCHA"), XS_Mob_GetCHA, file, "$");
|
||||
newXSproto(strcpy(buf, "GetCR"), XS_Mob_GetCR, file, "$");
|
||||
newXSproto(strcpy(buf, "GetCasterLevel"), XS_Mob_GetCasterLevel, file, "$$");
|
||||
@ -6917,6 +7000,7 @@ XS(boot_Mob) {
|
||||
newXSproto(strcpy(buf, "SetAppearance"), XS_Mob_SetAppearance, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "SetBodyType"), XS_Mob_SetBodyType, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "SetBucket"), XS_Mob_SetBucket, file, "$$$;$");
|
||||
newXSproto(strcpy(buf, "SetBuffDuration"), XS_Mob_SetBuffDuration, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "SetCurrentWP"), XS_Mob_SetCurrentWP, file, "$$");
|
||||
newXSproto(strcpy(buf, "SetDeltas"), XS_Mob_SetDeltas, file, "$$$$$");
|
||||
newXSproto(strcpy(buf, "SetDisableMelee"), XS_Mob_SetDisableMelee, file, "$$");
|
||||
|
||||
@ -46,7 +46,7 @@ extern WorldServer worldserver;
|
||||
|
||||
// the spell can still fail here, if the buff can't stack
|
||||
// in this case false will be returned, true otherwise
|
||||
bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_override, int reflect_effectiveness, int32 duration_override)
|
||||
bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_override, int reflect_effectiveness, int32 duration_override, bool disable_buff_overrwrite)
|
||||
{
|
||||
int caster_level, buffslot, effect, effect_value, i;
|
||||
EQ::ItemInstance *SummonedItem=nullptr;
|
||||
@ -119,7 +119,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
}
|
||||
else
|
||||
{
|
||||
buffslot = AddBuff(caster, spell_id, duration_override);
|
||||
buffslot = AddBuff(caster, spell_id, duration_override, -1, disable_buff_overrwrite);
|
||||
}
|
||||
if(buffslot == -1) // stacking failure
|
||||
return false;
|
||||
@ -3662,7 +3662,8 @@ void Mob::BuffProcess()
|
||||
|
||||
// DF_Permanent uses -1 DF_Aura uses -4 but we need to check negatives for some spells for some reason?
|
||||
if (spells[buffs[buffs_i].spellid].buff_duration_formula != DF_Permanent &&
|
||||
spells[buffs[buffs_i].spellid].buff_duration_formula != DF_Aura) {
|
||||
spells[buffs[buffs_i].spellid].buff_duration_formula != DF_Aura &&
|
||||
buffs[buffs_i].ticsremaining != PERMANENT_BUFF_DURATION) {
|
||||
if(!zone->BuffTimersSuspended() || !IsSuspendableSpell(buffs[buffs_i].spellid))
|
||||
{
|
||||
--buffs[buffs_i].ticsremaining;
|
||||
@ -10204,3 +10205,116 @@ bool Mob::HasPersistDeathIllusion(int32 spell_id) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Mob::SetBuffDuration(int32 spell_id, int32 duration) {
|
||||
|
||||
/*
|
||||
Will refresh the buff with specified spell_id to the specified duration
|
||||
If spell is -1, then all spells will be set to the specified duration
|
||||
If duration 0, then will set duration to buffs normal max duration.
|
||||
*/
|
||||
|
||||
bool adjust_all_buffs = false;
|
||||
|
||||
if (spell_id == -1) {
|
||||
adjust_all_buffs = true;
|
||||
}
|
||||
|
||||
if (!adjust_all_buffs && !IsValidSpell(spell_id)){
|
||||
return;
|
||||
}
|
||||
|
||||
if (duration < -1) {
|
||||
duration = PERMANENT_BUFF_DURATION;
|
||||
}
|
||||
|
||||
int buff_count = GetMaxBuffSlots();
|
||||
for (int slot = 0; slot < buff_count; slot++) {
|
||||
|
||||
if (!adjust_all_buffs) {
|
||||
if (buffs[slot].spellid != SPELL_UNKNOWN && buffs[slot].spellid == spell_id) {
|
||||
SpellOnTarget(buffs[slot].spellid, this, 0, false, 0, false, -1, duration, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (buffs[slot].spellid != SPELL_UNKNOWN) {
|
||||
SpellOnTarget(buffs[slot].spellid, this, 0, false, 0, false, -1, duration, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::ApplySpellBuff(int32 spell_id, int32 duration)
|
||||
{
|
||||
/*
|
||||
Used for quest command to apply a new buff with custom duration.
|
||||
Duration set to 0 will apply with normal duration.
|
||||
*/
|
||||
if (!IsValidSpell(spell_id)) {
|
||||
return;
|
||||
}
|
||||
if (!spells[spell_id].buff_duration) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (duration < -1) {
|
||||
duration = PERMANENT_BUFF_DURATION;
|
||||
}
|
||||
|
||||
SpellOnTarget(spell_id, this, 0, false, 0, false, -1, duration);
|
||||
}
|
||||
|
||||
int Mob::GetBuffStatValueBySpell(int32 spell_id, const char* stat_identifier)
|
||||
{
|
||||
if (!IsValidSpell(spell_id)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!stat_identifier) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string id = str_tolower(stat_identifier);
|
||||
|
||||
int buff_count = GetMaxBuffSlots();
|
||||
for (int slot = 0; slot < buff_count; slot++) {
|
||||
if (buffs[slot].spellid != SPELL_UNKNOWN && buffs[slot].spellid == spell_id) {
|
||||
return GetBuffStatValueBySlot(slot, stat_identifier);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Mob::GetBuffStatValueBySlot(uint8 slot, const char* stat_identifier)
|
||||
{
|
||||
if (slot > GetMaxBuffSlots()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!stat_identifier) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string id = str_tolower(stat_identifier);
|
||||
|
||||
if (id == "caster_level") { return buffs[slot].casterlevel; }
|
||||
else if (id == "spell_id") { return buffs[slot].spellid; }
|
||||
else if (id == "caster_id") { return buffs[slot].spellid;; }
|
||||
else if (id == "ticsremaining") { return buffs[slot].ticsremaining; }
|
||||
else if (id == "counters") { return buffs[slot].counters; }
|
||||
else if (id == "hit_number") { return buffs[slot].hit_number; }
|
||||
else if (id == "melee_rune") { return buffs[slot].melee_rune; }
|
||||
else if (id == "magic_rune") { return buffs[slot].magic_rune; }
|
||||
else if (id == "dot_rune") { return buffs[slot].dot_rune; }
|
||||
else if (id == "caston_x") { return buffs[slot].caston_x; }
|
||||
else if (id == "caston_y") { return buffs[slot].caston_y; }
|
||||
else if (id == "caston_z") { return buffs[slot].caston_z; }
|
||||
else if (id == "instrument_mod") { return buffs[slot].instrument_mod; }
|
||||
else if (id == "persistant_buff") { return buffs[slot].persistant_buff; }
|
||||
else if (id == "client") { return buffs[slot].client; }
|
||||
else if (id == "extra_di_chance") { return buffs[slot].ExtraDIChance; }
|
||||
else if (id == "root_break_chance") { return buffs[slot].RootBreakChance; }
|
||||
else if (id == "virus_spread_time") { return buffs[slot].virus_spread_time; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3200,9 +3200,8 @@ bool Mob::HasDiscBuff()
|
||||
// stacking problems, and -2 if this is not a buff
|
||||
// if caster is null, the buff will be added with the caster level being
|
||||
// the level of the mob
|
||||
int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_override)
|
||||
int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_override, bool disable_buff_overrwrite)
|
||||
{
|
||||
|
||||
int buffslot, ret, caster_level, emptyslot = -1;
|
||||
bool will_overwrite = false;
|
||||
std::vector<int> overwrite_slots;
|
||||
@ -3223,7 +3222,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
|
||||
LogSpells("Buff [{}] failed to add because its duration came back as 0", spell_id);
|
||||
return -2; // no duration? this isn't a buff
|
||||
}
|
||||
|
||||
|
||||
LogSpells("Trying to add buff [{}] cast by [{}] (cast level [{}]) with duration [{}]",
|
||||
spell_id, caster?caster->GetName():"UNKNOWN", caster_level, duration);
|
||||
|
||||
@ -3297,7 +3296,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
|
||||
|
||||
// at this point we know that this buff will stick, but we have
|
||||
// to remove some other buffs already worn if will_overwrite is true
|
||||
if (will_overwrite) {
|
||||
if (will_overwrite && !disable_buff_overrwrite) {
|
||||
std::vector<int>::iterator cur, end;
|
||||
cur = overwrite_slots.begin();
|
||||
end = overwrite_slots.end();
|
||||
@ -3314,9 +3313,6 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
|
||||
}
|
||||
}
|
||||
|
||||
// now add buff at emptyslot
|
||||
assert(buffs[emptyslot].spellid == SPELL_UNKNOWN); // sanity check
|
||||
|
||||
buffs[emptyslot].spellid = spell_id;
|
||||
buffs[emptyslot].casterlevel = caster_level;
|
||||
if (caster && !caster->IsAura()) // maybe some other things we don't want to ...
|
||||
@ -3446,7 +3442,7 @@ int Mob::CanBuffStack(uint16 spellid, uint8 caster_level, bool iFailIfOverwrite)
|
||||
// break stuff
|
||||
//
|
||||
bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectiveness, bool use_resist_adjust, int16 resist_adjust,
|
||||
bool isproc, int level_override, int32 duration_override)
|
||||
bool isproc, int level_override, int32 duration_override, bool disable_buff_overrwrite)
|
||||
{
|
||||
// well we can't cast a spell on target without a target
|
||||
if(!spelltar)
|
||||
@ -3994,7 +3990,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes
|
||||
}
|
||||
|
||||
// cause the effects to the target
|
||||
if(!spelltar->SpellEffect(this, spell_id, spell_effectiveness, level_override, reflect_effectiveness, duration_override))
|
||||
if(!spelltar->SpellEffect(this, spell_id, spell_effectiveness, level_override, reflect_effectiveness, duration_override, disable_buff_overrwrite))
|
||||
{
|
||||
// if SpellEffect returned false there's a problem applying the
|
||||
// spell. It's most likely a buff that can't stack.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user