From d54cf73f7ca82bdfd4949d7987e90fa14c23833b Mon Sep 17 00:00:00 2001 From: Fate Date: Sat, 31 Jan 2009 11:20:59 -0700 Subject: Add functionality for healer XP handling --- src/map/magic-expr.c | 13 +++++++++++++ src/map/magic-stmt.c | 13 +++++++++++++ src/map/map.h | 2 ++ src/map/pc.c | 38 ++++++++++++++++++++++++++++++++++++++ src/map/pc.h | 7 +++++++ src/map/script.c | 2 +- 6 files changed, 74 insertions(+), 1 deletion(-) (limited to 'src/map') diff --git a/src/map/magic-expr.c b/src/map/magic-expr.c index 4f7e823..cb3c0ae 100644 --- a/src/map/magic-expr.c +++ b/src/map/magic-expr.c @@ -1101,6 +1101,18 @@ fun_dir_towards(env_t *env, int args_nr, val_t *result, val_t *args) return 0; } +static int +fun_extract_healer_xp(env_t *env, int args_nr, val_t *result, val_t *args) +{ + character_t *sd = (ETY(0) == BL_PC) ? ARGPC(0) : NULL; + + if (!sd) + RESULTINT = 0; + else + RESULTINT = pc_extract_healer_exp(sd, ARGINT(1)); + return 0; +} + #define BATTLE_RECORD2(sname, name) { sname, "e", 'i', fun_get_##name } @@ -1177,6 +1189,7 @@ static fun_t functions[] = { { "map_nr", "l", 'i', fun_map_nr }, { "dir_towards", "lli", 'd', fun_dir_towards }, { "is_dead", "e", 'i', fun_is_dead }, + { "extract_healer_experience", "ei", 'i', fun_extract_healer_xp }, { NULL, NULL, '.', NULL } }; diff --git a/src/map/magic-stmt.c b/src/map/magic-stmt.c index 3422a1b..24b4c0f 100644 --- a/src/map/magic-stmt.c +++ b/src/map/magic-stmt.c @@ -761,6 +761,18 @@ op_drop_item_for(env_t *env, int args_nr, val_t *args) return 0; } +static int +op_gain_exp(env_t *env, int args_nr, val_t *args) +{ + character_t *c = (ETY(0) == BL_PC)? ARGPC(0) : NULL; + + if (!c) + return 1; + + pc_gainexp_reason(c, ARGINT(1), ARGINT(2), ARGINT(3)); + return 0; +} + static op_t operations[] = { { "sfx", ".ii", op_sfx }, @@ -785,6 +797,7 @@ static op_t operations[] = { "set_hair_style", "ei", op_set_hair_style }, { "drop_item", "l.ii", op_drop_item_for }, { "drop_item_for", "l.iiei", op_drop_item_for }, + { "gain_experience", "eiii", op_gain_exp }, { NULL, NULL, NULL } }; diff --git a/src/map/map.h b/src/map/map.h index 0b52a38..50fe321 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -251,6 +251,8 @@ struct map_session_data { // [Fate] Used for gradual healing; amount of enqueued regeneration struct quick_regeneration quick_regeneration_hp, quick_regeneration_sp; + // [Fate] XP that can be extracted from this player by healing + int heal_xp; // i.e., OTHER players (healers) can partake in this player's XP int invincible_timer; unsigned int canact_tick; diff --git a/src/map/pc.c b/src/map/pc.c index 41862e3..0eac9eb 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -307,6 +307,7 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) { if(sd->status.zeny < 0) sd->status.zeny = 0; clif_updatestatus(sd,SP_ZENY); } + sd->heal_xp = 0; // [Fate] Set gainable xp for healing this player to 0 return 0; } @@ -704,6 +705,7 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, short tmw_versio sd->sp_sub = 0; sd->quick_regeneration_hp.amount = 0; sd->quick_regeneration_sp.amount = 0; + sd->heal_xp = 0; sd->inchealspirithptick = 0; sd->inchealspiritsptick = 0; sd->canact_tick = tick; @@ -4442,6 +4444,11 @@ int pc_checkjoblevelup(struct map_session_data *sd) *------------------------------------------ */ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp) +{ + return pc_gainexp_reason(sd, base_exp, job_exp, PC_GAINEXP_REASON_KILLING); +} + +int pc_gainexp_reason(struct map_session_data *sd,int base_exp,int job_exp, int reason) { char output[256]; nullpo_retr(0, sd); @@ -4470,6 +4477,16 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp) } sd->status.base_exp += base_exp; + + // [Fate] Adjust experience points that healers can extract from this character + if (reason != PC_GAINEXP_REASON_HEALING) { + const int max_heal_xp = 20 + (sd->status.base_level * sd->status.base_level); + + sd->heal_xp += base_exp; + if (sd->heal_xp > max_heal_xp) + sd->heal_xp = max_heal_xp; + } + if(sd->status.base_exp < 0) sd->status.base_exp = 0; @@ -4499,6 +4516,20 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp) return 0; } +int +pc_extract_healer_exp(struct map_session_data *sd, int max) +{ + int amount; + nullpo_retr(0, sd); + + amount = sd->heal_xp; + if (max < amount) + amount = max; + + sd->heal_xp -= amount; + return amount; +} + /*========================================== * base level側必要経験値計算 *------------------------------------------ @@ -7142,6 +7173,13 @@ static int pc_natural_heal_sub(struct map_session_data *sd,va_list ap) { nullpo_retr(0, sd); + if (sd->heal_xp > 0) { + if (sd->heal_xp < 64) + --sd->heal_xp; // [Fate] Slowly reduce XP that healers can get for healing this char + else + sd->heal_xp -= (sd->heal_xp >> 6); + } + // Hijack this callback: Adjust spellpower bonus if (sd->spellpower_bonus_target < sd->spellpower_bonus_current) { sd->spellpower_bonus_current = sd->spellpower_bonus_target; diff --git a/src/map/pc.h b/src/map/pc.h index 3d6fc64..0c4141a 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -105,6 +105,13 @@ int pc_follow(struct map_session_data*, int); // [MouseJstr] int pc_checkbaselevelup(struct map_session_data *sd); int pc_checkjoblevelup(struct map_session_data *sd); int pc_gainexp(struct map_session_data*,int,int); + +#define PC_GAINEXP_REASON_KILLING 0 +#define PC_GAINEXP_REASON_HEALING 1 +#define PC_GAINEXP_REASON_SCRIPT 2 +int pc_gainexp_reason(struct map_session_data*,int,int, int reason); +int pc_extract_healer_exp(struct map_session_data*, int max); // [Fate] Used by healers: extract healer-xp from the target, return result (up to max) + int pc_nextbaseexp(struct map_session_data *); int pc_nextbaseafter(struct map_session_data *); // [Valaris] int pc_nextjobexp(struct map_session_data *); diff --git a/src/map/script.c b/src/map/script.c index 9e4880e..e15ee4d 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -3628,7 +3628,7 @@ int buildin_getexp(struct script_state *st) if(base<0 || job<0) return 0; if(sd) - pc_gainexp(sd,base,job); + pc_gainexp_reason(sd,base,job, PC_GAINEXP_REASON_SCRIPT); return 0; } -- cgit v1.2.3-60-g2f50