[Spells] Allow item click effects to have cast time and recast time modified by focus effects. (#1695)

* prelim

* Spell Focus implemented

* AA implemented

* Update spdat.h

* Update spdat.h

* working

* Update spells.cpp

* prelim excludes

* enum limit expansion

* overhaul

* v2 testing

* updates

* working

* Fin

* Update spell_effects.cpp

* Update spell_effects.cpp

* update

* Update spells.cpp

* fix

* fix

* Update spell_effects.cpp

* remove debugs

* Update spells.cpp
This commit is contained in:
KayenEQ 2021-11-10 21:23:49 -05:00 committed by GitHub
parent 990729fe21
commit d9c8e80bca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 23 deletions

View File

@ -4546,6 +4546,14 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
int index_id = -1;
uint32 focus_reuse_time = 0;
bool is_from_item_click = false;
bool try_apply_to_item_click = false;
bool has_item_limit_check = false;
if (casting_spell_inventory_slot && casting_spell_inventory_slot != -1) {
is_from_item_click = true;
}
bool LimitFailure = false;
bool LimitInclude[MaxLimitInclude] = {false};
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice
@ -4903,6 +4911,7 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
break;
case SE_FFItemClass:
has_item_limit_check = true;
if (casting_spell_inventory_slot && casting_spell_inventory_slot != -1) {
if (IsClient() && casting_spell_slot == EQ::spells::CastingSlot::Item && casting_spell_inventory_slot != 0xFFFFFFFF) {
auto item = CastToClient()->GetInv().GetItem(casting_spell_inventory_slot);
@ -4995,18 +5004,21 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
case SE_IncreaseSpellHaste:
if (type == focusSpellHaste && base_value > value) {
value = base_value;
try_apply_to_item_click = is_from_item_click ? true : false;
}
break;
case SE_Fc_CastTimeMod2:
if (type == focusFcCastTimeMod2 && base_value > value) {
value = base_value;
try_apply_to_item_click = is_from_item_click ? true : false;
}
break;
case SE_Fc_CastTimeAmt:
if (type == focusFcCastTimeAmt && base_value > value) {
value = base_value;
try_apply_to_item_click = is_from_item_click ? true : false;
}
break;
@ -5081,6 +5093,7 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
case SE_ReduceReuseTimer:
if (type == focusReduceRecastTime) {
value = base_value / 1000;
try_apply_to_item_click = is_from_item_click ? true : false;
}
break;
@ -5247,6 +5260,10 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
}
}
if (try_apply_to_item_click && !has_item_limit_check) {
return 0;
}
if (LimitFailure) {
return 0;
}
@ -5291,6 +5308,14 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
int index_id = -1;
uint32 focus_reuse_time = 0; //If this is set and all limits pass, start timer at end of script.
bool is_from_item_click = false;
bool try_apply_to_item_click = false;
bool has_item_limit_check = false;
if (casting_spell_inventory_slot && casting_spell_inventory_slot != -1) {
is_from_item_click = true;
}
bool LimitInclude[MaxLimitInclude] = {false};
/* Certain limits require only one of several Include conditions to be true. Determined by limits being negative or positive
Ie. Add damage to fire OR ice spells. If positive we 'Include', by checking each limit of same type to look for match until found. Opposed to
@ -5655,7 +5680,7 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
Note: You can apply multiple includes or excludes to a single focus spell, using multiple SPA 415 limits in the spell. Ie. Check for clicks from ItemType 10 or 11.
*/
has_item_limit_check = true;
if (casting_spell_inventory_slot && casting_spell_inventory_slot != -1) {
if (IsClient() && casting_spell_slot == EQ::spells::CastingSlot::Item && casting_spell_inventory_slot != 0xFFFFFFFF) {
auto item = CastToClient()->GetInv().GetItem(casting_spell_inventory_slot);
@ -5756,18 +5781,21 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
case SE_IncreaseSpellHaste:
if (type == focusSpellHaste && focus_spell.base_value[i] > value) {
value = focus_spell.base_value[i];
try_apply_to_item_click = is_from_item_click ? true : false;
}
break;
case SE_Fc_CastTimeMod2:
if (type == focusFcCastTimeMod2 && focus_spell.base_value[i] > value) {
value = focus_spell.base_value[i];
try_apply_to_item_click = is_from_item_click ? true : false;
}
break;
case SE_Fc_CastTimeAmt:
if (type == focusFcCastTimeAmt && focus_spell.base_value[i] > value) {
value = focus_spell.base_value[i];
try_apply_to_item_click = is_from_item_click ? true : false;
}
break;
@ -5828,6 +5856,7 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
case SE_ReduceReuseTimer:
if (type == focusReduceRecastTime) {
value = focus_spell.base_value[i] / 1000;
try_apply_to_item_click = is_from_item_click ? true : false;
}
break;
@ -6012,6 +6041,15 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
}
}
/*
For item click cast/recast focus modifiers. Only use if SPA 415 exists.
This is an item click but does not have SPA 415 limiter. Fail here.
*/
if (try_apply_to_item_click && !has_item_limit_check) {
return 0;
}
if (Caston_spell_id) {
if (IsValidSpell(Caston_spell_id) && (Caston_spell_id != spell_id)) {
SpellFinished(

View File

@ -425,6 +425,13 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
cast_time = GetActSpellCasttime(spell_id, cast_time);
}
}
//must use SPA 415 with focus (SPA 127/500/501) to reduce item recast
else if (cast_time && IsClient() && slot == CastingSlot::Item && item_slot != 0xFFFFFFFF) {
orgcasttime = cast_time;
if (cast_time) {
cast_time = GetActSpellCasttime(spell_id, cast_time);
}
}
else
orgcasttime = cast_time;
@ -2543,6 +2550,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
recast -= GetAA(aaTouchoftheWicked) * 420;
}
int reduction = CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id);//Client only
if(reduction)
recast -= reduction;
@ -2556,7 +2564,17 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
EQ::ItemInstance *itm = CastToClient()->GetInv().GetItem(inventory_slot);
if(itm && itm->GetItem()->RecastDelay > 0){
auto recast_type = itm->GetItem()->RecastType;
CastToClient()->GetPTimers().Start((pTimerItemStart + recast_type), itm->GetItem()->RecastDelay);
int recast_delay = itm->GetItem()->RecastDelay;
//must use SPA 415 with focus (SPA 310) to reduce item recast
int reduction = CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id);
if (reduction) {
recast_delay -= reduction;
}
recast_delay = std::max(recast_delay, 0);
if (recast_delay > 0) {
CastToClient()->GetPTimers().Start((pTimerItemStart + recast_type), recast_delay);
if (recast_type != -1) {
database.UpdateItemRecastTimestamps(
CastToClient()->CharacterID(),
@ -2564,14 +2582,16 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
CastToClient()->GetPTimers().Get(pTimerItemStart + recast_type)->GetReadyTimestamp()
);
}
auto outapp = new EQApplicationPacket(OP_ItemRecastDelay, sizeof(ItemRecastDelay_Struct));
ItemRecastDelay_Struct *ird = (ItemRecastDelay_Struct *)outapp->pBuffer;
ird->recast_delay = itm->GetItem()->RecastDelay;
ird->recast_delay = static_cast<uint32>(recast_delay);
ird->recast_type = recast_type;
CastToClient()->QueuePacket(outapp);
safe_delete(outapp);
}
}
}
if(IsNPC())
CastToNPC()->AI_Event_SpellCastFinished(true, static_cast<uint16>(slot));