mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-11 21:22:31 +00:00
[Spells] Implemented SPA 415 SE_FFItemClass (#1688)
* prelim * Spell Focus implemented * AA implemented * Update spdat.h * Update spdat.h * prelim excludes * enum limit expansion * overhaul * v2 testing * updates * working * Fin * Update spell_effects.cpp * Update spell_effects.cpp * var fix * Update spell_effects.cpp make it not apply to casted spells... oops * Update spell_effects.cpp * Update spell_effects.cpp
This commit is contained in:
parent
1cdb1816a2
commit
7f497f9d32
@ -1230,7 +1230,7 @@ bool IsEffectIgnoredInStacking(int spa)
|
|||||||
case SE_LimitClass:
|
case SE_LimitClass:
|
||||||
case SE_LimitRace:
|
case SE_LimitRace:
|
||||||
case SE_FcBaseEffects:
|
case SE_FcBaseEffects:
|
||||||
case 415:
|
case SE_FFItemClass:
|
||||||
case SE_SkillDamageAmount2:
|
case SE_SkillDamageAmount2:
|
||||||
case SE_FcLimitUse:
|
case SE_FcLimitUse:
|
||||||
case SE_FcIncreaseNumHits:
|
case SE_FcIncreaseNumHits:
|
||||||
@ -1298,6 +1298,7 @@ bool IsFocusLimit(int spa)
|
|||||||
case SE_Ff_Value_Min:
|
case SE_Ff_Value_Min:
|
||||||
case SE_Ff_Value_Max:
|
case SE_Ff_Value_Max:
|
||||||
case SE_Ff_FocusTimerMin:
|
case SE_Ff_FocusTimerMin:
|
||||||
|
case SE_FFItemClass:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -177,7 +177,7 @@
|
|||||||
#define EFFECT_COUNT 12
|
#define EFFECT_COUNT 12
|
||||||
#define MAX_SPELL_TRIGGER 12 // One for each slot(only 6 for AA since AA use 2)
|
#define MAX_SPELL_TRIGGER 12 // One for each slot(only 6 for AA since AA use 2)
|
||||||
#define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists.
|
#define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists.
|
||||||
#define MaxLimitInclude 16 //Number(x 0.5) of focus Limiters that have inclusive checks used when calcing focus effects
|
#define MaxLimitInclude 18 //Number(x 0.5) of focus Limiters that have inclusive checks used when calcing focus effects
|
||||||
#define MAX_SKILL_PROCS 4 //Number of spells to check skill procs from. (This is arbitrary) [Single spell can have multiple proc checks]
|
#define MAX_SKILL_PROCS 4 //Number of spells to check skill procs from. (This is arbitrary) [Single spell can have multiple proc checks]
|
||||||
#define MAX_AA_PROCS 16 //(Actual Proc Amount is MAX_AA_PROCS/4) Number of spells to check AA procs from. (This is arbitrary)
|
#define MAX_AA_PROCS 16 //(Actual Proc Amount is MAX_AA_PROCS/4) Number of spells to check AA procs from. (This is arbitrary)
|
||||||
#define MAX_SYMPATHETIC_PROCS 10 // Number of sympathetic procs a client can have (This is arbitrary)
|
#define MAX_SYMPATHETIC_PROCS 10 // Number of sympathetic procs a client can have (This is arbitrary)
|
||||||
@ -206,7 +206,9 @@ enum FocusLimitIncludes {
|
|||||||
IncludeExistsSELimitSpellClass = 12,
|
IncludeExistsSELimitSpellClass = 12,
|
||||||
IncludeFoundSELimitSpellClass = 13,
|
IncludeFoundSELimitSpellClass = 13,
|
||||||
IncludeExistsSELimitSpellSubclass = 14,
|
IncludeExistsSELimitSpellSubclass = 14,
|
||||||
IncludeFoundSELimitSpellSubclass = 15
|
IncludeFoundSELimitSpellSubclass = 15,
|
||||||
|
IncludeExistsSEFFItemClass = 16,
|
||||||
|
IncludeFoundSEFFItemClass = 17
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
The id's correspond to 'type' 39 in live(2021) dbstr_us gives the message for target and caster restricted effects. These are not present in the ROF2 dbstr_us.
|
The id's correspond to 'type' 39 in live(2021) dbstr_us gives the message for target and caster restricted effects. These are not present in the ROF2 dbstr_us.
|
||||||
@ -1115,7 +1117,7 @@ typedef enum {
|
|||||||
#define SE_LimitRace 412 // implemented, @Ff, Race that can use the spell focus, base1: race, Note: not used in any known live spells. Use only single race at a time.
|
#define SE_LimitRace 412 // implemented, @Ff, Race that can use the spell focus, base1: race, Note: not used in any known live spells. Use only single race at a time.
|
||||||
#define SE_FcBaseEffects 413 // implemented, @Fc, On Caster, base spell effectiveness mod pct, base: pct
|
#define SE_FcBaseEffects 413 // implemented, @Fc, On Caster, base spell effectiveness mod pct, base: pct
|
||||||
#define SE_LimitCastingSkill 414 // implemented, @Ff, Spell and singing skills(s) that a spell focus can require or exclude, base1: skill id, Include: Positive Exclude: Negative
|
#define SE_LimitCastingSkill 414 // implemented, @Ff, Spell and singing skills(s) that a spell focus can require or exclude, base1: skill id, Include: Positive Exclude: Negative
|
||||||
//#define SE_FFItemClass 415 // not used - base1 matches ItemType, base2 matches SubType, -1 ignored, max is bitmask of valid slots
|
#define SE_FFItemClass 415 // implemented, @Ff, Limits focuses to be applied only from item click. base1: item ItemType (-1 to include for all ItemTypes,-1000 to exclude clicks from getting the focus, or exclude specific SubTypes or Slots if set), limit: item SubType (-1 for all SubTypes), max: item Slots (bitmask of valid slots, -1 ALL slots), Note: not used on live. See comments in Mob::CalcFocusEffect for more details.
|
||||||
#define SE_ACv2 416 // implemented - New AC spell effect
|
#define SE_ACv2 416 // implemented - New AC spell effect
|
||||||
#define SE_ManaRegen_v2 417 // implemented - New mana regen effect
|
#define SE_ManaRegen_v2 417 // implemented - New mana regen effect
|
||||||
#define SE_SkillDamageAmount2 418 // implemented - adds skill damage directly to certain attacks
|
#define SE_SkillDamageAmount2 418 // implemented - adds skill damage directly to certain attacks
|
||||||
|
|||||||
@ -3266,6 +3266,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
case SE_Buy_AA_Rank:
|
case SE_Buy_AA_Rank:
|
||||||
case SE_Ff_FocusTimerMin:
|
case SE_Ff_FocusTimerMin:
|
||||||
case SE_Proc_Timer_Modifier:
|
case SE_Proc_Timer_Modifier:
|
||||||
|
case SE_FFItemClass:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4548,6 +4549,7 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
|
|||||||
10/11 SE_LimitCastingSkill:
|
10/11 SE_LimitCastingSkill:
|
||||||
12/13 SE_LimitSpellClass:
|
12/13 SE_LimitSpellClass:
|
||||||
14/15 SE_LimitSpellSubClass:
|
14/15 SE_LimitSpellSubClass:
|
||||||
|
16/17 SE_FFItemCLass:
|
||||||
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -4891,6 +4893,59 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_FFItemClass:
|
||||||
|
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);
|
||||||
|
if (item && item->GetItem()) {
|
||||||
|
//If ItemType set to < -1, then we will exclude either all Subtypes (-1000), or specific items by ItemType, SubType or Slot. See above for rules.
|
||||||
|
if (base_value < -1) { //Excludes
|
||||||
|
bool exclude_this_item = true;
|
||||||
|
int tmp_itemtype = (item->GetItem()->ItemType + 100) * -1;
|
||||||
|
//ItemType (if set to -1000, ignore and exclude any ItemType)
|
||||||
|
if (base_value < -1 && base_value != -1000) {
|
||||||
|
if (base_value != tmp_itemtype) {
|
||||||
|
exclude_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//SubType (if set to -1, ignore and exclude all SubTypes)
|
||||||
|
if (limit_value >= 0) {
|
||||||
|
if (limit_value != item->GetItem()->SubType) {
|
||||||
|
exclude_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exclude_this_item) {
|
||||||
|
LimitFailure = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {//Includes
|
||||||
|
LimitInclude[IncludeExistsSEFFItemClass] = true;
|
||||||
|
bool include_this_item = true;
|
||||||
|
//ItemType (if set to -1, ignore and include any ItemType)
|
||||||
|
if (base_value >= 0) {
|
||||||
|
if (base_value != item->GetItem()->ItemType) {
|
||||||
|
include_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//SubType (if set to -1, ignore and include any SubType)
|
||||||
|
if (limit_value >= 0) {
|
||||||
|
if (limit_value != item->GetItem()->SubType) {
|
||||||
|
include_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (include_this_item) {
|
||||||
|
LimitInclude[IncludeFoundSEFFItemClass] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//If this is checking that focus can only be cast from an item, then if its not cast from item fail.
|
||||||
|
else if (base_value >= -1) {
|
||||||
|
LimitFailure = true;
|
||||||
|
}
|
||||||
|
//If we are checking to exclude items from a focus then do not fail unless the above check fails.
|
||||||
|
break;
|
||||||
|
|
||||||
/* These are not applicable to AA's because there is never a 'caster' of the 'buff' with the focus effect.
|
/* These are not applicable to AA's because there is never a 'caster' of the 'buff' with the focus effect.
|
||||||
case SE_Ff_Same_Caster:
|
case SE_Ff_Same_Caster:
|
||||||
@ -5239,6 +5294,7 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
10/11 SE_LimitCastingSkill:
|
10/11 SE_LimitCastingSkill:
|
||||||
12/13 SE_LimitSpellClass:
|
12/13 SE_LimitSpellClass:
|
||||||
14/15 SE_LimitSpellSubClass:
|
14/15 SE_LimitSpellSubClass:
|
||||||
|
16/17 SE_FFItemCLass:
|
||||||
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -5567,6 +5623,96 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_FFItemClass:
|
||||||
|
|
||||||
|
/*
|
||||||
|
Limits focuses to check if cast from item clicks. Can be used to INCLUDE or EXCLUDE items by ItemType and/or SubType and/or Slots
|
||||||
|
Not used on live, going on information we have plus implemented as broadly as possible to allow all possible options.
|
||||||
|
base = item table field 'ItemType' Limit = item table field 'SubType' Max = item table field 'Slots' (this is slot bitmask)
|
||||||
|
|
||||||
|
When including: Setting base, limit, max respectively to -1 will cause it to ignore that check, letting any type or slot ect be used.
|
||||||
|
|
||||||
|
Special rules for excluding. base value needs to be negative < -1, if excluding all ItemTypes set to -1000.
|
||||||
|
For SubType and Slots set using same rules above as for includes. Ie. -1 for all, positive for specifics
|
||||||
|
To exclude a specific ItemType we have to do some math. The exclude value will be the negative value of (ItemType + 100).
|
||||||
|
If ItemType = 10, then SET ItemType= -110 to exclude. If its ItemType 0, then SET ItemType= -100 to exclude ect. Not ideal but it works.
|
||||||
|
|
||||||
|
Usage example: [INCLUDE] Only focus spell if from click cast and is a 'defense armor' item type=10 [base= 10, limit= -1, max= -1]
|
||||||
|
Usage example: [INCLUDE] Only focus spell if from click cast and is from helmet slot' slots= 4 [base= -1, limit= -1, max= 4]
|
||||||
|
Usage example: [EXCLUDE] Do not focus spell if it is from an item click. [base= -1000, limit= -1, max= -1]
|
||||||
|
Usage example: [EXCLUDE] Do not focus spell if it is from an item click from a helmet slot. [base= -1000, limit= -1, max= 4]
|
||||||
|
Usage example: [EXCLUDE] Do not focus spell if it is from an item click and is a 'defense armor' item type=10. [base= -110, limit= -1, max= -1]
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (item && item->GetItem()) {
|
||||||
|
//If ItemType set to < -1, then we will exclude either all Subtypes (-1000), or specific items by ItemType, SubType or Slot. See above for rules.
|
||||||
|
if (focus_spell.base_value[i] < -1) { //Excludes
|
||||||
|
bool exclude_this_item = true;
|
||||||
|
int tmp_itemtype = (item->GetItem()->ItemType + 100) * -1;
|
||||||
|
//ItemType (if set to -1000, ignore and exclude any ItemType)
|
||||||
|
if (focus_spell.base_value[i] < -1 && focus_spell.base_value[i] != -1000) {
|
||||||
|
if (focus_spell.base_value[i] != tmp_itemtype) {
|
||||||
|
exclude_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//SubType (if set to -1, ignore and exclude all SubTypes)
|
||||||
|
if (focus_spell.limit_value[i] >= 0) {
|
||||||
|
if (focus_spell.limit_value[i] != item->GetItem()->SubType) {
|
||||||
|
exclude_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//item slot bitmask (if set to -1, ignore and exclude all SubTypes)
|
||||||
|
if (focus_spell.max_value[i] >= 0) {
|
||||||
|
if (focus_spell.max_value[i] != item->GetItem()->Slots) {
|
||||||
|
exclude_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exclude_this_item) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {//Includes
|
||||||
|
LimitInclude[IncludeExistsSEFFItemClass] = true;
|
||||||
|
bool include_this_item = true;
|
||||||
|
//ItemType (if set to -1, ignore and include any ItemType)
|
||||||
|
if (focus_spell.base_value[i] >= 0) {
|
||||||
|
if (focus_spell.base_value[i] != item->GetItem()->ItemType) {
|
||||||
|
include_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//SubType (if set to -1, ignore and include any SubType)
|
||||||
|
if (focus_spell.limit_value[i] >= 0) {
|
||||||
|
if (focus_spell.limit_value[i] != item->GetItem()->SubType) {
|
||||||
|
include_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//item slot bitmask (if set to -1, ignore and include any slot)
|
||||||
|
if (focus_spell.max_value[i] >= 0) {
|
||||||
|
if (focus_spell.max_value[i] != item->GetItem()->Slots) {
|
||||||
|
include_this_item = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (include_this_item) {
|
||||||
|
LimitInclude[IncludeFoundSEFFItemClass] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//If this is checking that focus can only be cast from an item, then if its not cast from item fail.
|
||||||
|
else if (focus_spell.base_value[i] >= -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//If we are checking to exclude items from a focus then do not fail unless the above check fails.
|
||||||
|
break;
|
||||||
|
|
||||||
// handle effects
|
// handle effects
|
||||||
case SE_ImprovedDamage:
|
case SE_ImprovedDamage:
|
||||||
if (type == focusImprovedDamage) {
|
if (type == focusImprovedDamage) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user