summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/map/battle/client.conf12
-rw-r--r--src/map/atcommand.c6
-rw-r--r--src/map/battle.c7
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/clif.c7
-rw-r--r--src/map/pc.c11
-rw-r--r--src/map/script.c28
-rw-r--r--src/map/skill.c105
-rw-r--r--src/map/status.c178
-rw-r--r--src/map/status.h18
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc16
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc8
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc2
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc72
14 files changed, 313 insertions, 159 deletions
diff --git a/conf/map/battle/client.conf b/conf/map/battle/client.conf
index 35c585bf6..b7d4ac781 100644
--- a/conf/map/battle/client.conf
+++ b/conf/map/battle/client.conf
@@ -177,3 +177,15 @@ client_emblem_max_blank_percent: 100
// kRO removed the packet and this re-enables the message.
// Official: false.
mvp_exp_reward_message: false
+
+// Displays the same HP value as official servers do when a character is dead.
+// (Note 1)
+// On official servers, HP are never displayed as 0, but when dead, they
+// display the value that will be shown after resurrection (50% HP for novice
+// classes, 1 HP for other classes). Athena servers, instead, show the real
+// value (0 when dead), to avoid confusion.
+// Note: this is only a visual setting, and the server will internally handle
+// it as 0 regardless of this. This means that scripts will know that the
+// character has 0 HP when dead.
+// Default: true (Official behavior)
+display_fake_hp_when_dead: true
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 236975b32..c8cca2aea 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1131,7 +1131,7 @@ ACMD(heal)
}
if ( hp > 0 && sp >= 0 ) {
- if(!status->heal(&sd->bl, hp, sp, 0))
+ if (status->heal(&sd->bl, hp, sp, STATUS_HEAL_DEFAULT) == 0)
clif->message(fd, msg_fd(fd,157)); // HP and SP are already with the good value.
else
clif->message(fd, msg_fd(fd,17)); // HP, SP recovered.
@@ -1148,7 +1148,7 @@ ACMD(heal)
//Opposing signs.
if ( hp ) {
if (hp > 0)
- status->heal(&sd->bl, hp, 0, 0);
+ status->heal(&sd->bl, hp, 0, STATUS_HEAL_DEFAULT);
else {
status->damage(NULL, &sd->bl, -hp, 0, 0, 0);
clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, BDT_ENDURE, 0);
@@ -1157,7 +1157,7 @@ ACMD(heal)
if ( sp ) {
if (sp > 0)
- status->heal(&sd->bl, 0, sp, 0);
+ status->heal(&sd->bl, 0, sp, STATUS_HEAL_DEFAULT);
else
status->damage(NULL, &sd->bl, 0, -sp, 0, 0);
}
diff --git a/src/map/battle.c b/src/map/battle.c
index 44241bf23..652453bf0 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -2872,7 +2872,7 @@ static int64 battle_calc_damage(struct block_list *src, struct block_list *bl, s
if( sc->data[SC__MAELSTROM] && (flag&BF_MAGIC) && skill_id && (skill->get_inf(skill_id)&INF_GROUND_SKILL) ) {
// {(Maelstrom Skill LevelxAbsorbed Skill Level)+(Caster's Job/5)}/2
int sp = (sc->data[SC__MAELSTROM]->val1 * skill_lv + (t_sd ? t_sd->status.job_level / 5 : 0)) / 2;
- status->heal(bl, 0, sp, 3);
+ status->heal(bl, 0, sp, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
d->dmg_lv = ATK_BLOCK;
return 0;
}
@@ -3243,7 +3243,7 @@ static int64 battle_calc_damage(struct block_list *src, struct block_list *bl, s
//(since battle_drain is strictly for players currently)
if ((sce=sc->data[SC_HAMI_BLOODLUST]) && flag&BF_WEAPON && damage > 0 &&
rnd()%100 < sce->val3)
- status->heal(src, damage*sce->val4/100, 0, 3);
+ status->heal(src, damage*sce->val4/100, 0, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
if( (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON
&& rnd()%100 < sce->val2 && sc->fv_counter <= sce->val3 )
@@ -6094,7 +6094,7 @@ static void battle_drain(struct map_session_data *sd, struct block_list *tbl, in
if (!thp && !tsp) return;
- status->heal(&sd->bl, thp, tsp, battle_config.show_hp_sp_drain ? 3 : 1);
+ status->heal(&sd->bl, thp, tsp, STATUS_HEAL_FORCED | (battle_config.show_hp_sp_drain ? STATUS_HEAL_SHOWEFFECT : STATUS_HEAL_DEFAULT));
if (rhp || rsp)
status_zap(tbl, rhp, rsp);
@@ -7407,6 +7407,7 @@ static const struct battle_data {
{ "features/feature_attendance_endtime",&battle_config.feature_attendance_endtime, 1, 0, 99999999, },
{ "min_item_buy_price", &battle_config.min_item_buy_price, 1, 0, INT_MAX, },
{ "min_item_sell_price", &battle_config.min_item_sell_price, 0, 0, INT_MAX, },
+ { "display_fake_hp_when_dead", &battle_config.display_fake_hp_when_dead, 1, 0, 1, },
};
static bool battle_set_value_sub(int index, int value)
diff --git a/src/map/battle.h b/src/map/battle.h
index 02536e4a1..750753c08 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -574,6 +574,8 @@ struct Battle_Config {
int min_item_buy_price;
int min_item_sell_price;
+
+ int display_fake_hp_when_dead;
};
/* criteria for battle_config.idletime_critera */
diff --git a/src/map/clif.c b/src/map/clif.c
index 44cefcd7e..d1ff201ad 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -3244,7 +3244,12 @@ static void clif_updatestatus(struct map_session_data *sd, int type)
WFIFOL(fd,4)=sd->battle_status.max_sp;
break;
case SP_HP:
- WFIFOL(fd,4)=sd->battle_status.hp;
+ if (sd->battle_status.hp == 0 && battle_config.display_fake_hp_when_dead) {
+ // On official servers, the HP displayed when dead is the HP that the character will have at respawn.
+ WFIFOL(fd, 4) = status->get_restart_hp(sd, &sd->battle_status);
+ } else {
+ WFIFOL(fd, 4) = sd->battle_status.hp;
+ }
break;
case SP_SP:
WFIFOL(fd,4)=sd->battle_status.sp;
diff --git a/src/map/pc.c b/src/map/pc.c
index b8a6912ee..78b773550 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -399,7 +399,7 @@ static int pc_banding(struct map_session_data *sd, uint16 skill_lv)
for( j = 0; j < i; j++ ) {
bsd = map->id2sd(b_sd[j]);
if( bsd != NULL ) {
- status->set_hp(&bsd->bl,hp,0); // Set hp
+ status->set_hp(&bsd->bl, hp, STATUS_HEAL_DEFAULT); // Set hp
if( (sc = status->get_sc(&bsd->bl)) != NULL && sc->data[SC_BANDING] ) {
sc->data[SC_BANDING]->val2 = c; // Set the counter. It doesn't count your self.
status_calc_bl(&bsd->bl, status->sc2scb_flag(SC_BANDING)); // Set atk and def.
@@ -523,10 +523,9 @@ static int pc_setrestartvalue(struct map_session_data *sd, int type)
if (type&1) {
//Normal resurrection
- st->hp = 1; //Otherwise status->heal may fail if dead.
- status->heal(&sd->bl, bst->hp, 0, 1);
+ status->heal(&sd->bl, bst->hp, 0, STATUS_HEAL_FORCED | STATUS_HEAL_ALLOWREVIVE);
if( st->sp < bst->sp )
- status->set_sp(&sd->bl, bst->sp, 1);
+ status->set_sp(&sd->bl, bst->sp, STATUS_HEAL_FORCED);
} else { //Just for saving on the char-server (with values as if respawned)
sd->status.hp = bst->hp;
sd->status.sp = (st->sp < bst->sp) ? bst->sp : st->sp;
@@ -8827,7 +8826,7 @@ static int pc_itemheal(struct map_session_data *sd, int itemid, int hp, int sp)
}
}
- return status->heal(&sd->bl, hp, sp, 1);
+ return status->heal(&sd->bl, hp, sp, STATUS_HEAL_FORCED);
}
/*==========================================
@@ -10878,7 +10877,7 @@ static void pc_regen(struct map_session_data *sd, unsigned int diff_tick)
}
if (hp > 0 || sp > 0)
- status->heal(&sd->bl, hp, sp, 0);
+ status->heal(&sd->bl, hp, sp, STATUS_HEAL_DEFAULT);
return;
}
diff --git a/src/map/script.c b/src/map/script.c
index 8c09bb8d8..41f21cd72 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -6855,7 +6855,7 @@ static BUILDIN(heal)
hp=script_getnum(st,2);
sp=script_getnum(st,3);
- status->heal(&sd->bl, hp, sp, 1);
+ status->heal(&sd->bl, hp, sp, STATUS_HEAL_FORCED);
return true;
}
/*==========================================
@@ -18781,7 +18781,7 @@ static BUILDIN(setunitdata)
md->level = val;
break;
case UDT_HP:
- status->set_hp(bl, (unsigned int) val, 0);
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
clif->charnameack(0, &md->bl);
break;
case UDT_MAXHP:
@@ -18789,7 +18789,7 @@ static BUILDIN(setunitdata)
clif->charnameack(0, &md->bl);
break;
case UDT_SP:
- status->set_sp(bl, (unsigned int) val, 0);
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXSP:
md->status.max_sp = (unsigned int) val;
@@ -18950,13 +18950,13 @@ static BUILDIN(setunitdata)
hd->homunculus.level = (short) val;
break;
case UDT_HP:
- status->set_hp(bl, (unsigned int) val, 0);
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXHP:
hd->homunculus.max_hp = val;
break;
case UDT_SP:
- status->set_sp(bl, (unsigned int) val, 0);
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXSP:
hd->homunculus.max_sp = val;
@@ -19089,13 +19089,13 @@ static BUILDIN(setunitdata)
pd->pet.level = (short) val;
break;
case UDT_HP:
- status->set_hp(bl, (unsigned int) val, 0);
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXHP:
pd->status.max_hp = (unsigned int) val;
break;
case UDT_SP:
- status->set_sp(bl, (unsigned int) val, 0);
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXSP:
pd->status.max_sp = (unsigned int) val;
@@ -19223,13 +19223,13 @@ static BUILDIN(setunitdata)
mc->base_status.size = (unsigned char) val;
break;
case UDT_HP:
- status->set_hp(bl, (unsigned int) val, 0);
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXHP:
mc->base_status.max_hp = (unsigned int) val;
break;
case UDT_SP:
- status->set_sp(bl, (unsigned int) val, 0);
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXSP:
mc->base_status.max_sp = (unsigned int) val;
@@ -19357,13 +19357,13 @@ static BUILDIN(setunitdata)
ed->base_status.size = (unsigned char) val;
break;
case UDT_HP:
- status->set_hp(bl, (unsigned int) val, 0);
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXHP:
ed->base_status.max_hp = (unsigned int) val;
break;
case UDT_SP:
- status->set_sp(bl, (unsigned int) val, 0);
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXSP:
ed->base_status.max_sp = (unsigned int) val;
@@ -19489,13 +19489,13 @@ static BUILDIN(setunitdata)
nd->level = (unsigned short) val;
break;
case UDT_HP:
- status->set_hp(bl, (unsigned int) val, 0);
+ status->set_hp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXHP:
nd->status.max_hp = (unsigned int) val;
break;
case UDT_SP:
- status->set_sp(bl, (unsigned int) val, 0);
+ status->set_sp(bl, (unsigned int) val, STATUS_HEAL_DEFAULT);
break;
case UDT_MAXSP:
nd->status.max_sp = (unsigned int) val;
@@ -20806,7 +20806,7 @@ static BUILDIN(mercenary_heal)
hp = script_getnum(st,2);
sp = script_getnum(st,3);
- status->heal(&sd->md->bl, hp, sp, 0);
+ status->heal(&sd->md->bl, hp, sp, STATUS_HEAL_DEFAULT);
return true;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 9857badbe..8410a77d0 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2361,11 +2361,11 @@ static int skill_counter_additional_effect(struct block_list *src, struct block_
) {
// Soul Drain should only work on targeted spells [Skotlex]
if( pc_issit(sd) ) pc->setstand(sd); // Character stuck in attacking animation while 'sitting' fix. [Skotlex]
- if( skill->get_nk(skill_id)&NK_SPLASH && skill->area_temp[1] != bl->id )
+ if (skill->get_nk(skill_id)&NK_SPLASH && skill->area_temp[1] != bl->id) {
;
- else {
+ } else {
clif->skill_nodamage(src,bl,HW_SOULDRAIN,rate,1);
- status->heal(src, 0, status->get_lv(bl)*(95+15*rate)/100, 2);
+ status->heal(src, 0, status->get_lv(bl)*(95+15*rate)/100, STATUS_HEAL_SHOWEFFECT);
}
}
@@ -2388,9 +2388,9 @@ static int skill_counter_additional_effect(struct block_list *src, struct block_
sc->data[SC_SOULLINK]->val3 = 0; //Clear bounced spell check.
}
}
- if( hp || sp ) {
+ if (hp != 0 || sp != 0) {
// updated to force healing to allow healing through berserk
- status->heal(src, hp, sp, battle_config.show_hp_sp_gain ? 3 : 1);
+ status->heal(src, hp, sp, STATUS_HEAL_FORCED | (battle_config.show_hp_sp_gain ? STATUS_HEAL_SHOWEFFECT : STATUS_HEAL_DEFAULT));
}
}
@@ -2899,7 +2899,7 @@ static int skill_attack(int attack_type, struct block_list *src, struct block_li
sp = sp * sc->data[SC_MAGICROD]->val2 / 100;
if(skill_id == WZ_WATERBALL && skill_lv > 1)
sp = sp/((skill_lv|1)*(skill_lv|1)); //Estimate SP cost of a single water-ball
- status->heal(bl, 0, sp, 2);
+ status->heal(bl, 0, sp, STATUS_HEAL_SHOWEFFECT);
}
}
@@ -4477,7 +4477,7 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl
if( skill_id == MO_EXTREMITYFIST ) {
mbl = src;
i = 3; // for Asura(from caster)
- status->set_sp(src, 0, 0);
+ status->set_sp(src, 0, STATUS_HEAL_DEFAULT);
status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
#ifdef RENEWAL
@@ -4487,9 +4487,9 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl
status_change_end(src, SC_NJ_NEN, INVALID_TIMER);
status_change_end(src, SC_HIDING, INVALID_TIMER);
#ifdef RENEWAL
- status->set_hp(src, max(status_get_max_hp(src)/100, 1), 0);
+ status->set_hp(src, max(status_get_max_hp(src)/100, 1), STATUS_HEAL_DEFAULT);
#else // not RENEWAL
- status->set_hp(src, 1, 0);
+ status->set_hp(src, 1, STATUS_HEAL_DEFAULT);
#endif // RENEWAL
}
dir = map->calc_dir(src,bl->x,bl->y);
@@ -4603,7 +4603,7 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl
heal = skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, sflag);
if (skill_id == NPC_VAMPIRE_GIFT && heal > 0) {
clif->skill_nodamage(NULL, src, AL_HEAL, heal, 1);
- status->heal(src,heal,0,0);
+ status->heal(src, heal, 0, STATUS_HEAL_DEFAULT);
}
if (skill_id == SU_SCRATCH && status->get_lv(src) >= 30 && (rnd() % 100 < (int)(status->get_lv(src) / 30) + 10)) // TODO: Need activation chance.
skill->addtimerskill(src, tick + skill->get_delay(skill_id, skill_lv), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag);
@@ -4971,7 +4971,7 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl
src, src, bl, skill_id, skill_lv, tick, flag);
if (heal > 0){
clif->skill_nodamage(NULL, src, AL_HEAL, heal, 1);
- status->heal(src, heal, 0, 0);
+ status->heal(src, heal, 0, STATUS_HEAL_DEFAULT);
}
}
break;
@@ -5082,7 +5082,7 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl
heal = 0; // Don't absorb heal from Ice Walls or other skill units.
if( heal && rnd()%100 < rate ) {
- status->heal(src, heal, 0, 0);
+ status->heal(src, heal, 0, STATUS_HEAL_DEFAULT);
clif->skill_nodamage(NULL, src, AL_HEAL, heal, 1);
}
}
@@ -5843,7 +5843,7 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data)
//When Asura fails... (except when it fails from Fog of Wall)
//Consume SP/spheres
skill->consume_requirement(sd,ud->skill_id, ud->skill_lv,1);
- status->set_sp(src, 0, 0);
+ status->set_sp(src, 0, STATUS_HEAL_DEFAULT);
sc = &sd->sc;
if (sc->count) {
//End states
@@ -6126,7 +6126,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
clif->skill_nodamage (src, bl, skill_id, heal, 1);
if( tsc && tsc->data[SC_AKAITSUKI] && heal && skill_id != HLIF_HEAL )
heal = ~heal + 1;
- heal_get_jobexp = status->heal(bl,heal,0,0);
+ heal_get_jobexp = status->heal(bl, heal, 0, STATUS_HEAL_DEFAULT);
if(sd && dstsd && heal > 0 && sd != dstsd && battle_config.heal_exp > 0){
heal_get_jobexp = heal_get_jobexp * battle_config.heal_exp / 100;
@@ -6159,8 +6159,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
clif->updatestatus(sd,SP_BASEEXP);
clif->updatestatus(sd,SP_JOBEXP);
}
- status->set_hp(src, 1, 0);
- status->set_sp(src, 0, 0);
+ status->set_hp(src, 1, STATUS_HEAL_DEFAULT);
+ status->set_sp(src, 0, STATUS_HEAL_DEFAULT);
break;
} else if (status->isdead(bl) && flag&1) { //Revive
skill->area_temp[0]++; //Count it in, then fall-through to the Resurrection code.
@@ -6333,7 +6333,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
break;
case SA_INSTANTDEATH:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- status->set_hp(bl,1,0);
+ status->set_hp(bl, 1, STATUS_HEAL_DEFAULT);
break;
case SA_QUESTION:
case SA_GRAVITY:
@@ -6911,7 +6911,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
if (dstsd && dstsd->charm_type != CHARM_TYPE_NONE && dstsd->charm_count > 0) {
pc->del_charm(dstsd, dstsd->charm_count, dstsd->charm_type);
}
- if (sp) status->heal(src, 0, sp, 3);
+ if (sp != 0)
+ status->heal(src, 0, sp, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
clif->skill_nodamage(src,bl,skill_id,skill_lv,sp?1:0);
}
break;
@@ -7273,7 +7274,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
case NV_FIRSTAID:
clif->skill_nodamage(src,bl,skill_id,5,1);
- status->heal(bl,5,0,0);
+ status->heal(bl, 5, 0, STATUS_HEAL_DEFAULT);
break;
case AL_CURE:
@@ -7350,7 +7351,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
case MER_SCAPEGOAT:
if( mer && mer->master ) {
- status->heal(&mer->master->bl, mer->battle_status.hp, 0, 2);
+ status->heal(&mer->master->bl, mer->battle_status.hp, 0, STATUS_HEAL_SHOWEFFECT);
status->damage(src, src, mer->battle_status.max_hp, 0, 0, 1);
}
break;
@@ -7667,7 +7668,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
if( tsc && tsc->data[SC_EXTREMITYFIST2] )
sp = 0;
#endif
- status->heal(bl,(int)hp,sp,0);
+ status->heal(bl, (int)hp, sp, STATUS_HEAL_DEFAULT);
}
break;
case AM_CP_WEAPON:
@@ -7842,7 +7843,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
sp = skill->get_sp(skill_id,skill_lv);
sp = sp * tsc->data[SC_MAGICROD]->val2 / 100;
if(sp < 1) sp = 1;
- status->heal(bl,0,sp,2);
+ status->heal(bl, 0, sp, STATUS_HEAL_SHOWEFFECT);
status_percent_damage(bl, src, 0, -20, false); //20% max SP damage.
} else {
struct unit_data *ud = unit->bl2ud(bl);
@@ -7874,8 +7875,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
if (sp) //Recover some of the SP used
sp = sp*(25*(skill_lv-1))/100;
- if(hp || sp)
- status->heal(src, hp, sp, 2);
+ if (hp != 0 || sp != 0)
+ status->heal(src, hp, sp, STATUS_HEAL_SHOWEFFECT);
}
}
break;
@@ -8118,14 +8119,14 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
{
int hp_rate = skill_lv == 0 ? 0 : skill->get_hp_rate(skill_id, skill_lv);
int gain_hp = tstatus->max_hp*abs(hp_rate)/100; // The earned is the same % of the target HP than it cost the caster. [Skotlex]
- clif->skill_nodamage(src,bl,skill_id,status->heal(bl, gain_hp, 0, 0),1);
+ clif->skill_nodamage(src, bl, skill_id, status->heal(bl, gain_hp, 0, STATUS_HEAL_DEFAULT), 1);
}
break;
case WE_FEMALE:
{
int sp_rate = skill_lv == 0 ? 0 : skill->get_sp_rate(skill_id, skill_lv);
int gain_sp = tstatus->max_sp*abs(sp_rate)/100;// The earned is the same % of the target SP than it cost the caster. [Skotlex]
- clif->skill_nodamage(src,bl,skill_id,status->heal(bl, 0, gain_sp, 0),1);
+ clif->skill_nodamage(src, bl, skill_id, status->heal(bl, 0, gain_sp, STATUS_HEAL_DEFAULT), 1);
}
break;
@@ -8165,7 +8166,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
break;
}
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
- status->heal(bl,0,sp,2);
+ status->heal(bl, 0, sp, STATUS_HEAL_SHOWEFFECT);
}
break;
@@ -8320,7 +8321,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
}
dstmd->state.soul_change_flag = 1;
sp2 = sstatus->max_sp * 3 /100;
- status->heal(src, 0, sp2, 2);
+ status->heal(src, 0, sp2, STATUS_HEAL_SHOWEFFECT);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
}
@@ -8332,8 +8333,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
if( tsc && tsc->data[SC_EXTREMITYFIST2] )
sp1 = tstatus->sp;
#endif // RENEWAL
- status->set_sp(src, sp2, 3);
- status->set_sp(bl, sp1, 3);
+ status->set_sp(src, sp2, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
+ status->set_sp(bl, sp1, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
}
break;
@@ -8371,7 +8372,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
clif->skill_nodamage(NULL,bl,AL_HEAL,hp,1);
if(sp > 0)
clif->skill_nodamage(NULL,bl,MG_SRECOVERY,sp,1);
- status->heal(bl,hp,sp,0);
+ status->heal(bl, hp, sp, STATUS_HEAL_DEFAULT);
}
break;
// Full Chemical Protection
@@ -8460,7 +8461,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
sc_start(src,bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
break;
case 5: // 2000HP heal, random teleported
- status->heal(src, 2000, 0, 0);
+ status->heal(src, 2000, 0, STATUS_HEAL_DEFAULT);
if( !map_flag_vs(bl->m) )
unit->warp(bl, -1,-1,-1, CLR_TELEPORT);
break;
@@ -8754,7 +8755,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
//Eh? why double skill packet?
clif->skill_nodamage(src,bl,AL_HEAL,hp,1);
clif->skill_nodamage(src,bl,skill_id,hp,1);
- status->heal(bl, hp, 0, 0);
+ status->heal(bl, hp, 0, STATUS_HEAL_DEFAULT);
}
break;
// Homun single-target support skills [orn]
@@ -8901,7 +8902,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
int heal = status_get_max_hp(bl) * 25 / 100;
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- status->heal(bl,heal,0,1);
+ status->heal(bl, heal, 0, STATUS_HEAL_FORCED);
status->change_clear_buffs(bl,4);
}
break;
@@ -8955,7 +8956,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
value = status_get_max_hp(bl) * 25 / 100;
status->change_clear_buffs(bl,4);
skill->area_temp[5] &= ~0x20;
- status->heal(bl,value,0,1);
+ status->heal(bl, value, 0, STATUS_HEAL_FORCED);
type = SC_REFRESH;
}else if( skill->area_temp[5]&0x40 ){
skill->area_temp[5] &= ~0x40;
@@ -9140,7 +9141,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
clif->skill_nodamage(bl, bl, skill_id, heal, 1);
if( tsc && tsc->data[SC_AKAITSUKI] && heal )
heal = ~heal + 1;
- status->heal(bl, heal, 0, 1);
+ status->heal(bl, heal, 0, STATUS_HEAL_FORCED);
}
} else if( sd )
party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
@@ -9416,7 +9417,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
pc->setmadogear(sd, false);
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
skill->castend_damage_id(src, src, skill_id, skill_lv, tick, flag);
- status->set_sp(src, 0, 0);
+ status->set_sp(src, 0, STATUS_HEAL_DEFAULT);
}
break;
@@ -9455,7 +9456,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
case 5: hp = 23; break;
}
heal = tstatus->max_hp * hp / 100;
- status->heal(bl,heal,0,2);
+ status->heal(bl, heal, 0, STATUS_HEAL_SHOWEFFECT);
clif->skill_nodamage(src, bl, skill_id, skill_lv, heal);
}
break;
@@ -9533,7 +9534,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
int sp = 100 * skill_lv;
if( dstmd ) sp = dstmd->level * 2;
if( status_zap(bl,0,sp) )
- status->heal(src,0,sp/2,3);//What does flag 3 do? [Rytech]
+ status->heal(src, 0, sp / 2, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
}
if ( tsc && tsc->data[SC__UNLUCKY] && skill_id == SC_UNLUCKY) {
//If the target was successfully inflected with the Unlucky status, give 1 of 3 random status's.
@@ -9657,7 +9658,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
case 3:
sc_start(src, bl, SC_SHIELDSPELL_REF, 100, opt, INFINITE_DURATION); // HP Recovery
val = sstatus->max_hp * ((status->get_lv(src) / 10) + (shield->refine + 1)) / 100;
- status->heal(bl, val, 0, 2);
+ status->heal(bl, val, 0, STATUS_HEAL_SHOWEFFECT);
status_change_end(bl,SC_SHIELDSPELL_REF,INVALID_TIMER);
break;
}
@@ -9800,7 +9801,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
}
heal = 120 * skill_lv + status_get_max_hp(bl) * (2 + skill_lv) / 100;
- status->heal(bl, heal, 0, 0);
+ status->heal(bl, heal, 0, STATUS_HEAL_DEFAULT);
if( (tsc && tsc->opt1) && (rnd()%100 < ((skill_lv * 5) + (status_get_dex(src) + status->get_lv(src)) / 4) - (1 + (rnd() % 10))) ) {
status_change_end(bl, SC_STONE, INVALID_TIMER);
@@ -9871,7 +9872,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
heal = 1;
status->fixed_revive(bl, heal, 0);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- status->set_sp(bl, 0, 0);
+ status->set_sp(bl, 0, STATUS_HEAL_DEFAULT);
}
}
break;
@@ -10208,7 +10209,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
}
e_hp = ed->battle_status.max_hp * 10 / 100;
e_sp = ed->battle_status.max_sp * 10 / 100;
- status->heal(&ed->bl,e_hp,e_sp,3);
+ status->heal(&ed->bl, e_hp, e_sp, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
clif->skill_nodamage(src,&ed->bl,skill_id,skill_lv,1);
}
break;
@@ -10518,7 +10519,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
}
}
heal = 5 * status->get_lv(&hd->bl) + status->base_matk(&hd->bl, &hd->battle_status, status->get_lv(&hd->bl));
- status->heal(bl, heal, 0, 0);
+ status->heal(bl, heal, 0, STATUS_HEAL_DEFAULT);
clif->skill_nodamage(src, src, skill_id, skill_lv, clif->skill_nodamage(src, bl, AL_HEAL, heal, 1));
status->change_start(src, src, type, 1000, skill_lv, 0, 0, 0, skill->get_time(skill_id,skill_lv), SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
status->change_start(src, bl, type, 1000, skill_lv, 0, 0, 0, skill->get_time(skill_id,skill_lv), SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
@@ -12800,7 +12801,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b
clif->skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
if (tsc && tsc->data[SC_AKAITSUKI] && heal)
heal = ~heal + 1;
- status->heal(bl, heal, 0, 0);
+ status->heal(bl, heal, 0, STATUS_HEAL_DEFAULT);
if (diff >= 500)
sg->val1--;
}
@@ -12821,7 +12822,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b
if (status->isimmune(bl))
heal = 0;
clif->skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
- status->heal(bl, heal, 0, 0);
+ status->heal(bl, heal, 0, STATUS_HEAL_DEFAULT);
}
break;
@@ -13032,7 +13033,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b
if( tsc && tsc->data[SC_AKAITSUKI] && heal )
heal = ~heal + 1;
clif->skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
- status->heal(bl, heal, 0, 0);
+ status->heal(bl, heal, 0, STATUS_HEAL_DEFAULT);
}
}
break;
@@ -13086,7 +13087,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b
case 0: // Heal 1~9999 HP
heal = rnd() %9999+1;
clif->skill_nodamage(ss,bl,AL_HEAL,heal,1);
- status->heal(bl,heal,0,0);
+ status->heal(bl, heal, 0, STATUS_HEAL_DEFAULT);
break;
case 1: // End all negative status
status->change_clear_buffs(bl,2);
@@ -13231,7 +13232,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b
}
hp = tstatus->max_hp * hp / 100;
sp = tstatus->max_sp * sp / 100;
- status->heal(bl, hp, sp, 2);
+ status->heal(bl, hp, sp, STATUS_HEAL_SHOWEFFECT);
sc_start(ss, bl, type, 100, sg->skill_lv, (sg->interval * 3) + 100);
}
// Reveal hidden players every 5 seconds.
@@ -13353,7 +13354,7 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b
clif->skill_nodamage(&src->bl, bl, AL_HEAL, hp, 0);
if( tsc && tsc->data[SC_AKAITSUKI] && hp )
hp = ~hp + 1;
- status->heal(bl, hp, 0, 0);
+ status->heal(bl, hp, 0, STATUS_HEAL_DEFAULT);
sc_start(ss, bl, type, 100, sg->skill_lv, sg->interval + 100);
}
break;
@@ -13367,13 +13368,13 @@ static int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *b
int hp = tstatus->max_hp / 100; //+1% each 5s
if ((sg->val3) % 5) { //each 5s
if (tstatus->def_ele == skill->get_ele(sg->skill_id,sg->skill_lv)) {
- status->heal(bl, hp, 0, 2);
+ status->heal(bl, hp, 0, STATUS_HEAL_SHOWEFFECT);
} else if( (sg->unit_id == UNT_FIRE_INSIGNIA && tstatus->def_ele == ELE_EARTH)
|| (sg->unit_id == UNT_WATER_INSIGNIA && tstatus->def_ele == ELE_FIRE)
|| (sg->unit_id == UNT_WIND_INSIGNIA && tstatus->def_ele == ELE_WATER)
|| (sg->unit_id == UNT_EARTH_INSIGNIA && tstatus->def_ele == ELE_WIND)
) {
- status->heal(bl, -hp, 0, 0);
+ status->heal(bl, -hp, 0, STATUS_HEAL_DEFAULT);
}
}
sg->val3++; //timer
diff --git a/src/map/status.c b/src/map/status.c
index 370432ce7..edcdd515d 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -1240,10 +1240,15 @@ static void status_copy(struct status_data *a, const struct status_data *b)
memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
}
-//Sets HP to given value. Flag is the flag passed to status->heal in case
-//final value is higher than current (use 2 to make a healing effect display
-//on players) It will always succeed (overrides Berserk block), but it can't kill.
-static int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
+/**
+ * Sets HP to the given value.
+ *
+ * @param bl The target unit.
+ * @param hp The desired HP value.
+ * @param flag Additional options. @see enum status_heal_flag. STATUS_HEAL_FORCED is always implied.
+ * @return The amount of HP gained.
+ */
+static int status_set_hp(struct block_list *bl, unsigned int hp, enum status_heal_flag flag)
{
struct status_data *st;
if (hp < 1) return 0;
@@ -1254,14 +1259,19 @@ static int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
if (hp > st->max_hp) hp = st->max_hp;
if (hp == st->hp) return 0;
if (hp > st->hp)
- return status->heal(bl, hp - st->hp, 0, 1|flag);
+ return status->heal(bl, hp - st->hp, 0, STATUS_HEAL_FORCED | flag);
return status_zap(bl, st->hp - hp, 0);
}
-//Sets SP to given value. Flag is the flag passed to status->heal in case
-//final value is higher than current (use 2 to make a healing effect display
-//on players)
-static int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
+/**
+ * Sets SP to the given value.
+ *
+ * @param bl The target unit.
+ * @param hp The desired SP value.
+ * @param flag Additional options. @see enum status_heal_flag. STATUS_HEAL_FORCED is always implied.
+ * @return The amount of SP gained.
+ */
+static int status_set_sp(struct block_list *bl, unsigned int sp, enum status_heal_flag flag)
{
struct status_data *st;
@@ -1272,7 +1282,7 @@ static int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
if (sp > st->max_sp) sp = st->max_sp;
if (sp == st->sp) return 0;
if (sp > st->sp)
- return status->heal(bl, 0, sp - st->sp, 1|flag);
+ return status->heal(bl, 0, sp - st->sp, STATUS_HEAL_FORCED | flag);
return status_zap(bl, 0, st->sp - sp);
}
@@ -1304,12 +1314,12 @@ static int status_damage(struct block_list *src, struct block_list *target, int6
sp = 0; //Not a valid SP target.
if (hp < 0) { //Assume absorbed damage.
- status->heal(target, -hp, 0, 1);
+ status->heal(target, -hp, 0, STATUS_HEAL_FORCED);
hp = 0;
}
if (sp < 0) {
- status->heal(target, 0, -sp, 1);
+ status->heal(target, 0, -sp, STATUS_HEAL_FORCED);
sp = 0;
}
@@ -1527,9 +1537,16 @@ static int status_damage(struct block_list *src, struct block_list *target, int6
return (int)(hp+sp);
}
-//Heals a character. If flag&1, this is forced healing (otherwise stuff like Berserk can block it)
-//If flag&2, when the player is healed, show the HP/SP heal effect.
-static int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag)
+/**
+ * Heals a character.
+ *
+ * @param bl The target unit.
+ * @param in_hp Amount of HP to recover.
+ * @param in_sp Amount of SP to recover.
+ * @param flag Additional options, @see enum status_heal_flag.
+ * @return The amount of HP + SP healed.
+ */
+static int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, enum status_heal_flag flag)
{
struct status_data *st;
struct status_change *sc;
@@ -1538,7 +1555,9 @@ static int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag
nullpo_ret(bl);
st = status->get_status_data(bl);
- if (st == &status->dummy || !st->hp)
+ if (st == &status->dummy)
+ return 0;
+ if (st->hp == 0 && (flag & STATUS_HEAL_ALLOWREVIVE) != 0)
return 0;
/* From here onwards, we consider it a 32-type as the client does not support higher and the value doesn't get through percentage modifiers */
@@ -1555,10 +1574,10 @@ static int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag
hp = 0;
}
- if(hp) {
- if( sc && sc->data[SC_BERSERK] ) {
- if( flag&1 )
- flag &= ~2;
+ if (hp != 0) {
+ if (sc && sc->data[SC_BERSERK] != NULL) {
+ if ((flag & STATUS_HEAL_FORCED) != 0)
+ flag &= ~STATUS_HEAL_SHOWEFFECT;
else
hp = 0;
}
@@ -1593,7 +1612,7 @@ static int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag
// send hp update to client
switch(bl->type) {
- case BL_PC: pc->heal(BL_UCAST(BL_PC, bl), hp, sp, (flag&2) ? 1 : 0); break;
+ case BL_PC: pc->heal(BL_UCAST(BL_PC, bl), hp, sp, (flag & STATUS_HEAL_SHOWEFFECT) != 0 ? 1 : 0); break;
case BL_MOB: mob->heal(BL_UCAST(BL_MOB, bl), hp); break;
case BL_HOM: homun->healed(BL_UCAST(BL_HOM, bl)); break;
case BL_MER: mercenary->heal(BL_UCAST(BL_MER, bl), hp, sp); break;
@@ -1648,18 +1667,18 @@ static int status_percent_change(struct block_list *src, struct block_list *targ
if (flag)
status->damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1));
else
- status->heal(target, INT_MAX, 0, 0);
+ status->heal(target, INT_MAX, 0, STATUS_HEAL_DEFAULT);
}
if (sp > INT_MAX) {
sp -= INT_MAX;
if (flag)
status->damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1));
else
- status->heal(target, 0, INT_MAX, 0);
+ status->heal(target, 0, INT_MAX, STATUS_HEAL_DEFAULT);
}
if (flag)
return status->damage(src, target, hp, sp, 0, (!src||src==target?5:1));
- return status->heal(target, hp, sp, 0);
+ return status->heal(target, hp, sp, STATUS_HEAL_DEFAULT);
}
static int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp)
@@ -2330,6 +2349,51 @@ static unsigned int status_get_base_maxhp(const struct map_session_data *sd, con
return (unsigned int)cap_value(val,0,UINT_MAX);
}
+/**
+ * Calculates the HP that a character will have after death, on respawn.
+ *
+ * @param sd The character to calculate.
+ * @param st The character's status data.
+ */
+static unsigned int status_get_restart_hp(const struct map_session_data *sd, const struct status_data *st)
+{
+ unsigned int hp = 0;
+
+ if (sd->special_state.restart_full_recover)
+ return st->max_hp;
+
+ if ((sd->job & MAPID_BASEMASK) == MAPID_NOVICE && (sd->job & JOBL_2) == 0 && battle_config.restart_hp_rate < 50)
+ hp = st->max_hp / 2;
+ else
+ hp = APPLY_RATE(st->max_hp, battle_config.restart_hp_rate);
+
+ if (hp > 0)
+ return hp;
+
+ return 1;
+}
+
+/**
+ * Calculates the SP that a character will have after death, on respawn.
+ *
+ * @param sd The character to calculate.
+ * @param st The character's status data.
+ */
+static unsigned int status_get_restart_sp(const struct map_session_data *sd, const struct status_data *st)
+{
+ unsigned int sp = 0;
+
+ if (sd->special_state.restart_full_recover)
+ return st->max_sp;
+
+ sp = APPLY_RATE(st->max_sp, battle_config.restart_sp_rate);
+
+ if (sp > 0)
+ return sp;
+
+ return 1; // the minimum for the respawn setting is SP:1
+}
+
static void status_calc_pc_additional(struct map_session_data *sd, enum e_status_calc_opt opt)
{
/* Just used for Plugin to give bonuses. */
@@ -2884,20 +2948,8 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o
// ----- RESPAWN HP/SP -----
//
//Calc respawn hp and store it on base_status
- if (sd->special_state.restart_full_recover)
- {
- bstatus->hp = bstatus->max_hp;
- bstatus->sp = bstatus->max_sp;
- } else {
- status->calc_pc_recover_hp(sd, bstatus);
- if(!bstatus->hp)
- bstatus->hp = 1;
-
- bstatus->sp = APPLY_RATE(bstatus->max_sp, battle_config.restart_sp_rate);
-
- if( !bstatus->sp ) /* the minimum for the respawn setting is SP:1 */
- bstatus->sp = 1;
- }
+ bstatus->hp = status->get_restart_hp(sd, bstatus);
+ bstatus->sp = status->get_restart_sp(sd, bstatus);
// ----- MISC CALCULATION -----
status->calc_misc(&sd->bl, bstatus, sd->status.base_level);
@@ -9410,10 +9462,10 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
return 0;
PER( 100 / (status_get_max_hp(bl) / hp), lv );
- status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, 1);
+ status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, STATUS_HEAL_FORCED);
PER( 100 / (status_get_max_sp(bl) / sp), lv );
- status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), 1);
+ status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), STATUS_HEAL_FORCED);
}
#undef PER
break;
@@ -9646,8 +9698,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en
switch (type) {
case SC_BERSERK:
if (!(sce->val2)) { //don't heal if already set
- status->heal(bl, st->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
- status->set_sp(bl, 0, 0); //Damage all SP
+ status->heal(bl, st->max_hp, 0, STATUS_HEAL_FORCED); //Do not use percent_heal as this healing must override BERSERK's block.
+ status->set_sp(bl, 0, STATUS_HEAL_DEFAULT); //Damage all SP
}
sce->val2 = 5 * st->max_hp / 100;
break;
@@ -10973,7 +11025,7 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
status_percent_heal(bl, 100, 0);
status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER);
} else if(st->hp > 100 && sce->val2) //If val2 is removed, no HP penalty (dispelled?) [Skotlex]
- status->set_hp(bl, 100, 0);
+ status->set_hp(bl, 100, STATUS_HEAL_DEFAULT);
if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) {
sc->data[SC_ENDURE]->val4 = 0;
status_change_end(bl, SC_ENDURE, INVALID_TIMER);
@@ -11025,8 +11077,8 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid,
if (tid == INVALID_TIMER)
break;
// "lose almost all their HP and SP" on natural expiration.
- status->set_hp(bl, 10, 0);
- status->set_sp(bl, 10, 0);
+ status->set_hp(bl, 10, STATUS_HEAL_DEFAULT);
+ status->set_sp(bl, 10, STATUS_HEAL_DEFAULT);
break;
case SC_AUTOTRADE:
if (tid == INVALID_TIMER)
@@ -11437,8 +11489,8 @@ static int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data)
hp = st->max_hp - st->hp;
if (hp > sce->val2)
hp = sce->val2;
- if (hp)
- status->heal(bl, hp, 0, 2);
+ if (hp != 0)
+ status->heal(bl, hp, 0, STATUS_HEAL_SHOWEFFECT);
sce->val4 = INVALID_TIMER;
return 1;
}
@@ -11644,7 +11696,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
int hp = 0;
if (st->hp < st->max_hp)
hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ;
- status->heal(bl, hp, 0, 2);
+ status->heal(bl, hp, 0, STATUS_HEAL_SHOWEFFECT);
sc_timer_next((sce->val2 * 1000) + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11793,7 +11845,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
break;
case SC_ABUNDANCE:
if(--(sce->val4) > 0) {
- status->heal(bl,0,60,0);
+ status->heal(bl, 0, 60, STATUS_HEAL_DEFAULT);
sc_timer_next(10000+tick, status->change_timer, bl->id, data);
}
break;
@@ -11909,7 +11961,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
heal = ~heal + 1;
map->freeblock_lock();
- status->heal(bl, heal, 0, 2);
+ status->heal(bl, heal, 0, STATUS_HEAL_SHOWEFFECT);
if( sc->data[type] ) {
sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
}
@@ -12032,7 +12084,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
if ( sc->data[type] ) {
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
}
- status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level
+ status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, STATUS_HEAL_DEFAULT); // 5 + 5% per level
map->freeblock_unlock();
return 0;
}
@@ -12049,7 +12101,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
case SC_DEEP_SLEEP:
if( --(sce->val4) >= 0 )
{// Recovers 3% of the player's MaxHP/MaxSP every 2 seconds.
- status->heal(bl, st->max_hp * 3 / 100, st->max_sp * 3 / 100, 2);
+ status->heal(bl, st->max_hp * 3 / 100, st->max_sp * 3 / 100, STATUS_HEAL_SHOWEFFECT);
sc_timer_next(2000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -12059,7 +12111,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
if( --(sce->val4) >= 0 ) {
if( !status->charge(bl,0,sce->val3) )
break;
- status->heal(bl, sce->val2, 0, 1);
+ status->heal(bl, sce->val2, 0, STATUS_HEAL_FORCED);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -12067,7 +12119,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
case SC_SONG_OF_MANA:
if( --(sce->val4) >= 0 ) {
- status->heal(bl,0,sce->val3,3);
+ status->heal(bl, 0, sce->val3, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -12261,7 +12313,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
return 0;
case SC_MEIKYOUSISUI:
if( --(sce->val4) > 0 ) {
- status->heal(bl, st->max_hp * (sce->val1+1) / 100, st->max_sp * sce->val1 / 100, 0);
+ status->heal(bl, st->max_hp * (sce->val1+1) / 100, st->max_sp * sce->val1 / 100, STATUS_HEAL_DEFAULT);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -12297,7 +12349,7 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
break;
case SC_FRIGG_SONG:
if( --(sce->val4) > 0 ) {
- status->heal(bl, sce->val3, 0, 0);
+ status->heal(bl, sce->val3, 0, STATUS_HEAL_DEFAULT);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -12879,7 +12931,7 @@ static int status_natural_heal(struct block_list *bl, va_list args)
sregen->tick.hp += val;
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, sregen->hp, 0, 3) < sregen->hp) {
+ if (status->heal(bl, sregen->hp, 0, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->hp) {
//Full
flag&=~(RGN_HP|RGN_SHP);
break;
@@ -12894,7 +12946,7 @@ static int status_natural_heal(struct block_list *bl, va_list args)
sregen->tick.sp += val;
while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.sp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, 0, sregen->sp, 3) < sregen->sp) {
+ if (status->heal(bl, 0, sregen->sp, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->sp) {
//Full
flag&=~(RGN_SP|RGN_SSP);
break;
@@ -12943,7 +12995,7 @@ static int status_natural_heal(struct block_list *bl, va_list args)
val += regen->hp;
regen->tick.hp -= battle_config.natural_healhp_interval;
} while(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval);
- if (status->heal(bl, val, 0, 1) < val)
+ if (status->heal(bl, val, 0, STATUS_HEAL_FORCED) < val)
flag&=~RGN_SHP; //full.
}
}
@@ -12962,7 +13014,7 @@ static int status_natural_heal(struct block_list *bl, va_list args)
val += regen->sp;
regen->tick.sp -= battle_config.natural_healsp_interval;
} while(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval);
- if (status->heal(bl, 0, val, 1) < val)
+ if (status->heal(bl, 0, val, STATUS_HEAL_FORCED) < val)
flag&=~RGN_SSP; //full.
}
}
@@ -12979,7 +13031,7 @@ static int status_natural_heal(struct block_list *bl, va_list args)
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, sregen->hp, 0, 3) < sregen->hp)
+ if (status->heal(bl, sregen->hp, 0, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->hp)
break; //Full
}
}
@@ -13004,7 +13056,7 @@ static int status_natural_heal(struct block_list *bl, va_list args)
}
}
sregen->tick.sp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, 0, val, 3) < val)
+ if (status->heal(bl, 0, val, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < val)
break; //Full
}
}
@@ -13729,6 +13781,8 @@ void status_defaults(void)
status->base_atk = status_base_atk;
status->get_base_maxhp = status_get_base_maxhp;
status->get_base_maxsp = status_get_base_maxsp;
+ status->get_restart_hp = status_get_restart_hp;
+ status->get_restart_sp = status_get_restart_sp;
status->calc_npc_ = status_calc_npc_;
status->calc_str = status_calc_str;
status->calc_agi = status_calc_agi;
diff --git a/src/map/status.h b/src/map/status.h
index 6305d00d9..17af22703 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -99,6 +99,16 @@ enum scstart_flag {
SCFLAG_ALL = SCFLAG_NONE|SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_LOADED|SCFLAG_FIXEDRATE|SCFLAG_NOICON
};
+/**
+ * Flags to be used with status->heal() and related functions.
+ */
+enum status_heal_flag {
+ STATUS_HEAL_DEFAULT = 0x00, ///< Default
+ STATUS_HEAL_FORCED = 0x01, ///< Forced healing (bypassing Berserk and similar)
+ STATUS_HEAL_SHOWEFFECT = 0x02, ///< Show the HP/SP heal effect
+ STATUS_HEAL_ALLOWREVIVE = 0x04, ///< Force resurrection in case of dead targets.
+};
+
// Status changes listing. These code are for use by the server.
typedef enum sc_type {
SC_NONE = -1,
@@ -2309,9 +2319,9 @@ struct status_interface {
int (*charge) (struct block_list* bl, int64 hp, int64 sp);
int (*percent_change) (struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag);
//Used to set the hp/sp of an object to an absolute value (can't kill)
- int (*set_hp) (struct block_list *bl, unsigned int hp, int flag);
- int (*set_sp) (struct block_list *bl, unsigned int sp, int flag);
- int (*heal) (struct block_list *bl,int64 hp,int64 sp, int flag);
+ int (*set_hp) (struct block_list *bl, unsigned int hp, enum status_heal_flag flag);
+ int (*set_sp) (struct block_list *bl, unsigned int sp, enum status_heal_flag flag);
+ int (*heal) (struct block_list *bl,int64 hp,int64 sp, enum status_heal_flag flag);
int (*revive) (struct block_list *bl, unsigned char per_hp, unsigned char per_sp);
int (*fixed_revive) (struct block_list *bl, unsigned int per_hp, unsigned int per_sp);
struct regen_data * (*get_regen_data) (struct block_list *bl);
@@ -2384,6 +2394,8 @@ struct status_interface {
unsigned short (*base_atk) (const struct block_list *bl, const struct status_data *st);
unsigned int (*get_base_maxhp) (const struct map_session_data *sd, const struct status_data *st);
unsigned int (*get_base_maxsp) (const struct map_session_data *sd, const struct status_data *st);
+ unsigned int (*get_restart_hp) (const struct map_session_data *sd, const struct status_data *st);
+ unsigned int (*get_restart_sp) (const struct map_session_data *sd, const struct status_data *st);
int (*calc_npc_) (struct npc_data *nd, enum e_status_calc_opt opt);
unsigned short (*calc_str) (struct block_list *bl, struct status_change *sc, int str);
unsigned short (*calc_agi) (struct block_list *bl, struct status_change *sc, int agi);
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 72387a8af..0a70f6d1a 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -7584,12 +7584,12 @@ typedef int (*HPMHOOK_pre_status_charge) (struct block_list **bl, int64 *hp, int
typedef int (*HPMHOOK_post_status_charge) (int retVal___, struct block_list *bl, int64 hp, int64 sp);
typedef int (*HPMHOOK_pre_status_percent_change) (struct block_list **src, struct block_list **target, signed char *hp_rate, signed char *sp_rate, int *flag);
typedef int (*HPMHOOK_post_status_percent_change) (int retVal___, struct block_list *src, struct block_list *target, signed char hp_rate, signed char sp_rate, int flag);
-typedef int (*HPMHOOK_pre_status_set_hp) (struct block_list **bl, unsigned int *hp, int *flag);
-typedef int (*HPMHOOK_post_status_set_hp) (int retVal___, struct block_list *bl, unsigned int hp, int flag);
-typedef int (*HPMHOOK_pre_status_set_sp) (struct block_list **bl, unsigned int *sp, int *flag);
-typedef int (*HPMHOOK_post_status_set_sp) (int retVal___, struct block_list *bl, unsigned int sp, int flag);
-typedef int (*HPMHOOK_pre_status_heal) (struct block_list **bl, int64 *hp, int64 *sp, int *flag);
-typedef int (*HPMHOOK_post_status_heal) (int retVal___, struct block_list *bl, int64 hp, int64 sp, int flag);
+typedef int (*HPMHOOK_pre_status_set_hp) (struct block_list **bl, unsigned int *hp, enum status_heal_flag *flag);
+typedef int (*HPMHOOK_post_status_set_hp) (int retVal___, struct block_list *bl, unsigned int hp, enum status_heal_flag flag);
+typedef int (*HPMHOOK_pre_status_set_sp) (struct block_list **bl, unsigned int *sp, enum status_heal_flag *flag);
+typedef int (*HPMHOOK_post_status_set_sp) (int retVal___, struct block_list *bl, unsigned int sp, enum status_heal_flag flag);
+typedef int (*HPMHOOK_pre_status_heal) (struct block_list **bl, int64 *hp, int64 *sp, enum status_heal_flag *flag);
+typedef int (*HPMHOOK_post_status_heal) (int retVal___, struct block_list *bl, int64 hp, int64 sp, enum status_heal_flag flag);
typedef int (*HPMHOOK_pre_status_revive) (struct block_list **bl, unsigned char *per_hp, unsigned char *per_sp);
typedef int (*HPMHOOK_post_status_revive) (int retVal___, struct block_list *bl, unsigned char per_hp, unsigned char per_sp);
typedef int (*HPMHOOK_pre_status_fixed_revive) (struct block_list **bl, unsigned int *per_hp, unsigned int *per_sp);
@@ -7732,6 +7732,10 @@ typedef unsigned int (*HPMHOOK_pre_status_get_base_maxhp) (const struct map_sess
typedef unsigned int (*HPMHOOK_post_status_get_base_maxhp) (unsigned int retVal___, const struct map_session_data *sd, const struct status_data *st);
typedef unsigned int (*HPMHOOK_pre_status_get_base_maxsp) (const struct map_session_data **sd, const struct status_data **st);
typedef unsigned int (*HPMHOOK_post_status_get_base_maxsp) (unsigned int retVal___, const struct map_session_data *sd, const struct status_data *st);
+typedef unsigned int (*HPMHOOK_pre_status_get_restart_hp) (const struct map_session_data **sd, const struct status_data **st);
+typedef unsigned int (*HPMHOOK_post_status_get_restart_hp) (unsigned int retVal___, const struct map_session_data *sd, const struct status_data *st);
+typedef unsigned int (*HPMHOOK_pre_status_get_restart_sp) (const struct map_session_data **sd, const struct status_data **st);
+typedef unsigned int (*HPMHOOK_post_status_get_restart_sp) (unsigned int retVal___, const struct map_session_data *sd, const struct status_data *st);
typedef int (*HPMHOOK_pre_status_calc_npc_) (struct npc_data **nd, enum e_status_calc_opt *opt);
typedef int (*HPMHOOK_post_status_calc_npc_) (int retVal___, struct npc_data *nd, enum e_status_calc_opt opt);
typedef unsigned short (*HPMHOOK_pre_status_calc_str) (struct block_list **bl, struct status_change **sc, int *str);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 873e82c48..5573e4a14 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -6242,6 +6242,10 @@ struct {
struct HPMHookPoint *HP_status_get_base_maxhp_post;
struct HPMHookPoint *HP_status_get_base_maxsp_pre;
struct HPMHookPoint *HP_status_get_base_maxsp_post;
+ struct HPMHookPoint *HP_status_get_restart_hp_pre;
+ struct HPMHookPoint *HP_status_get_restart_hp_post;
+ struct HPMHookPoint *HP_status_get_restart_sp_pre;
+ struct HPMHookPoint *HP_status_get_restart_sp_post;
struct HPMHookPoint *HP_status_calc_npc__pre;
struct HPMHookPoint *HP_status_calc_npc__post;
struct HPMHookPoint *HP_status_calc_str_pre;
@@ -12847,6 +12851,10 @@ struct {
int HP_status_get_base_maxhp_post;
int HP_status_get_base_maxsp_pre;
int HP_status_get_base_maxsp_post;
+ int HP_status_get_restart_hp_pre;
+ int HP_status_get_restart_hp_post;
+ int HP_status_get_restart_sp_pre;
+ int HP_status_get_restart_sp_post;
int HP_status_calc_npc__pre;
int HP_status_calc_npc__post;
int HP_status_calc_str_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 838968ce0..601441a61 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -3190,6 +3190,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(status->base_atk, HP_status_base_atk) },
{ HP_POP(status->get_base_maxhp, HP_status_get_base_maxhp) },
{ HP_POP(status->get_base_maxsp, HP_status_get_base_maxsp) },
+ { HP_POP(status->get_restart_hp, HP_status_get_restart_hp) },
+ { HP_POP(status->get_restart_sp, HP_status_get_restart_sp) },
{ HP_POP(status->calc_npc_, HP_status_calc_npc_) },
{ HP_POP(status->calc_str, HP_status_calc_str) },
{ HP_POP(status->calc_agi, HP_status_calc_agi) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index d8f515444..7a75f57e2 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -81540,11 +81540,11 @@ int HP_status_percent_change(struct block_list *src, struct block_list *target,
}
return retVal___;
}
-int HP_status_set_hp(struct block_list *bl, unsigned int hp, int flag) {
+int HP_status_set_hp(struct block_list *bl, unsigned int hp, enum status_heal_flag flag) {
int hIndex = 0;
int retVal___ = 0;
if (HPMHooks.count.HP_status_set_hp_pre > 0) {
- int (*preHookFunc) (struct block_list **bl, unsigned int *hp, int *flag);
+ int (*preHookFunc) (struct block_list **bl, unsigned int *hp, enum status_heal_flag *flag);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_status_set_hp_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_status_set_hp_pre[hIndex].func;
@@ -81559,7 +81559,7 @@ int HP_status_set_hp(struct block_list *bl, unsigned int hp, int flag) {
retVal___ = HPMHooks.source.status.set_hp(bl, hp, flag);
}
if (HPMHooks.count.HP_status_set_hp_post > 0) {
- int (*postHookFunc) (int retVal___, struct block_list *bl, unsigned int hp, int flag);
+ int (*postHookFunc) (int retVal___, struct block_list *bl, unsigned int hp, enum status_heal_flag flag);
for (hIndex = 0; hIndex < HPMHooks.count.HP_status_set_hp_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_status_set_hp_post[hIndex].func;
retVal___ = postHookFunc(retVal___, bl, hp, flag);
@@ -81567,11 +81567,11 @@ int HP_status_set_hp(struct block_list *bl, unsigned int hp, int flag) {
}
return retVal___;
}
-int HP_status_set_sp(struct block_list *bl, unsigned int sp, int flag) {
+int HP_status_set_sp(struct block_list *bl, unsigned int sp, enum status_heal_flag flag) {
int hIndex = 0;
int retVal___ = 0;
if (HPMHooks.count.HP_status_set_sp_pre > 0) {
- int (*preHookFunc) (struct block_list **bl, unsigned int *sp, int *flag);
+ int (*preHookFunc) (struct block_list **bl, unsigned int *sp, enum status_heal_flag *flag);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_status_set_sp_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_status_set_sp_pre[hIndex].func;
@@ -81586,7 +81586,7 @@ int HP_status_set_sp(struct block_list *bl, unsigned int sp, int flag) {
retVal___ = HPMHooks.source.status.set_sp(bl, sp, flag);
}
if (HPMHooks.count.HP_status_set_sp_post > 0) {
- int (*postHookFunc) (int retVal___, struct block_list *bl, unsigned int sp, int flag);
+ int (*postHookFunc) (int retVal___, struct block_list *bl, unsigned int sp, enum status_heal_flag flag);
for (hIndex = 0; hIndex < HPMHooks.count.HP_status_set_sp_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_status_set_sp_post[hIndex].func;
retVal___ = postHookFunc(retVal___, bl, sp, flag);
@@ -81594,11 +81594,11 @@ int HP_status_set_sp(struct block_list *bl, unsigned int sp, int flag) {
}
return retVal___;
}
-int HP_status_heal(struct block_list *bl, int64 hp, int64 sp, int flag) {
+int HP_status_heal(struct block_list *bl, int64 hp, int64 sp, enum status_heal_flag flag) {
int hIndex = 0;
int retVal___ = 0;
if (HPMHooks.count.HP_status_heal_pre > 0) {
- int (*preHookFunc) (struct block_list **bl, int64 *hp, int64 *sp, int *flag);
+ int (*preHookFunc) (struct block_list **bl, int64 *hp, int64 *sp, enum status_heal_flag *flag);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_status_heal_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_status_heal_pre[hIndex].func;
@@ -81613,7 +81613,7 @@ int HP_status_heal(struct block_list *bl, int64 hp, int64 sp, int flag) {
retVal___ = HPMHooks.source.status.heal(bl, hp, sp, flag);
}
if (HPMHooks.count.HP_status_heal_post > 0) {
- int (*postHookFunc) (int retVal___, struct block_list *bl, int64 hp, int64 sp, int flag);
+ int (*postHookFunc) (int retVal___, struct block_list *bl, int64 hp, int64 sp, enum status_heal_flag flag);
for (hIndex = 0; hIndex < HPMHooks.count.HP_status_heal_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_status_heal_post[hIndex].func;
retVal___ = postHookFunc(retVal___, bl, hp, sp, flag);
@@ -83531,6 +83531,60 @@ unsigned int HP_status_get_base_maxsp(const struct map_session_data *sd, const s
}
return retVal___;
}
+unsigned int HP_status_get_restart_hp(const struct map_session_data *sd, const struct status_data *st) {
+ int hIndex = 0;
+ unsigned int retVal___ = 0;
+ if (HPMHooks.count.HP_status_get_restart_hp_pre > 0) {
+ unsigned int (*preHookFunc) (const struct map_session_data **sd, const struct status_data **st);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_status_get_restart_hp_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_status_get_restart_hp_pre[hIndex].func;
+ retVal___ = preHookFunc(&sd, &st);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.status.get_restart_hp(sd, st);
+ }
+ if (HPMHooks.count.HP_status_get_restart_hp_post > 0) {
+ unsigned int (*postHookFunc) (unsigned int retVal___, const struct map_session_data *sd, const struct status_data *st);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_status_get_restart_hp_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_status_get_restart_hp_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd, st);
+ }
+ }
+ return retVal___;
+}
+unsigned int HP_status_get_restart_sp(const struct map_session_data *sd, const struct status_data *st) {
+ int hIndex = 0;
+ unsigned int retVal___ = 0;
+ if (HPMHooks.count.HP_status_get_restart_sp_pre > 0) {
+ unsigned int (*preHookFunc) (const struct map_session_data **sd, const struct status_data **st);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_status_get_restart_sp_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_status_get_restart_sp_pre[hIndex].func;
+ retVal___ = preHookFunc(&sd, &st);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.status.get_restart_sp(sd, st);
+ }
+ if (HPMHooks.count.HP_status_get_restart_sp_post > 0) {
+ unsigned int (*postHookFunc) (unsigned int retVal___, const struct map_session_data *sd, const struct status_data *st);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_status_get_restart_sp_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_status_get_restart_sp_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd, st);
+ }
+ }
+ return retVal___;
+}
int HP_status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) {
int hIndex = 0;
int retVal___ = 0;