mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-27 16:11:29 +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_LimitRace:
|
||||
case SE_FcBaseEffects:
|
||||
case 415:
|
||||
case SE_FFItemClass:
|
||||
case SE_SkillDamageAmount2:
|
||||
case SE_FcLimitUse:
|
||||
case SE_FcIncreaseNumHits:
|
||||
@ -1298,6 +1298,7 @@ bool IsFocusLimit(int spa)
|
||||
case SE_Ff_Value_Min:
|
||||
case SE_Ff_Value_Max:
|
||||
case SE_Ff_FocusTimerMin:
|
||||
case SE_FFItemClass:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@ -177,7 +177,7 @@
|
||||
#define EFFECT_COUNT 12
|
||||
#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 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_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)
|
||||
@ -206,7 +206,9 @@ enum FocusLimitIncludes {
|
||||
IncludeExistsSELimitSpellClass = 12,
|
||||
IncludeFoundSELimitSpellClass = 13,
|
||||
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.
|
||||
@ -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_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_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_ManaRegen_v2 417 // implemented - New mana regen effect
|
||||
#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_Ff_FocusTimerMin:
|
||||
case SE_Proc_Timer_Modifier:
|
||||
case SE_FFItemClass:
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -4548,6 +4549,7 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
|
||||
10/11 SE_LimitCastingSkill:
|
||||
12/13 SE_LimitSpellClass:
|
||||
14/15 SE_LimitSpellSubClass:
|
||||
16/17 SE_FFItemCLass:
|
||||
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;
|
||||
|
||||
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.
|
||||
case SE_Ff_Same_Caster:
|
||||
@ -5239,13 +5294,14 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
||||
10/11 SE_LimitCastingSkill:
|
||||
12/13 SE_LimitSpellClass:
|
||||
14/15 SE_LimitSpellSubClass:
|
||||
16/17 SE_FFItemCLass:
|
||||
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
||||
*/
|
||||
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
|
||||
switch (focus_spell.effect_id[i]) {
|
||||
|
||||
|
||||
case SE_Blank:
|
||||
break;
|
||||
|
||||
@ -5567,6 +5623,96 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
||||
}
|
||||
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
|
||||
case SE_ImprovedDamage:
|
||||
if (type == focusImprovedDamage) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user