diff --git a/db/constants.conf b/db/constants.conf index deef0317557..eb16c1bbf56 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -1307,6 +1307,10 @@ constants_db: { SC_SOULDIVISION: 716 SC_ACTIVE_MONSTER_TRANSFORM: 717 + SC_TAROTCARD_ATK_PERC: 719 + SC_TAROTCARD_MATK_PERC: 720 + SC_TAROTCARD_DEF_PERC: 721 + SC_GOSPEL_ATK_PERC: 722 comment__: "Emotes" e_gasp: 0 diff --git a/db/pre-re/sc_config.conf b/db/pre-re/sc_config.conf index 2589e6aa587..d0a3d39bda9 100644 --- a/db/pre-re/sc_config.conf +++ b/db/pre-re/sc_config.conf @@ -80,6 +80,10 @@ SC_TYPE: { Range: (bool, defaults to false) Regen: (bool, defaults to false) Dye: (bool, defaults to false) + AtkPerc: (bool, defaults to false) + DefPerc: (bool, defaults to false) + MatkPerc: (bool, defaults to false) + MdefPerc: (bool, defaults to false) All: (bool, defaults to false) } Icon: (string, defaults to SI_BLANK) The status icon attached to the SC @@ -92,10 +96,8 @@ SC_PROVOKE: { NoBoss: true } CalcFlags: { - Batk: true - Watk: true - Def: true - Def2: true + AtkPerc: true + DefPerc: true } Icon: "SI_PROVOKE" Skill: "SM_PROVOKE" @@ -198,7 +200,7 @@ SC_ANGELUS: { Buff: true } CalcFlags: { - Def2: true + DefPerc: true } Icon: "SI_ANGELUS" Skill: "AL_ANGELUS" @@ -459,7 +461,7 @@ SC_NOEQUIPWEAPON: { Buff: true } CalcFlags: { - Watk: true + AtkPerc: true } Icon: "SI_NOEQUIPWEAPON" Skill: "RG_STRIPWEAPON" @@ -473,7 +475,7 @@ SC_NOEQUIPSHIELD: { Buff: true } CalcFlags: { - Def: true + DefPerc: true } Icon: "SI_NOEQUIPSHIELD" Skill: "RG_STRIPSHIELD" @@ -756,11 +758,9 @@ SC_LKCONCENTRATION: { Buff: true } CalcFlags: { - Batk: true - Watk: true Hit: true - Def: true - Def2: true + AtkPerc: true + DefPerc: true } Icon: "SI_LKCONCENTRATION" Skill: "LK_CONCENTRATION" @@ -980,8 +980,8 @@ SC_JOINTBEAT: { Debuff: true } CalcFlags: { - Batk: true - Def2: true + AtkPerc: true + DefPerc: true Speed: true Aspd: true } @@ -994,8 +994,8 @@ SC_MINDBREAKER: { Buff: true } CalcFlags: { - Matk: true - Mdef2: true + MatkPerc: true + MdefPerc: true } Skill: "PF_MINDBREAKER" } @@ -5389,7 +5389,7 @@ SC_MIRACLE: { } SC_POISON: { CalcFlags: { - Def2: true + DefPerc: true Regen: true } Icon: "SI_CLOUDKILL" @@ -5532,10 +5532,8 @@ SC_ALMIGHTY: { } SC_SKE: { CalcFlags: { - Batk: true - Watk: true - Def: true - Def2: true + AtkPerc: true + DefPerc: true } Icon: "SI_SKE" Skill: "SL_SKE" @@ -5568,8 +5566,7 @@ SC_SLEEP: { SC_CURSE: { CalcFlags: { Luk: true - Batk: true - Watk: true + AtkPerc: true Speed: true } Skill: "NPC_CURSEATTACK" @@ -5586,7 +5583,7 @@ SC_BLIND: { } SC_DPOISON: { CalcFlags: { - Def2: true + DefPerc: true Regen: true } Skill: "NPC_POISON" @@ -5723,8 +5720,7 @@ SC_KNOWLEDGE: { } SC_FLING: { CalcFlags: { - Def: true - Def2: true + DefPerc: true } Skill: "GS_FLING" } @@ -5743,15 +5739,13 @@ SC_HLIF_CHANGE: { } SC_HAMI_BLOODLUST: { CalcFlags: { - Batk: true - Watk: true + AtkPerc: true } Skill: "HAMI_BLOODLUST" } SC_HLIF_FLEET: { CalcFlags: { - Batk: true - Watk: true + AtkPerc: true Aspd: true } Skill: "HFLI_FLEET" @@ -5902,8 +5896,7 @@ SC_INCMSPRATE: { } SC_INCATKRATE: { CalcFlags: { - Batk: true - Watk: true + AtkPerc: true } } SC_INCMATKRATE: { @@ -6408,3 +6401,42 @@ SC_ACTIVE_MONSTER_TRANSFORM: { SC__FEINTBOMB_MASTER: { Skill: "SC_FEINTBOMB" } +SC_TAROTCARD_ATK_PERC: { + Flags: { + NoSave: true + NoClearanceReset: true + Debuff: true + } + CalcFlags: { + AtkPerc: true + } +} +SC_TAROTCARD_MATK_PERC: { + Flags: { + NoSave: true + NoClearanceReset: true + Debuff: true + } + CalcFlags: { + MatkPerc: true + } +} +SC_TAROTCARD_DEF_PERC: { + Flags: { + NoSave: true + NoClearanceReset: true + Debuff: true + } + CalcFlags: { + DefPerc: true + } +} +SC_GOSPEL_ATK_PERC: { + Flags: { + NoSave: true + Debuff: true + } + CalcFlags: { + AtkPerc: true + } +} diff --git a/db/re/sc_config.conf b/db/re/sc_config.conf index b2254b8c9ff..2f760d38fc2 100644 --- a/db/re/sc_config.conf +++ b/db/re/sc_config.conf @@ -80,6 +80,10 @@ SC_TYPE: { Range: (bool, defaults to false) Regen: (bool, defaults to false) Dye: (bool, defaults to false) + AtkPerc: (bool, defaults to false) + DefPerc: (bool, defaults to false) + MatkPerc: (bool, defaults to false) + MdefPerc: (bool, defaults to false) All: (bool, defaults to false) } Icon: (string, defaults to SI_BLANK) The status icon attached to the SC @@ -92,10 +96,8 @@ SC_PROVOKE: { NoBoss: true } CalcFlags: { - Batk: true - Watk: true - Def: true - Def2: true + AtkPerc: true + DefPerc: true } Icon: "SI_PROVOKE" Skill: "SM_PROVOKE" @@ -460,7 +462,7 @@ SC_NOEQUIPWEAPON: { Buff: true } CalcFlags: { - Watk: true + AtkPerc: true } Icon: "SI_NOEQUIPWEAPON" Skill: "RG_STRIPWEAPON" @@ -474,7 +476,7 @@ SC_NOEQUIPSHIELD: { Buff: true } CalcFlags: { - Def: true + DefPerc: true } Icon: "SI_NOEQUIPSHIELD" Skill: "RG_STRIPSHIELD" @@ -760,7 +762,8 @@ SC_LKCONCENTRATION: { } CalcFlags: { Hit: true - Def: true + AtkPerc: true + DefPerc: true } Icon: "SI_LKCONCENTRATION" Skill: "LK_CONCENTRATION" @@ -981,8 +984,8 @@ SC_JOINTBEAT: { Debuff: true } CalcFlags: { - Batk: true - Def2: true + AtkPerc: true + DefPerc: true Speed: true Aspd: true } @@ -995,8 +998,8 @@ SC_MINDBREAKER: { Buff: true } CalcFlags: { - Matk: true - Mdef2: true + MatkPerc: true + MdefPerc: true } Skill: "PF_MINDBREAKER" } @@ -5389,7 +5392,7 @@ SC_MIRACLE: { } SC_POISON: { CalcFlags: { - Def2: true + DefPerc: true Regen: true } Icon: "SI_CLOUDKILL" @@ -5532,10 +5535,8 @@ SC_ALMIGHTY: { } SC_SKE: { CalcFlags: { - Batk: true - Watk: true - Def: true - Def2: true + AtkPerc: true + DefPerc: true } Icon: "SI_SKE" Skill: "SL_SKE" @@ -5568,8 +5569,7 @@ SC_SLEEP: { SC_CURSE: { CalcFlags: { Luk: true - Batk: true - Watk: true + AtkPerc: true Speed: true } Skill: "NPC_CURSEATTACK" @@ -5586,7 +5586,7 @@ SC_BLIND: { } SC_DPOISON: { CalcFlags: { - Def2: true + DefPerc: true Regen: true } Skill: "NPC_POISON" @@ -5723,8 +5723,7 @@ SC_KNOWLEDGE: { } SC_FLING: { CalcFlags: { - Def: true - Def2: true + DefPerc: true } Skill: "GS_FLING" } @@ -5743,15 +5742,13 @@ SC_HLIF_CHANGE: { } SC_HAMI_BLOODLUST: { CalcFlags: { - Batk: true - Watk: true + AtkPerc: true } Skill: "HAMI_BLOODLUST" } SC_HLIF_FLEET: { CalcFlags: { - Batk: true - Watk: true + AtkPerc: true Aspd: true } Skill: "HFLI_FLEET" @@ -5902,8 +5899,7 @@ SC_INCMSPRATE: { } SC_INCATKRATE: { CalcFlags: { - Batk: true - Watk: true + AtkPerc: true } } SC_INCMATKRATE: { @@ -6410,3 +6406,42 @@ SC_ACTIVE_MONSTER_TRANSFORM: { SC__FEINTBOMB_MASTER: { Skill: "SC_FEINTBOMB" } +SC_TAROTCARD_ATK_PERC: { + Flags: { + NoSave: true + NoClearanceReset: true + Debuff: true + } + CalcFlags: { + AtkPerc: true + } +} +SC_TAROTCARD_MATK_PERC: { + Flags: { + NoSave: true + NoClearanceReset: true + Debuff: true + } + CalcFlags: { + MatkPerc: true + } +} +SC_TAROTCARD_DEF_PERC: { + Flags: { + NoSave: true + NoClearanceReset: true + Debuff: true + } + CalcFlags: { + DefPerc: true + } +} +SC_GOSPEL_ATK_PERC: { + Flags: { + NoSave: true + Debuff: true + } + CalcFlags: { + AtkPerc: true + } +} diff --git a/src/map/battle.c b/src/map/battle.c index 7758e242a76..38da0f50a39 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1489,6 +1489,7 @@ static int64 battle_calc_defense(int attack_type, struct block_list *src, struct #else vit_def = def2; #endif + vit_def = (vit_def * tstatus->def_percent) / 100; if((battle->check_undead(sstatus->race,sstatus->def_ele) || sstatus->race==RC_DEMON) && //This bonus already doesn't work vs players src->type == BL_MOB && (i=pc->checkskill(tsd,AL_DP)) > 0) vit_def += i*(int)(3 +(tsd->status.base_level+1)*0.04); // [orn] @@ -1504,6 +1505,8 @@ static int64 battle_calc_defense(int attack_type, struct block_list *src, struct #else vit_def = def2; #endif + vit_def = (vit_def * tstatus->def_percent) / 100; + def1 = (def1 * tstatus->def_percent) / 100; } if (battle_config.weapon_defense_type) { @@ -4012,6 +4015,10 @@ static struct Damage battle_calc_magic_attack(struct block_list *src, struct blo default: MATK_RATE(battle->calc_skillratio(BF_MAGIC, src, target, skill_id, skill_lv, skillratio, mflag)); } + + // Aegis: It seems like most percentual matk bonuses, besides matk_percent, are used additively. + MATK_RATE(sstatus->matk_percent); + //Constant/misc additions from skills if (skill_id == WZ_FIREPILLAR) MATK_ADD(100+50*skill_lv); @@ -5303,6 +5310,20 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id)); } + bool skip_atk_rate_bonus; + switch (skill_id) { + case MO_EXTREMITYFIST: + skip_atk_rate_bonus = true; + break; + default: + skip_atk_rate_bonus = false; + break; + } + + if (skip_atk_rate_bonus) + break; + + int temp_atk_rate = sstatus->atk_percent; //Add any bonuses that modify the base baseatk+watk (pre-skills) if(sd) { #ifndef RENEWAL @@ -5314,13 +5335,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl if(flag.cri && sc && sc->data[SC_MTF_CRIDAMAGE]) ATK_ADDRATE(sc->data[SC_MTF_CRIDAMAGE]->val1);// temporary it should be 'bonus.crit_atk_rate' #ifndef RENEWAL - if(sd->status.party_id && (temp=pc->checkskill(sd,TK_POWER)) > 0){ if ((i = party->foreachsamemap(party->sub_count, sd, 0, sd->status.char_id)) > 0) - ATK_ADDRATE(2*temp*i); + temp_atk_rate += 2 * temp * i; } #endif } + ATK_RATE(temp_atk_rate); break; } //End default case } //End switch(skill_id) diff --git a/src/map/pc.h b/src/map/pc.h index 25ca09daf97..b842717fc43 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -791,10 +791,13 @@ END_ZEROED_BLOCK; #define pc_leftside_matk(sd) (status->base_matk(&(sd)->bl, status->get_status_data(&(sd)->bl), (sd)->status.base_level)) #define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->battle_status.lhw.matk+(sd)->bonus.ematk) #else - #define pc_leftside_atk(sd) ((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk) + #define pc_leftside_atk(sd) (\ + (((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk)\ + * (sd)->battle_status.atk_percent) / 100\ + ) #define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2) #define pc_leftside_def(sd) ((sd)->battle_status.def) - #define pc_rightside_def(sd) ((sd)->battle_status.def2) + #define pc_rightside_def(sd) (((sd)->battle_status.def2 * (sd)->battle_status.def_percent) / 100) #define pc_leftside_mdef(sd) ((sd)->battle_status.mdef) #define pc_rightside_mdef(sd) ( (sd)->battle_status.mdef2 - ((sd)->battle_status.vit>>1) ) #define pc_leftside_matk(sd) (\ diff --git a/src/map/skill.c b/src/map/skill.c index 62cd169ea2c..4ae67eff72f 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -9355,7 +9355,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * status_percent_damage(src, bl, 0, 100, false); break; case 1: // matk halved - sc_start(src, bl, SC_INCMATKRATE, 100, -50, skill->get_time2(skill_id, skill_lv), skill_id); + sc_start(src, bl, SC_TAROTCARD_MATK_PERC, 100, -50, skill->get_time2(skill_id, skill_lv), skill_id); break; case 2: // all buffs removed status->change_clear_buffs(bl,1); @@ -9371,7 +9371,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * } break; case 4: // atk halved - sc_start(src, bl, SC_INCATKRATE, 100, -50, skill->get_time2(skill_id, skill_lv), skill_id); + sc_start(src, bl, SC_TAROTCARD_ATK_PERC, 100, -50, skill->get_time2(skill_id, skill_lv), skill_id); break; case 5: // 2000HP heal, random teleported status->heal(src, 2000, 0, STATUS_HEAL_DEFAULT); @@ -9401,8 +9401,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * case 10: // 6666 damage, atk matk halved, cursed status_fix_damage(src, bl, 6666, 0); clif->damage(src,bl,0,0,6666,0,BDT_NORMAL,0); - sc_start(src, bl, SC_INCATKRATE, 100, -50, skill->get_time2(skill_id, skill_lv), skill_id); - sc_start(src, bl, SC_INCMATKRATE, 100, -50, skill->get_time2(skill_id, skill_lv), skill_id); + sc_start(src, bl, SC_TAROTCARD_ATK_PERC, 100, -50, skill->get_time2(skill_id, skill_lv), skill_id); + sc_start(src, bl, SC_TAROTCARD_MATK_PERC, 100, -50, skill->get_time2(skill_id, skill_lv), skill_id); sc_start(src, bl, SC_CURSE, skill_lv, 100, skill->get_time2(skill_id, skill_lv), skill_id); break; case 11: // 4444 damage @@ -9413,11 +9413,11 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * sc_start(src, bl, SC_STUN, 100, skill_lv, 5000, skill_id); break; case 13: // atk,matk,hit,flee,def reduced - sc_start(src, bl, SC_INCATKRATE, 100, -20, skill->get_time2(skill_id, skill_lv), skill_id); - sc_start(src, bl, SC_INCMATKRATE, 100, -20, skill->get_time2(skill_id, skill_lv), skill_id); + sc_start(src, bl, SC_TAROTCARD_ATK_PERC, 100, -20, skill->get_time2(skill_id, skill_lv), skill_id); + sc_start(src, bl, SC_TAROTCARD_MATK_PERC, 100, -20, skill->get_time2(skill_id, skill_lv), skill_id); sc_start(src, bl, SC_INCHITRATE, 100, -20, skill->get_time2(skill_id, skill_lv), skill_id); sc_start(src, bl, SC_INCFLEERATE, 100, -20, skill->get_time2(skill_id, skill_lv), skill_id); - sc_start(src, bl, SC_INCDEFRATE, 100, -20, skill->get_time2(skill_id, skill_lv), skill_id); + sc_start(src, bl, SC_TAROTCARD_DEF_PERC, 100, -20, skill->get_time2(skill_id, skill_lv), skill_id); sc_start(src, bl, type, 100, skill_lv, skill->get_time2(skill_id, skill_lv), skill_id); break; default: @@ -14341,7 +14341,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b if (tsd) clif->gospel_info(tsd, 0x1e); break; case 11: // ATK +100% - sc_start(ss, bl, SC_INCATKRATE, 100, 100, time, skill_id); + sc_start(ss, bl, SC_GOSPEL_ATK_PERC, 100, 100, time, skill_id); if (tsd) clif->gospel_info(tsd, 0x1f); break; case 12: // HIT/Flee +50 @@ -14370,13 +14370,16 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b sc_start(ss, bl, SC_POISON, 100, 1, time, skill_id); break; case 4: // Level 10 Provoke + // TODO: [Aegis] while this does apply the status effect of provoke, it manually sets the atk / def percentage changes... + // this means you could be affected by gospel provoke as well as normal provoke, since provoke also manually applies the atk / def changes in Aegis. + // We're not doing that here. sc_start(ss, bl, SC_PROVOKE, 100, 10, time, skill_id); break; case 5: // DEF -100% sc_start(ss, bl, SC_INCDEFRATE, 100, -100, time, skill_id); break; case 6: // ATK -100% - sc_start(ss, bl, SC_INCATKRATE, 100, -100, time, skill_id); + sc_start(ss, bl, SC_GOSPEL_ATK_PERC, 100, -100, time, skill_id); break; case 7: // Flee -100% sc_start(ss, bl, SC_INCFLEERATE, 100, -100, time, skill_id); diff --git a/src/map/status.c b/src/map/status.c index a0bf120c7b3..34b9d72c410 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -87,9 +87,9 @@ static int status_sc2skill(sc_type sc) /** * Returns the status calculation flag associated with a given status change. * @param sc The status to look up - * @return The scb_flag registered for this status (see enum scb_flag) + * @return The scb_flag registered for this status (see e_scb_flag) */ -static unsigned int status_sc2scb_flag(sc_type sc) +static e_scb_flag status_sc2scb_flag(sc_type sc) { if( sc < 0 || sc >= SC_MAX ) { ShowError("status_sc2scb_flag: Unsupported status change id %d\n", sc); @@ -2987,8 +2987,8 @@ static void status_calc_regen_rate(struct block_list *bl, struct regen_data *reg #define status_get_homluk(st, hd) ((st)->luk + (hd)->homunculus.luk_value) /// Recalculates parts of an object's battle status according to the specified flags. -/// @param flag bitfield of values from enum scb_flag -static void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) +/// @param flag bitfield of values from e_scb_flag +static void status_calc_bl_main(struct block_list *bl, e_scb_flag flag) { const struct status_data *bst = status->get_base_status(bl); struct status_data *st = status->get_status_data(bl); @@ -3079,6 +3079,28 @@ static void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag ; } + if ((flag & SCB_ATK_PERC) != 0) { + int prev_atk_percent = st->atk_percent; + st->atk_percent = status->calc_atk_percent(bl, sc); + if (prev_atk_percent != st->atk_percent) + clif->updatestatus(sd, SP_ATK1); + } + + if ((flag & SCB_MATK_PERC) != 0) + st->matk_percent = status->calc_matk_percent(bl, sc); + + if ((flag & SCB_DEF_PERC) != 0) { + int prev_def_percent = st->def_percent; + st->def_percent = status->calc_def_percent(bl, sc); + if (prev_def_percent != st->def_percent) + clif->updatestatus(sd, SP_DEF2); + } + + if ((flag & SCB_MDEF_PERC) != 0) { + st->mdef_percent = status->calc_mdef_percent(bl, sc); + flag |= SCB_MDEF; + } + if(flag&SCB_BATK && bst->batk) { st->batk = status->base_atk(bl,st); temp = bst->batk - status->base_atk(bl,bst); @@ -3388,9 +3410,9 @@ static void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag /// Recalculates parts of an object's base status and battle status according to the specified flags. /// Also sends updates to the client wherever applicable. -/// @param flag bitfield of values from enum scb_flag +/// @param flag bitfield of values from e_scb_flag /// @param first if true, will cause status_calc_* functions to run their base status initialization code -static void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt) +static void status_calc_bl_(struct block_list *bl, e_scb_flag flag, enum e_status_calc_opt opt) { struct status_data bst; // previous battle status struct status_data *st; // pointer to current battle status @@ -3471,7 +3493,7 @@ static void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_st if(bst.batk != st->batk #ifndef RENEWAL - || bst.rhw.atk != st->rhw.atk || bst.lhw.atk != st->lhw.atk + || bst.rhw.atk != st->rhw.atk || bst.lhw.atk != st->lhw.atk || bst.atk_percent != st->atk_percent #endif ) clif->updatestatus(sd,SP_ATK1); @@ -4292,6 +4314,160 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang return (unsigned short)cap_value(luk, 0, USHRT_MAX); } +/** + * Adds up the granted ATK percent bonuses. + * + * @param bl the object who's ATK percent we're calculating. + * @param sc the status change data of our object. + * @return the calculated ATK percent. + */ +static int status_calc_atk_percent(struct block_list *bl, struct status_change *sc) +{ + nullpo_ret(bl); + int atk_percent = 100; // [Aegis] by default we have 100% of our atk. + + if (sc == NULL || sc->count == 0) + return cap_value(atk_percent, 0, USHRT_MAX); + + // Add/Subtract additively according to status changes. + if (sc->data[SC_TAROTCARD_ATK_PERC] != NULL) + atk_percent += sc->data[SC_TAROTCARD_ATK_PERC]->val1; + + if (sc->data[SC_GOSPEL_ATK_PERC] != NULL) + atk_percent += sc->data[SC_GOSPEL_ATK_PERC]->val1; + + if (sc->data[SC_PROVOKE] != NULL) + atk_percent += sc->data[SC_PROVOKE]->val3; + + if (sc->data[SC_LKCONCENTRATION] != NULL) + atk_percent += sc->data[SC_LKCONCENTRATION]->val2; + + if (sc->data[SC_HAMI_BLOODLUST] != NULL) + atk_percent += sc->data[SC_HAMI_BLOODLUST]->val2; + + if (sc->data[SC_JOINTBEAT] != NULL && (sc->data[SC_JOINTBEAT]->val2 & BREAK_WAIST) != 0) + atk_percent -= 25; + + if (sc->data[SC_SKE] != NULL) + atk_percent += 300; + + if (sc->data[SC_HLIF_FLEET] != NULL) + atk_percent += sc->data[SC_HLIF_FLEET]->val3; + + if (sc->data[SC_CURSE] != NULL) + atk_percent -= 25; + + if (sc->data[SC_INCATKRATE] != NULL) // should be used by NPC_POWERUP only + atk_percent += sc->data[SC_INCATKRATE]->val1; + + if (sc->data[SC_NOEQUIPWEAPON] != NULL && bl->type != BL_PC) + atk_percent -= sc->data[SC_NOEQUIPWEAPON]->val2; + + return cap_value(atk_percent, 0, USHRT_MAX); +} + +/** + * Adds up the granted MATK percent bonuses. + * + * @param bl the object who's MATK percent we're calculating. + * @param sc the status change data of our object. + * @return the calculated MATK percent. + */ +static int status_calc_matk_percent(struct block_list *bl, struct status_change *sc) +{ + nullpo_ret(bl); + int matk_percent = 100; // [Aegis] by default we have 100% of our matk. + + if (sc == NULL || sc->count == 0) + return cap_value(matk_percent, 0, USHRT_MAX); + + // Add/Subtract additively according to status changes. + if (sc->data[SC_TAROTCARD_MATK_PERC] != NULL) + matk_percent += sc->data[SC_TAROTCARD_MATK_PERC]->val1; + + if (sc->data[SC_MINDBREAKER] != NULL) + matk_percent += sc->data[SC_MINDBREAKER]->val2; + + return cap_value(matk_percent, 0, USHRT_MAX); +} + +/** + * Adds up the granted DEF percent bonuses. + * + * @param bl the object who's DEF percent we're calculating. + * @param sc the status change data of our object. + * @return the calculated DEF percent. + */ +static int status_calc_def_percent(struct block_list *bl, struct status_change *sc) +{ + nullpo_ret(bl); + int def_percent = 100; // [Aegis] by default we have 100% of our def. + + if (sc == NULL || sc->count == 0) + return cap_value(def_percent, 0, USHRT_MAX); + + // Add/Subtract additively according to status changes. + if (sc->data[SC_TAROTCARD_DEF_PERC] != NULL) + def_percent += sc->data[SC_TAROTCARD_DEF_PERC]->val1; + + if (sc->data[SC_PROVOKE] != NULL) + def_percent -= sc->data[SC_PROVOKE]->val4; // passed as absolute value. + + if (sc->data[SC_LKCONCENTRATION] != NULL) + def_percent -= sc->data[SC_LKCONCENTRATION]->val4; // passed as absolute value. + + if (sc->data[SC_JOINTBEAT]) { + // [Aegis] General (m)atk/m(def) percentage buffs/debuffs take the stronger one, as in max(abs(fst_perc), abs(snd_perc)). + // This is done individually for def, mdef, atk, def. And compared is only with same-skill originating changes. + if ((sc->data[SC_JOINTBEAT]->val2 & BREAK_SHOULDER) != 0) + def_percent -= 50; + else if ((sc->data[SC_JOINTBEAT]->val2 & BREAK_WAIST) != 0) + def_percent -= 25; + } + + if (sc->data[SC_SKE] != NULL) + def_percent -= 50; + + if (sc->data[SC_NOEQUIPSHIELD] != NULL) + def_percent -= sc->data[SC_NOEQUIPSHIELD]->val2; + + if (sc->data[SC_FLING] != NULL) + def_percent -= sc->data[SC_FLING]->val2; + +#ifndef RENEWAL + if (sc->data[SC_ANGELUS] != NULL) + def_percent += sc->data[SC_ANGELUS]->val2; +#endif + + // [Aegis] These can't stack. + if (sc->data[SC_POISON] != NULL || sc->data[SC_DPOISON] != NULL) + def_percent -= 25; + + return cap_value(def_percent, 0, USHRT_MAX); +} + +/** + * Adds up the granted MDEF percent bonuses. + * + * @param bl the object who's MDEF percent we're calculating. + * @param sc the status change data of our object. + * @return the calculated MDEF percent. + */ +static int status_calc_mdef_percent(struct block_list *bl, struct status_change *sc) +{ + nullpo_ret(bl); + int mdef_percent = 100; // [Aegis] by default we have 100% of our mdef. + + if (sc == NULL || sc->count == 0) + return cap_value(mdef_percent, 0, USHRT_MAX); + + // Add/Subtract additively according to status changes. + if (sc->data[SC_MINDBREAKER] != NULL) + mdef_percent -= sc->data[SC_MINDBREAKER]->val3; + + return cap_value(mdef_percent, 0, USHRT_MAX); +} + static int status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable) { nullpo_ret(bl); @@ -4338,30 +4514,12 @@ static int status_calc_batk(struct block_list *bl, struct status_change *sc, int if (sc->data[SC_ANGRIFFS_MODUS]) batk += sc->data[SC_ANGRIFFS_MODUS]->val2; - if(sc->data[SC_INCATKRATE]) - batk += batk * sc->data[SC_INCATKRATE]->val1/100; - if(sc->data[SC_PROVOKE]) - batk += batk * sc->data[SC_PROVOKE]->val3/100; -#ifndef RENEWAL - if(sc->data[SC_LKCONCENTRATION]) - batk += batk * sc->data[SC_LKCONCENTRATION]->val2/100; -#endif - if(sc->data[SC_SKE]) - batk += batk * 3; - if(sc->data[SC_HAMI_BLOODLUST]) - batk += batk * sc->data[SC_HAMI_BLOODLUST]->val2/100; - if(sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST) - batk -= batk * 25/100; - if(sc->data[SC_CURSE]) - batk -= batk * 25/100; if( sc->data[SC_ZANGETSU] ) batk += sc->data[SC_ZANGETSU]->val2; #if 0 //Curse shouldn't effect on this? <- Curse OR Bleeding?? if(sc->data[SC_BLOODING]) batk -= batk * 25/100; #endif // 0 - if(sc->data[SC_HLIF_FLEET]) - batk += batk * sc->data[SC_HLIF_FLEET]->val3/100; if(sc->data[SC__ENERVATION]) batk -= batk * sc->data[SC__ENERVATION]->val2 / 100; if(sc->data[SC_SATURDAY_NIGHT_FEVER]) @@ -4450,21 +4608,7 @@ static int status_calc_watk(struct block_list *bl, struct status_change *sc, int watk += sc->data[SC_NIBELUNGEN]->val2; } } - if(sc->data[SC_LKCONCENTRATION]) - watk += watk * sc->data[SC_LKCONCENTRATION]->val2/100; #endif - if(sc->data[SC_INCATKRATE]) - watk += watk * sc->data[SC_INCATKRATE]->val1/100; - if(sc->data[SC_PROVOKE]) - watk += watk * sc->data[SC_PROVOKE]->val3/100; - if(sc->data[SC_SKE]) - watk += watk * 3; - if(sc->data[SC_HLIF_FLEET]) - watk += watk * sc->data[SC_HLIF_FLEET]->val3/100; - if(sc->data[SC_CURSE]) - watk -= watk * 25/100; - if(sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC) - watk -= watk * sc->data[SC_NOEQUIPWEAPON]->val2/100; if(sc->data[SC__ENERVATION]) watk -= watk * sc->data[SC__ENERVATION]->val2 / 100; if(sc->data[SC_RUSH_WINDMILL]) @@ -4535,8 +4679,6 @@ static int status_calc_matk(struct block_list *bl, struct status_change *sc, int if (!viewable) { /* some statuses that are hidden in the status window */ - if (sc->data[SC_MINDBREAKER]) - matk += matk * sc->data[SC_MINDBREAKER]->val2 / 100; if (sc->data[SC_POPECOOKIE] != NULL) matk += matk * sc->data[SC_POPECOOKIE]->val2 / 100; if (sc->data[SC_VITALIZE_POTION] != NULL) @@ -4569,7 +4711,7 @@ static int status_calc_matk(struct block_list *bl, struct status_change *sc, int matk += sc->data[SC_ZANGETSU]->val3; if (sc->data[SC_MAGICPOWER] && sc->data[SC_MAGICPOWER]->val4) matk += matk * sc->data[SC_MAGICPOWER]->val3 / 100; - if (sc->data[SC_INCMATKRATE]) + if (sc->data[SC_INCMATKRATE]) // Apparently nothing in Hercules uses this. Why does this exist? matk += matk * sc->data[SC_INCMATKRATE]->val1 / 100; if (sc->data[SC_MOONLIT_SERENADE]) matk += matk * sc->data[SC_MOONLIT_SERENADE]->val2 / 100; @@ -4891,16 +5033,6 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc, def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1; if (sc->data[SC_CRUCIS]) def -= def * sc->data[SC_CRUCIS]->val2/100; - if (sc->data[SC_LKCONCENTRATION]) - def -= def * sc->data[SC_LKCONCENTRATION]->val4/100; - if (sc->data[SC_SKE]) - def >>=1; - if (sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense-> - def -= def * sc->data[SC_PROVOKE]->val4/100; - if (sc->data[SC_NOEQUIPSHIELD]) - def -= def * sc->data[SC_NOEQUIPSHIELD]->val2/100; - if (sc->data[SC_FLING]) - def -= def * (sc->data[SC_FLING]->val2)/100; if (sc->data[SC_ANALYZE]) def -= def * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100; if (sc->data[SC_SATURDAY_NIGHT_FEVER]) @@ -4973,27 +5105,10 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change def2 += sc->data[SC_SUN_COMFORT]->val2; if (sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 1) def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2); - if (sc->data[SC_ANGELUS]) #ifdef RENEWAL //in renewal only the VIT stat bonus is boosted by angelus + if (sc->data[SC_ANGELUS]) def2 += status_get_vit(bl) / 2 * sc->data[SC_ANGELUS]->val2/100; -#else - def2 += def2 * sc->data[SC_ANGELUS]->val2/100; - if (sc->data[SC_LKCONCENTRATION]) - def2 -= def2 * sc->data[SC_LKCONCENTRATION]->val4/100; #endif - if (sc->data[SC_POISON]) - def2 -= def2 * 25/100; - if (sc->data[SC_DPOISON]) - def2 -= def2 * 25/100; - if (sc->data[SC_SKE]) - def2 -= def2 * 50/100; - if (sc->data[SC_PROVOKE]) - def2 -= def2 * sc->data[SC_PROVOKE]->val4/100; - if (sc->data[SC_JOINTBEAT]) - def2 -= def2 * ((sc->data[SC_JOINTBEAT]->val2&BREAK_SHOULDER) ? 50 : 0) / 100 - + def2 * ((sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST) ? 25 : 0) / 100; - if (sc->data[SC_FLING]) - def2 -= def2 * (sc->data[SC_FLING]->val3)/100; if (sc->data[SC_ANALYZE]) def2 -= def2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100; if (sc->data[SC_ECHOSONG]) @@ -5006,6 +5121,7 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change def2 -= def2 * sc->data[SC_NEEDLE_OF_PARALYZE]->val2 / 100; if (sc->data[SC_UNLIMIT]) return 1; + #ifdef RENEWAL return (short)cap_value(def2,SHRT_MIN,SHRT_MAX); #else @@ -5038,7 +5154,7 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, return 90; #endif - if(sc->data[SC_STONESKIN]) + if(sc->data[SC_STONESKIN]) // [Aegis] Technically this uses MDEFPercent/DEFPercent + sth else mdef += sc->data[SC_STONESKIN]->val3; if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3) mdef += 50; @@ -5085,8 +5201,6 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang /* some statuses that are hidden in the status window */ if(sc->data[SC_MDEFSET]) return sc->data[SC_MDEFSET]->val1; - if(sc->data[SC_MINDBREAKER]) - mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100; #ifdef RENEWAL if (sc->data[SC_ASSUMPTIO]) mdef2 <<= 1; @@ -5104,6 +5218,11 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang mdef2 -= mdef2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100; if (sc->data[SC_UNLIMIT]) return 1; + + struct status_data *sstatus = status->get_status_data(bl); + if (sstatus != NULL) // may be NULL on first call + mdef2 = (mdef2 * sstatus->mdef_percent) / 100; + #ifdef RENEWAL return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX); #else @@ -6972,7 +7091,8 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl struct status_change_entry* sce; struct status_data *st; struct view_data *vd; - int opt_flag, calc_flag, undead_flag, val_flag = 0, tick_time = 0; + int opt_flag, undead_flag, val_flag = 0, tick_time = 0; + e_scb_flag calc_flag = SCB_NONE; nullpo_ret(bl); sc = status->get_sc(bl); @@ -7461,6 +7581,14 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl if( sce->val4 && !val4 )//you cannot override master guild aura return 0; break; + case SC_TAROTCARD_ATK_PERC: + case SC_TAROTCARD_MATK_PERC: + case SC_TAROTCARD_DEF_PERC: + case SC_GOSPEL_ATK_PERC: + // [Aegis] Don't override stronger (m)atk & m(def) percentage based buffs. + if (abs(val1) < abs(sce->val1)) + return 1; + break; case SC_JOINTBEAT: val2 |= sce->val2; // stackable ailments FALLTHROUGH @@ -7612,11 +7740,11 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl } break; case SC_NOEQUIPWEAPON: - if (!sd) //Watk reduction + if (sd == NULL) // ATK% reduction val2 = 25; break; case SC_NOEQUIPSHIELD: - if (!sd) //Def reduction + if (sd == NULL) // DEF% reduction val2 = 15; break; case SC_NOEQUIPARMOR: @@ -8162,13 +8290,13 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl total_tick += total_tick / 10; break; case SC_LKCONCENTRATION: - val2 = 5*val1; //Batk/Watk Increase + val2 = 5 * val1; // ATK% Increase val3 = 10*val1; //Hit Increase - val4 = 5*val1; //Def reduction + val4 = 5 * val1; // Def% reduction sc_start(src, bl, SC_ENDURE, 100, 1, total_tick, skill_id); // Endure effect break; case SC_ANGELUS: - val2 = 5*val1; //def increase + val2 = 5*val1; // DEF% increase break; case SC_IMPOSITIO: val2 = 5*val1; //watk increase @@ -8204,11 +8332,7 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl break; case SC_FLING: - if (bl->type == BL_PC) - val2 = 0; //No armor reduction to players. - else - val2 = 5*val1; //Def reduction - val3 = 5*val1; //Def2 reduction + val2 = 5*val1; // DEF% reduction break; case SC_PROVOKE: //val2 signals autoprovoke. @@ -8228,11 +8352,11 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl break; case SC_HLIF_FLEET: val2 = 30*val1; //Aspd change - val3 = 5+5*val1; //bAtk/wAtk rate change + val3 = 5+5*val1; // ATK% change break; case SC_MINDBREAKER: - val2 = 20*val1; //matk increase. - val3 = 12*val1; //mdef2 reduction. + val2 = 20 * val1; // MATK% increase. + val3 = 12 * val1; // MDEF% reduction. break; case SC_SKA: val2 = total_tick/1000; @@ -9667,7 +9791,7 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl return 1; } -static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag) +static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, e_scb_flag calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag) { Assert_retr(false, type >= SC_NONE && type < SC_MAX); if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->get_sc_icon(type) == SI_BLANK) { @@ -10694,8 +10818,9 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid) struct status_change_entry *sce; struct status_data *st; struct view_data *vd; - int opt_flag=0, calc_flag; + int opt_flag=0; bool invisible = false; + e_scb_flag calc_flag = SCB_NONE; nullpo_ret(bl); @@ -13997,7 +14122,7 @@ static bool status_read_scdb_libconfig_sub_calcflag(struct config_setting_t *it, struct { const char *name; - enum scb_flag value; + e_scb_flag value; } flags[] = { { "None", SCB_NONE }, { "Base", SCB_BASE }, @@ -14031,6 +14156,10 @@ static bool status_read_scdb_libconfig_sub_calcflag(struct config_setting_t *it, { "Range", SCB_RANGE }, { "Regen", SCB_REGEN }, { "Dye", SCB_DYE }, + { "AtkPerc", SCB_ATK_PERC }, + { "DefPerc", SCB_DEF_PERC }, + { "MatkPerc", SCB_MATK_PERC }, + { "MdefPerc", SCB_MDEF_PERC }, { "All", SCB_ALL }, }; @@ -14566,6 +14695,10 @@ void status_defaults(void) status->calc_int = status_calc_int; status->calc_dex = status_calc_dex; status->calc_luk = status_calc_luk; + status->calc_atk_percent = status_calc_atk_percent; + status->calc_matk_percent = status_calc_matk_percent; + status->calc_def_percent = status_calc_def_percent; + status->calc_mdef_percent = status_calc_mdef_percent; status->calc_watk = status_calc_watk; status->calc_matk = status_calc_matk; status->calc_hit = status_calc_hit; diff --git a/src/map/status.h b/src/map/status.h index 4944d03bd42..adbc6317e64 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -914,6 +914,10 @@ typedef enum sc_type { SC_FIRE_EXPANSION_TEAR_GAS_SOB, + SC_TAROTCARD_ATK_PERC, + SC_TAROTCARD_MATK_PERC, + SC_TAROTCARD_DEF_PERC, + SC_GOSPEL_ATK_PERC, #ifndef SC_MAX SC_MAX, //Automatically updated max, used in for's to check we are within bounds. #endif @@ -1030,48 +1034,75 @@ enum manner_flags MANNER_NOROOM = 0x10, }; +#ifndef _MSC_VER +#define CONST_OR_ENUMVAL(_const_, _val_) _const_ = _val_, +#else +#define CONST_OR_ENUMVAL(_const_, _val_) static const uint64_t _const_ = _val_; +#endif + +#ifndef _MSC_VER //Define flags for the status_calc_bl function. [Skotlex] -enum scb_flag +enum _scb_flag { - SCB_NONE = 0x00000000, - SCB_BASE = 0x00000001, - SCB_MAXHP = 0x00000002, - SCB_MAXSP = 0x00000004, - SCB_STR = 0x00000008, - SCB_AGI = 0x00000010, - SCB_VIT = 0x00000020, - SCB_INT = 0x00000040, - SCB_DEX = 0x00000080, - SCB_LUK = 0x00000100, - SCB_BATK = 0x00000200, - SCB_WATK = 0x00000400, - SCB_MATK = 0x00000800, - SCB_HIT = 0x00001000, - SCB_FLEE = 0x00002000, - SCB_DEF = 0x00004000, - SCB_DEF2 = 0x00008000, - SCB_MDEF = 0x00010000, - SCB_MDEF2 = 0x00020000, - SCB_SPEED = 0x00040000, - SCB_ASPD = 0x00080000, - SCB_DSPD = 0x00100000, - SCB_CRI = 0x00200000, - SCB_FLEE2 = 0x00400000, - SCB_ATK_ELE = 0x00800000, - SCB_DEF_ELE = 0x01000000, - SCB_MODE = 0x02000000, - SCB_SIZE = 0x04000000, - SCB_RACE = 0x08000000, - SCB_RANGE = 0x10000000, - SCB_REGEN = 0x20000000, - SCB_DYE = 0x40000000, // force cloth-dye change to 0 to avoid client crashes. +#endif + CONST_OR_ENUMVAL(SCB_NONE, 0x00000000) + CONST_OR_ENUMVAL(SCB_BASE, 0x00000001) + CONST_OR_ENUMVAL(SCB_MAXHP, 0x00000002) + CONST_OR_ENUMVAL(SCB_MAXSP, 0x00000004) + CONST_OR_ENUMVAL(SCB_STR, 0x00000008) + CONST_OR_ENUMVAL(SCB_AGI, 0x00000010) + CONST_OR_ENUMVAL(SCB_VIT, 0x00000020) + CONST_OR_ENUMVAL(SCB_INT, 0x00000040) + CONST_OR_ENUMVAL(SCB_DEX, 0x00000080) + CONST_OR_ENUMVAL(SCB_LUK, 0x00000100) + CONST_OR_ENUMVAL(SCB_BATK, 0x00000200) + CONST_OR_ENUMVAL(SCB_WATK, 0x00000400) + CONST_OR_ENUMVAL(SCB_MATK, 0x00000800) + CONST_OR_ENUMVAL(SCB_HIT, 0x00001000) + CONST_OR_ENUMVAL(SCB_FLEE, 0x00002000) + CONST_OR_ENUMVAL(SCB_DEF, 0x00004000) + CONST_OR_ENUMVAL(SCB_DEF2, 0x00008000) + CONST_OR_ENUMVAL(SCB_MDEF, 0x00010000) + CONST_OR_ENUMVAL(SCB_MDEF2, 0x00020000) + CONST_OR_ENUMVAL(SCB_SPEED, 0x00040000) + CONST_OR_ENUMVAL(SCB_ASPD, 0x00080000) + CONST_OR_ENUMVAL(SCB_DSPD, 0x00100000) + CONST_OR_ENUMVAL(SCB_CRI, 0x00200000) + CONST_OR_ENUMVAL(SCB_FLEE2, 0x00400000) + CONST_OR_ENUMVAL(SCB_ATK_ELE, 0x00800000) + CONST_OR_ENUMVAL(SCB_DEF_ELE, 0x01000000) + CONST_OR_ENUMVAL(SCB_MODE, 0x02000000) + CONST_OR_ENUMVAL(SCB_SIZE, 0x04000000) + CONST_OR_ENUMVAL(SCB_RACE, 0x08000000) + CONST_OR_ENUMVAL(SCB_RANGE, 0x10000000) + CONST_OR_ENUMVAL(SCB_REGEN, 0x20000000) + CONST_OR_ENUMVAL(SCB_DYE, 0x40000000) // force cloth-dye change to 0 to avoid client crashes. #if 0 // Currently No SC use it. Also, when this will be implemented, there will be need to change to 64bit variable - SCB_BODY = 0x80000000, // Force bodysStyle change to 0 + CONST_OR_ENUMVAL(SCB_BODY, 0x80000000) // Force bodysStyle change to 0 #endif - - SCB_BATTLE = 0x3FFFFFFE, - SCB_ALL = 0x3FFFFFFF + CONST_OR_ENUMVAL(SCB_ATK_PERC, 0x100000000) + CONST_OR_ENUMVAL(SCB_MATK_PERC, 0x200000000) + CONST_OR_ENUMVAL(SCB_DEF_PERC, 0x400000000) + CONST_OR_ENUMVAL(SCB_MDEF_PERC, 0x800000000) + + CONST_OR_ENUMVAL(SCB_BATTLE, 0xF3FFFFFFE) + CONST_OR_ENUMVAL(SCB_ALL, 0xF3FFFFFFF) +#ifndef _MSC_VER }; +#endif + +#ifndef _MSC_VER + typedef enum _scb_flag e_scb_flag; +#else + typedef uint64_t e_scb_flag; +#endif +#undef CONST_OR_ENUMVAL + +STATIC_ASSERT(sizeof(e_scb_flag) > 4, "e_scb_flag values need to be larger than 32 bits."); +STATIC_ASSERT(sizeof(SCB_ATK_PERC) > 4, "e_scb_flag values need to be larger than 32 bits."); +STATIC_ASSERT(sizeof(SCB_MATK_PERC) > 4, "e_scb_flag values need to be larger than 32 bits."); +STATIC_ASSERT(sizeof(SCB_DEF_PERC) > 4, "e_scb_flag values need to be larger than 32 bits."); +STATIC_ASSERT(sizeof(SCB_MDEF_PERC) > 4, "e_scb_flag values need to be larger than 32 bits."); //Regen related flags. enum e_regen { @@ -1113,6 +1144,10 @@ struct status_data { hp, sp, // see status_cpy before adding members before hp and sp max_hp, max_sp; uint16 str, agi, vit, int_, dex, luk; + int atk_percent; + int matk_percent; + int def_percent; + int mdef_percent; uint32 batk, matk_min, matk_max, @@ -1274,7 +1309,7 @@ struct status_change { #define status_change_end(bl,type,tid) (status->change_end_((bl),(type),(tid))) -#define status_calc_bl(bl, flag) (status->calc_bl_((bl), (enum scb_flag)(flag), SCO_NONE)) +#define status_calc_bl(bl, flag) (status->calc_bl_((bl), (e_scb_flag)(flag), SCO_NONE)) #define status_calc_mob(md, opt) (status->calc_bl_(&(md)->bl, SCB_ALL, (opt))) #define status_calc_pet(pd, opt) (status->calc_bl_(&(pd)->bl, SCB_ALL, (opt))) #define status_calc_pc(sd, opt) (status->calc_bl_(&(sd)->bl, SCB_ALL, (opt))) @@ -1311,7 +1346,7 @@ BEGIN_ZEROED_BLOCK; /* Everything within this block will be memset to 0 when sta int id; int relevant_bl_types; } IconChangeTable[SC_MAX]; - unsigned int ChangeFlagTable[SC_MAX]; // status -> flags + e_scb_flag ChangeFlagTable[SC_MAX]; // status -> flags int SkillChangeTable[SC_MAX]; // status -> skill bool DisplayType[SC_MAX]; /* */ @@ -1347,7 +1382,7 @@ struct status_interface { /* funcs */ // for looking up associated data int (*sc2skill) (sc_type sc); - unsigned int (*sc2scb_flag) (sc_type sc); + e_scb_flag (*sc2scb_flag) (sc_type sc); int (*get_sc_relevant_bl_types) (sc_type type); int (*get_sc_type) (sc_type idx); int (*get_sc_icon) (sc_type type); @@ -1392,13 +1427,13 @@ struct status_interface { int (*change_start_set_option) (struct block_list *bl, struct status_change* sc, enum sc_type type, int val1, int val2, int val3, int val4); int (*get_val_flag) (enum sc_type type); void (*change_start_display) (struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4); - bool (*change_start_unknown_sc) (struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag); + bool (*change_start_unknown_sc) (struct block_list *src, struct block_list *bl, enum sc_type type, e_scb_flag calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag); int (*kaahi_heal_timer) (int tid, int64 tick, int id, intptr_t data); int (*change_timer) (int tid, int64 tick, int id, intptr_t data); int (*change_timer_sub) (struct block_list* bl, va_list ap); int (*change_clear) (struct block_list* bl, int type); int (*change_clear_buffs) (struct block_list* bl, int type); - void (*calc_bl_) (struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt); + void (*calc_bl_) (struct block_list *bl, e_scb_flag flag, enum e_status_calc_opt opt); int (*calc_mob_) (struct mob_data* md, enum e_status_calc_opt opt); int (*calc_pet_) (struct pet_data* pd, enum e_status_calc_opt opt); int (*calc_pc_) (struct map_session_data* sd, enum e_status_calc_opt opt); @@ -1450,6 +1485,10 @@ struct status_interface { unsigned short (*calc_int) (struct block_list *bl, struct status_change *sc, int int_); unsigned short (*calc_dex) (struct block_list *bl, struct status_change *sc, int dex); unsigned short (*calc_luk) (struct block_list *bl, struct status_change *sc, int luk); + int (*calc_atk_percent) (struct block_list *bl, struct status_change *sc); + int (*calc_matk_percent) (struct block_list *bl, struct status_change *sc); + int (*calc_def_percent) (struct block_list *bl, struct status_change *sc); + int (*calc_mdef_percent) (struct block_list *bl, struct status_change *sc); int (*calc_watk) (struct block_list *bl, struct status_change *sc, int watk, bool viewable); int (*calc_matk) (struct block_list *bl, struct status_change *sc, int matk, bool viewable); signed int (*calc_hit) (struct block_list *bl, struct status_change *sc, int hit, bool viewable); @@ -1467,7 +1506,7 @@ struct status_interface { unsigned char (*calc_element_lv) (struct block_list *bl, struct status_change *sc, int lv); uint32 (*calc_mode) (const struct block_list *bl, const struct status_change *sc, uint32 mode); int (*calc_ematk) (struct block_list *bl, struct status_change *sc, int matk); - void (*calc_bl_main) (struct block_list *bl, int flag); + void (*calc_bl_main) (struct block_list *bl, e_scb_flag flag); void (*display_add) (struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3); void (*display_remove) (struct map_session_data *sd, enum sc_type type); int (*natural_heal) (struct block_list *bl, va_list args); diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 0830c628958..8895dda5787 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -9038,8 +9038,8 @@ typedef void (*HPMHOOK_pre_status_final) (void); typedef void (*HPMHOOK_post_status_final) (void); typedef int (*HPMHOOK_pre_status_sc2skill) (sc_type *sc); typedef int (*HPMHOOK_post_status_sc2skill) (int retVal___, sc_type sc); -typedef unsigned int (*HPMHOOK_pre_status_sc2scb_flag) (sc_type *sc); -typedef unsigned int (*HPMHOOK_post_status_sc2scb_flag) (unsigned int retVal___, sc_type sc); +typedef e_scb_flag (*HPMHOOK_pre_status_sc2scb_flag) (sc_type *sc); +typedef e_scb_flag (*HPMHOOK_post_status_sc2scb_flag) (e_scb_flag retVal___, sc_type sc); typedef int (*HPMHOOK_pre_status_get_sc_relevant_bl_types) (sc_type *type); typedef int (*HPMHOOK_post_status_get_sc_relevant_bl_types) (int retVal___, sc_type type); typedef int (*HPMHOOK_pre_status_get_sc_type) (sc_type *idx); @@ -9124,8 +9124,8 @@ typedef int (*HPMHOOK_pre_status_get_val_flag) (enum sc_type *type); typedef int (*HPMHOOK_post_status_get_val_flag) (int retVal___, enum sc_type type); typedef void (*HPMHOOK_pre_status_change_start_display) (struct map_session_data **sd, enum sc_type *type, int *val1, int *val2, int *val3, int *val4); typedef void (*HPMHOOK_post_status_change_start_display) (struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4); -typedef bool (*HPMHOOK_pre_status_change_start_unknown_sc) (struct block_list **src, struct block_list **bl, enum sc_type *type, int *calc_flag, int *rate, int *val1, int *val2, int *val3, int *val4, int *total_tick, int *flag); -typedef bool (*HPMHOOK_post_status_change_start_unknown_sc) (bool retVal___, struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag); +typedef bool (*HPMHOOK_pre_status_change_start_unknown_sc) (struct block_list **src, struct block_list **bl, enum sc_type *type, e_scb_flag *calc_flag, int *rate, int *val1, int *val2, int *val3, int *val4, int *total_tick, int *flag); +typedef bool (*HPMHOOK_post_status_change_start_unknown_sc) (bool retVal___, struct block_list *src, struct block_list *bl, enum sc_type type, e_scb_flag calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag); typedef int (*HPMHOOK_pre_status_kaahi_heal_timer) (int *tid, int64 *tick, int *id, intptr_t *data); typedef int (*HPMHOOK_post_status_kaahi_heal_timer) (int retVal___, int tid, int64 tick, int id, intptr_t data); typedef int (*HPMHOOK_pre_status_change_timer) (int *tid, int64 *tick, int *id, intptr_t *data); @@ -9136,8 +9136,8 @@ typedef int (*HPMHOOK_pre_status_change_clear) (struct block_list **bl, int *typ typedef int (*HPMHOOK_post_status_change_clear) (int retVal___, struct block_list *bl, int type); typedef int (*HPMHOOK_pre_status_change_clear_buffs) (struct block_list **bl, int *type); typedef int (*HPMHOOK_post_status_change_clear_buffs) (int retVal___, struct block_list *bl, int type); -typedef void (*HPMHOOK_pre_status_calc_bl_) (struct block_list **bl, enum scb_flag *flag, enum e_status_calc_opt *opt); -typedef void (*HPMHOOK_post_status_calc_bl_) (struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt); +typedef void (*HPMHOOK_pre_status_calc_bl_) (struct block_list **bl, e_scb_flag *flag, enum e_status_calc_opt *opt); +typedef void (*HPMHOOK_post_status_calc_bl_) (struct block_list *bl, e_scb_flag flag, enum e_status_calc_opt opt); typedef int (*HPMHOOK_pre_status_calc_mob_) (struct mob_data **md, enum e_status_calc_opt *opt); typedef int (*HPMHOOK_post_status_calc_mob_) (int retVal___, struct mob_data *md, enum e_status_calc_opt opt); typedef int (*HPMHOOK_pre_status_calc_pet_) (struct pet_data **pd, enum e_status_calc_opt *opt); @@ -9238,6 +9238,14 @@ typedef unsigned short (*HPMHOOK_pre_status_calc_dex) (struct block_list **bl, s typedef unsigned short (*HPMHOOK_post_status_calc_dex) (unsigned short retVal___, struct block_list *bl, struct status_change *sc, int dex); typedef unsigned short (*HPMHOOK_pre_status_calc_luk) (struct block_list **bl, struct status_change **sc, int *luk); typedef unsigned short (*HPMHOOK_post_status_calc_luk) (unsigned short retVal___, struct block_list *bl, struct status_change *sc, int luk); +typedef int (*HPMHOOK_pre_status_calc_atk_percent) (struct block_list **bl, struct status_change **sc); +typedef int (*HPMHOOK_post_status_calc_atk_percent) (int retVal___, struct block_list *bl, struct status_change *sc); +typedef int (*HPMHOOK_pre_status_calc_matk_percent) (struct block_list **bl, struct status_change **sc); +typedef int (*HPMHOOK_post_status_calc_matk_percent) (int retVal___, struct block_list *bl, struct status_change *sc); +typedef int (*HPMHOOK_pre_status_calc_def_percent) (struct block_list **bl, struct status_change **sc); +typedef int (*HPMHOOK_post_status_calc_def_percent) (int retVal___, struct block_list *bl, struct status_change *sc); +typedef int (*HPMHOOK_pre_status_calc_mdef_percent) (struct block_list **bl, struct status_change **sc); +typedef int (*HPMHOOK_post_status_calc_mdef_percent) (int retVal___, struct block_list *bl, struct status_change *sc); typedef int (*HPMHOOK_pre_status_calc_watk) (struct block_list **bl, struct status_change **sc, int *watk, bool *viewable); typedef int (*HPMHOOK_post_status_calc_watk) (int retVal___, struct block_list *bl, struct status_change *sc, int watk, bool viewable); typedef int (*HPMHOOK_pre_status_calc_matk) (struct block_list **bl, struct status_change **sc, int *matk, bool *viewable); @@ -9272,8 +9280,8 @@ typedef uint32 (*HPMHOOK_pre_status_calc_mode) (const struct block_list **bl, co typedef uint32 (*HPMHOOK_post_status_calc_mode) (uint32 retVal___, const struct block_list *bl, const struct status_change *sc, uint32 mode); typedef int (*HPMHOOK_pre_status_calc_ematk) (struct block_list **bl, struct status_change **sc, int *matk); typedef int (*HPMHOOK_post_status_calc_ematk) (int retVal___, struct block_list *bl, struct status_change *sc, int matk); -typedef void (*HPMHOOK_pre_status_calc_bl_main) (struct block_list **bl, int *flag); -typedef void (*HPMHOOK_post_status_calc_bl_main) (struct block_list *bl, int flag); +typedef void (*HPMHOOK_pre_status_calc_bl_main) (struct block_list **bl, e_scb_flag *flag); +typedef void (*HPMHOOK_post_status_calc_bl_main) (struct block_list *bl, e_scb_flag flag); typedef void (*HPMHOOK_pre_status_display_add) (struct map_session_data **sd, enum sc_type *type, int *dval1, int *dval2, int *dval3); typedef void (*HPMHOOK_post_status_display_add) (struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3); typedef void (*HPMHOOK_pre_status_display_remove) (struct map_session_data **sd, enum sc_type *type); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index f24012717f0..17e3f1a9d72 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -7154,6 +7154,14 @@ struct { struct HPMHookPoint *HP_status_calc_dex_post; struct HPMHookPoint *HP_status_calc_luk_pre; struct HPMHookPoint *HP_status_calc_luk_post; + struct HPMHookPoint *HP_status_calc_atk_percent_pre; + struct HPMHookPoint *HP_status_calc_atk_percent_post; + struct HPMHookPoint *HP_status_calc_matk_percent_pre; + struct HPMHookPoint *HP_status_calc_matk_percent_post; + struct HPMHookPoint *HP_status_calc_def_percent_pre; + struct HPMHookPoint *HP_status_calc_def_percent_post; + struct HPMHookPoint *HP_status_calc_mdef_percent_pre; + struct HPMHookPoint *HP_status_calc_mdef_percent_post; struct HPMHookPoint *HP_status_calc_watk_pre; struct HPMHookPoint *HP_status_calc_watk_post; struct HPMHookPoint *HP_status_calc_matk_pre; @@ -14715,6 +14723,14 @@ struct { int HP_status_calc_dex_post; int HP_status_calc_luk_pre; int HP_status_calc_luk_post; + int HP_status_calc_atk_percent_pre; + int HP_status_calc_atk_percent_post; + int HP_status_calc_matk_percent_pre; + int HP_status_calc_matk_percent_post; + int HP_status_calc_def_percent_pre; + int HP_status_calc_def_percent_post; + int HP_status_calc_mdef_percent_pre; + int HP_status_calc_mdef_percent_post; int HP_status_calc_watk_pre; int HP_status_calc_watk_post; int HP_status_calc_matk_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index 2620b530b14..bbd15afec69 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -3656,6 +3656,10 @@ struct HookingPointData HookingPoints[] = { { HP_POP(status->calc_int, HP_status_calc_int) }, { HP_POP(status->calc_dex, HP_status_calc_dex) }, { HP_POP(status->calc_luk, HP_status_calc_luk) }, + { HP_POP(status->calc_atk_percent, HP_status_calc_atk_percent) }, + { HP_POP(status->calc_matk_percent, HP_status_calc_matk_percent) }, + { HP_POP(status->calc_def_percent, HP_status_calc_def_percent) }, + { HP_POP(status->calc_mdef_percent, HP_status_calc_mdef_percent) }, { HP_POP(status->calc_watk, HP_status_calc_watk) }, { HP_POP(status->calc_matk, HP_status_calc_matk) }, { HP_POP(status->calc_hit, HP_status_calc_hit) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 9e0460dd959..c6157ffb6f4 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -92934,11 +92934,11 @@ int HP_status_sc2skill(sc_type sc) { } return retVal___; } -unsigned int HP_status_sc2scb_flag(sc_type sc) { +e_scb_flag HP_status_sc2scb_flag(sc_type sc) { int hIndex = 0; - unsigned int retVal___ = 0; + e_scb_flag retVal___ = SCB_NONE; if (HPMHooks.count.HP_status_sc2scb_flag_pre > 0) { - unsigned int (*preHookFunc) (sc_type *sc); + e_scb_flag (*preHookFunc) (sc_type *sc); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_status_sc2scb_flag_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_status_sc2scb_flag_pre[hIndex].func; @@ -92953,7 +92953,7 @@ unsigned int HP_status_sc2scb_flag(sc_type sc) { retVal___ = HPMHooks.source.status.sc2scb_flag(sc); } if (HPMHooks.count.HP_status_sc2scb_flag_post > 0) { - unsigned int (*postHookFunc) (unsigned int retVal___, sc_type sc); + e_scb_flag (*postHookFunc) (e_scb_flag retVal___, sc_type sc); for (hIndex = 0; hIndex < HPMHooks.count.HP_status_sc2scb_flag_post; hIndex++) { postHookFunc = HPMHooks.list.HP_status_sc2scb_flag_post[hIndex].func; retVal___ = postHookFunc(retVal___, sc); @@ -94091,11 +94091,11 @@ void HP_status_change_start_display(struct map_session_data *sd, enum sc_type ty } return; } -bool HP_status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag) { +bool HP_status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, e_scb_flag calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag) { int hIndex = 0; bool retVal___ = false; if (HPMHooks.count.HP_status_change_start_unknown_sc_pre > 0) { - bool (*preHookFunc) (struct block_list **src, struct block_list **bl, enum sc_type *type, int *calc_flag, int *rate, int *val1, int *val2, int *val3, int *val4, int *total_tick, int *flag); + bool (*preHookFunc) (struct block_list **src, struct block_list **bl, enum sc_type *type, e_scb_flag *calc_flag, int *rate, int *val1, int *val2, int *val3, int *val4, int *total_tick, int *flag); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_status_change_start_unknown_sc_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_status_change_start_unknown_sc_pre[hIndex].func; @@ -94110,7 +94110,7 @@ bool HP_status_change_start_unknown_sc(struct block_list *src, struct block_list retVal___ = HPMHooks.source.status.change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, total_tick, flag); } if (HPMHooks.count.HP_status_change_start_unknown_sc_post > 0) { - bool (*postHookFunc) (bool retVal___, struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag); + bool (*postHookFunc) (bool retVal___, struct block_list *src, struct block_list *bl, enum sc_type type, e_scb_flag calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag); for (hIndex = 0; hIndex < HPMHooks.count.HP_status_change_start_unknown_sc_post; hIndex++) { postHookFunc = HPMHooks.list.HP_status_change_start_unknown_sc_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, type, calc_flag, rate, val1, val2, val3, val4, total_tick, flag); @@ -94259,10 +94259,10 @@ int HP_status_change_clear_buffs(struct block_list *bl, int type) { } return retVal___; } -void HP_status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt) { +void HP_status_calc_bl_(struct block_list *bl, e_scb_flag flag, enum e_status_calc_opt opt) { int hIndex = 0; if (HPMHooks.count.HP_status_calc_bl__pre > 0) { - void (*preHookFunc) (struct block_list **bl, enum scb_flag *flag, enum e_status_calc_opt *opt); + void (*preHookFunc) (struct block_list **bl, e_scb_flag *flag, enum e_status_calc_opt *opt); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_bl__pre; hIndex++) { preHookFunc = HPMHooks.list.HP_status_calc_bl__pre[hIndex].func; @@ -94277,7 +94277,7 @@ void HP_status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status HPMHooks.source.status.calc_bl_(bl, flag, opt); } if (HPMHooks.count.HP_status_calc_bl__post > 0) { - void (*postHookFunc) (struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt); + void (*postHookFunc) (struct block_list *bl, e_scb_flag flag, enum e_status_calc_opt opt); for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_bl__post; hIndex++) { postHookFunc = HPMHooks.list.HP_status_calc_bl__post[hIndex].func; postHookFunc(bl, flag, opt); @@ -95620,6 +95620,114 @@ unsigned short HP_status_calc_luk(struct block_list *bl, struct status_change *s } return retVal___; } +int HP_status_calc_atk_percent(struct block_list *bl, struct status_change *sc) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_status_calc_atk_percent_pre > 0) { + int (*preHookFunc) (struct block_list **bl, struct status_change **sc); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_atk_percent_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_status_calc_atk_percent_pre[hIndex].func; + retVal___ = preHookFunc(&bl, &sc); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.status.calc_atk_percent(bl, sc); + } + if (HPMHooks.count.HP_status_calc_atk_percent_post > 0) { + int (*postHookFunc) (int retVal___, struct block_list *bl, struct status_change *sc); + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_atk_percent_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_status_calc_atk_percent_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, sc); + } + } + return retVal___; +} +int HP_status_calc_matk_percent(struct block_list *bl, struct status_change *sc) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_status_calc_matk_percent_pre > 0) { + int (*preHookFunc) (struct block_list **bl, struct status_change **sc); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_matk_percent_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_status_calc_matk_percent_pre[hIndex].func; + retVal___ = preHookFunc(&bl, &sc); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.status.calc_matk_percent(bl, sc); + } + if (HPMHooks.count.HP_status_calc_matk_percent_post > 0) { + int (*postHookFunc) (int retVal___, struct block_list *bl, struct status_change *sc); + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_matk_percent_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_status_calc_matk_percent_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, sc); + } + } + return retVal___; +} +int HP_status_calc_def_percent(struct block_list *bl, struct status_change *sc) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_status_calc_def_percent_pre > 0) { + int (*preHookFunc) (struct block_list **bl, struct status_change **sc); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_def_percent_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_status_calc_def_percent_pre[hIndex].func; + retVal___ = preHookFunc(&bl, &sc); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.status.calc_def_percent(bl, sc); + } + if (HPMHooks.count.HP_status_calc_def_percent_post > 0) { + int (*postHookFunc) (int retVal___, struct block_list *bl, struct status_change *sc); + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_def_percent_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_status_calc_def_percent_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, sc); + } + } + return retVal___; +} +int HP_status_calc_mdef_percent(struct block_list *bl, struct status_change *sc) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_status_calc_mdef_percent_pre > 0) { + int (*preHookFunc) (struct block_list **bl, struct status_change **sc); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_mdef_percent_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_status_calc_mdef_percent_pre[hIndex].func; + retVal___ = preHookFunc(&bl, &sc); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.status.calc_mdef_percent(bl, sc); + } + if (HPMHooks.count.HP_status_calc_mdef_percent_post > 0) { + int (*postHookFunc) (int retVal___, struct block_list *bl, struct status_change *sc); + for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_mdef_percent_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_status_calc_mdef_percent_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, sc); + } + } + return retVal___; +} int HP_status_calc_watk(struct block_list *bl, struct status_change *sc, int watk, bool viewable) { int hIndex = 0; int retVal___ = 0; @@ -96079,10 +96187,10 @@ int HP_status_calc_ematk(struct block_list *bl, struct status_change *sc, int ma } return retVal___; } -void HP_status_calc_bl_main(struct block_list *bl, int flag) { +void HP_status_calc_bl_main(struct block_list *bl, e_scb_flag flag) { int hIndex = 0; if (HPMHooks.count.HP_status_calc_bl_main_pre > 0) { - void (*preHookFunc) (struct block_list **bl, int *flag); + void (*preHookFunc) (struct block_list **bl, e_scb_flag *flag); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_bl_main_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_status_calc_bl_main_pre[hIndex].func; @@ -96097,7 +96205,7 @@ void HP_status_calc_bl_main(struct block_list *bl, int flag) { HPMHooks.source.status.calc_bl_main(bl, flag); } if (HPMHooks.count.HP_status_calc_bl_main_post > 0) { - void (*postHookFunc) (struct block_list *bl, int flag); + void (*postHookFunc) (struct block_list *bl, e_scb_flag flag); for (hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_bl_main_post; hIndex++) { postHookFunc = HPMHooks.list.HP_status_calc_bl_main_post[hIndex].func; postHookFunc(bl, flag); diff --git a/tools/HPMHookGen/HPMHookGen.pl b/tools/HPMHookGen/HPMHookGen.pl index a1aa9ef1cc5..49f9cc6c003 100755 --- a/tools/HPMHookGen/HPMHookGen.pl +++ b/tools/HPMHookGen/HPMHookGen.pl @@ -250,6 +250,8 @@ ($$) $rtinit = ' = UNIT_DIR_UNDEFINED'; } elsif ($x =~ /^enum\s+quest_mobtype$/) { # Known enum quest_mobtype $rtinit = ' = QMT_RC_DEMIHUMAN'; + } elsif ($x =~ /^e_scb_flag$/) { # Known typedef e_scb_flag + $rtinit = ' = SCB_NONE'; } elsif ($x eq 'DBComparator' or $x eq 'DBHasher' or $x eq 'DBReleaser') { # DB function pointers $rtinit = ' = NULL'; } elsif ($x =~ /^(?:struct|union)\s+.*$/) { # Structs and unions