Skip to content

Commit

Permalink
New Bonuses: bResSC and bResSC2
Browse files Browse the repository at this point in the history
* `bonus2 bResSC,sc,n;` : Adds a n/100% relative tolerance to status change specified by SC constants.
* `bonus2 bResSC2,sc,n;` : Adds a n/100% absolute tolerance to status change specified by SC constants.

Signed-off-by: Cydh Ramdh <[email protected]>
  • Loading branch information
cydh committed Nov 20, 2016
1 parent 0dd3c74 commit 97edf66
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 0 deletions.
3 changes: 3 additions & 0 deletions doc/item_bonus.txt
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ bonus2 bAddEff2,eff,n; Adds a n/100% chance to cause status eff on self w
bonus2 bAddEffWhenHit,eff,n; Adds a n/100% chance to cause status eff on the enemy when being hit by physical damage
bonus2 bResEff,eff,n; Adds a n/100% tolerance to status eff

bonus2 bResSC,sc,n; Adds a n/100% relative tolerance to status change specified by SC constants.
bonus2 bResSC2,sc,n; Adds a n/100% absolute tolerance to status change specified by SC constants.

bonus3 bAddEff,eff,n,atf; Adds a n/100% chance to cause status eff on the target when attacking
bonus4 bAddEff,eff,n,atf,t; Adds a n/100% chance to cause status eff for t milliseconds on the target when attacking
bonus3 bAddEffWhenHit,eff,n,atf; Adds a n/100% chance to cause status eff on the target when being hit by physical damage
Expand Down
2 changes: 2 additions & 0 deletions src/map/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ enum _sp {
SP_STATE_NORECOVER_RACE, SP_CRITICAL_RANGEATK, SP_MAGIC_ADDRACE2, SP_IGNORE_MDEF_RACE2_RATE, // 2079-2082
SP_WEAPON_ATK_RATE, SP_WEAPON_MATK_RATE, SP_DROP_ADDRACE, SP_DROP_ADDCLASS, SP_NO_MADO_FUEL, // 2083-2087
SP_IGNORE_DEF_CLASS_RATE, SP_REGEN_PERCENT_HP, SP_REGEN_PERCENT_SP, //2088-2091

SP_RES_SC, SP_RES_SC2,
};

enum _look {
Expand Down
163 changes: 163 additions & 0 deletions src/map/pc.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ int night_timer_tid = INVALID_TIMER;

struct eri *pc_sc_display_ers = NULL;
struct eri *pc_itemgrouphealrate_ers = NULL;
struct eri *pc_resSC_ers = NULL;
struct eri *pc_resSC2_ers = NULL;
int pc_expiration_tid = INVALID_TIMER;

struct fame_list smith_fame_list[MAX_FAME_LIST];
Expand Down Expand Up @@ -1198,6 +1200,11 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
sd->qi_display = NULL;
sd->qi_count = 0;

sd->resSC = NULL;
sd->resSC_count = 0;
sd->resSC2 = NULL;
sd->resSC2_count = 0;

//warp player
if ((i=pc_setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT)) != SETPOS_OK) {
ShowError ("Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, i);
Expand Down Expand Up @@ -2423,6 +2430,148 @@ void pc_itemgrouphealrate_clear(struct map_session_data *sd) {
}
}

/** Get bResSC rate from player
* @param sd Player
* @param type SC Type
* @return Resistance rate
* @author Cydh
*/
short pc_resSC(struct map_session_data *sd, sc_type type) {
uint8 i;

nullpo_ret(sd);

if (!sd->resSC || !sd->resSC_count)
return 0;
for (i = 0; i < sd->resSC_count; i++) {
if (sd->resSC[i]->sc == type)
return sd->resSC[i]->rate;
}
return 0;
}

/** Add bResSC data to player
* @param sd Player
* @param type SC Type
* @param rate
* @author Cydh
*/
void pc_resSC_add(struct map_session_data *sd, sc_type type, short rate) {
struct s_pc_resSC *entry;
uint8 i;

for (i = 0; i < sd->resSC_count; i++) {
if (sd->resSC[i]->sc == type)
break;
}

if (i != sd->resSC_count) {
sd->resSC[i]->rate += rate;
return;
}

if (i == UINT8_MAX) {
ShowError("pc_resSC_add: Reached max (%d) possible bonuses for this player %d\n", UINT8_MAX);
return;
}

entry = ers_alloc(pc_resSC_ers, struct s_pc_resSC);
entry->sc = type;
entry->rate = rate;

RECREATE(sd->resSC, struct s_pc_resSC *, sd->resSC_count+1);
sd->resSC[sd->resSC_count++] = entry;
}

/** Clear resSC from player
* @param sd Player
* @author Cydh
*/
void pc_resSC_clear(struct map_session_data *sd) {
if (!sd || !sd->resSC_count)
return;
else {
uint8 i;
for( i = 0; i < sd->resSC_count; i++ )
ers_free(pc_resSC_ers, sd->resSC[i]);
sd->resSC_count = 0;
aFree(sd->resSC);
sd->resSC = NULL;
}
}


/** Get bResSC2 rate from player
* @param sd Player
* @param type SC Type
* @return Resistance rate
* @author Cydh
*/
short pc_resSC2(struct map_session_data *sd, sc_type type) {
uint8 i;

nullpo_ret(sd);

if (!sd->resSC2 || !sd->resSC2_count)
return 0;

for (i = 0; i < sd->resSC2_count; i++) {
if (sd->resSC2[i]->sc == type)
return sd->resSC2[i]->rate;
}
return 0;
}

/** Add bResSC2 data to player
* @param sd Player
* @param type SC Type
* @param rate
* @author Cydh
*/
void pc_resSC2_add(struct map_session_data *sd, sc_type type, short rate) {
struct s_pc_resSC *entry;
uint8 i;

for (i = 0; i < sd->resSC2_count; i++) {
if (sd->resSC2[i]->sc == type)
break;
}

if (i != sd->resSC2_count) {
sd->resSC2[i]->rate += rate;
return;
}

if (i == UINT8_MAX) {
ShowError("pc_resSC2_add: Reached max (%d) possible bonuses for this player %d\n", UINT8_MAX);
return;
}

entry = ers_alloc(pc_resSC2_ers, struct s_pc_resSC);
entry->sc = type;
entry->rate = rate;

RECREATE(sd->resSC2, struct s_pc_resSC *, sd->resSC2_count+1);
sd->resSC2[sd->resSC2_count++] = entry;
}

/** Clear resSC2 from player
* @param sd Player
* @author Cydh
*/
void pc_resSC2_clear(struct map_session_data *sd) {
if (!sd || !sd->resSC2_count)
return;
else {
uint8 i;
for( i = 0; i < sd->resSC2_count; i++ )
ers_free(pc_resSC2_ers, sd->resSC2[i]);
sd->resSC2_count = 0;
aFree(sd->resSC2);
sd->resSC2 = NULL;
}
}

/*==========================================
* Add a bonus(type) to player sd
* format: bonus bBonusName,val;
Expand Down Expand Up @@ -3729,6 +3878,16 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
if (sd->state.lr_flag != 2)
sd->dropaddclass[type2] += val;
break;
case SP_RES_SC: // bonus2 bResSC,sc,n;
PC_BONUS_CHK_SC(type2, SP_RESSC);
if (sd->state.lr_flag != 2)
pc_resSC_add(sd, (sc_type)type2, val);
break;
case SP_RES_SC2: // bonus2 bResSC2,sc,n;
PC_BONUS_CHK_SC(type2, SP_RES_SC2);
if (sd->state.lr_flag != 2)
pc_resSC2_add(sd, (sc_type)type2, val);
break;
default:
if (running_npc_stat_calc_event) {
ShowWarning("pc_bonus2: unknown bonus type %d %d %d in OnPCStatCalcEvent!\n", type, type2, val);
Expand Down Expand Up @@ -12269,6 +12428,8 @@ void do_final_pc(void) {

ers_destroy(pc_sc_display_ers);
ers_destroy(pc_itemgrouphealrate_ers);
ers_destroy(pc_resSC_ers);
ers_destroy(pc_resSC2_ers);
ers_destroy(num_reg_ers);
ers_destroy(str_reg_ers);
}
Expand Down Expand Up @@ -12313,6 +12474,8 @@ void do_init_pc(void) {

pc_sc_display_ers = ers_new(sizeof(struct sc_display_entry), "pc.c:pc_sc_display_ers", ERS_OPT_FLEX_CHUNK);
pc_itemgrouphealrate_ers = ers_new(sizeof(struct s_pc_itemgrouphealrate), "pc.c:pc_itemgrouphealrate_ers", ERS_OPT_NONE);
pc_resSC_ers = ers_new(sizeof(struct s_pc_resSC), "pc.c:pc_resSC_ers", ERS_OPT_NONE);
pc_resSC2_ers = ers_new(sizeof(struct s_pc_resSC), "pc.c:pc_resSC2_ers", ERS_OPT_NONE);
num_reg_ers = ers_new(sizeof(struct script_reg_num), "pc.c:num_reg_ers", ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);
str_reg_ers = ers_new(sizeof(struct script_reg_str), "pc.c:str_reg_ers", ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);

Expand Down
16 changes: 16 additions & 0 deletions src/map/pc.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ struct s_pc_itemgrouphealrate {
short rate; /// Rate
};

/// bResEff2 struct
struct s_pc_resSC {
sc_type sc;
short rate;
};

///Timed bonus 'bonus_script' struct [Cydh]
struct s_bonus_script_entry {
struct script_code *script;
Expand Down Expand Up @@ -670,6 +676,9 @@ struct map_session_data {
struct s_pc_itemgrouphealrate **itemgrouphealrate; /// List of Item Group Heal rate bonus
uint8 itemgrouphealrate_count; /// Number of rate bonuses

struct s_pc_resSC **resSC, **resSC2;
unsigned short resSC_count, resSC2_count;

/* Expiration Timer ID */
int expiration_tid;
time_t expiration_time;
Expand Down Expand Up @@ -705,6 +714,8 @@ struct map_session_data {

struct eri *pc_sc_display_ers; /// Player's SC display table
struct eri *pc_itemgrouphealrate_ers; /// Player's Item Group Heal Rate table
struct eri *pc_resSC_ers; /// Player's bResSC table
struct eri *pc_resSC2_ers; /// Player's bResSC2 table

/**
* ERS for the bulk of pc vars
Expand Down Expand Up @@ -1288,6 +1299,11 @@ void pc_show_questinfo_reinit(struct map_session_data *sd);

bool pc_job_can_entermap(enum e_job jobid, int m, int group_lv);

short pc_resSC(struct map_session_data *sd, sc_type type);
void pc_resSC_clear(struct map_session_data *sd);
short pc_resSC2(struct map_session_data *sd, sc_type type);
void pc_resSC2_clear(struct map_session_data *sd);

#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
int pc_level_penalty_mod(int level_diff, uint32 mob_class, enum e_mode mode, int type);
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/map/script_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,8 @@
script_set_constant("bIgnoreDefClassRate", SP_IGNORE_DEF_CLASS_RATE, false);
script_set_constant("bRegenPercentHP", SP_REGEN_PERCENT_HP, false);
script_set_constant("bRegenPercentSP", SP_REGEN_PERCENT_SP, false);
script_set_constant("bResSC", SP_RES_SC, false);
script_set_constant("bResSC2", SP_RES_SC2, false);

/* equip indices */
export_constant(EQI_HEAD_TOP);
Expand Down
14 changes: 14 additions & 0 deletions src/map/status.c
Original file line number Diff line number Diff line change
Expand Up @@ -3384,6 +3384,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true);

pc_itemgrouphealrate_clear(sd);
pc_resSC_clear(sd);
pc_resSC2_clear(sd);

running_npc_stat_calc_event = true;
npc_script_event(sd, NPCE_STATCALC);
Expand Down Expand Up @@ -7909,6 +7911,12 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
tick_def2 = status->luk * 100;
break;
default:
if (sd) { // Adjust the rate from bResSC and bResSC2 [Cydh]
if (sd->resSC2 && sd->resSC2_count)
rate -= pc_resSC2(sd, type);
if (sd->resSC && sd->resSC_count)
rate -= rate * pc_resSC(sd, type) / 10000;
}
// Effect that cannot be reduced? Likely a buff.
if (!(rnd()%10000 < rate))
return 0;
Expand Down Expand Up @@ -7961,6 +7969,9 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
rate -= rate*sc_def/10000;
rate -= sc_def2;

if (sd && sd->resSC2 && sd->resSC2_count)
rate -= pc_resSC2(sd, type);

// Minimum chances
switch (type) {
case SC_BITE:
Expand All @@ -7976,6 +7987,9 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
rate -= rate*sd->sc.data[SC_COMMONSC_RESIST]->val1/100;
}

if (sd && sd->resSC && sd->resSC_count)
rate -= rate * pc_resSC(sd, type) / 10000;

// Aegis accuracy
if(rate > 0 && rate%10 != 0) rate += (10 - rate%10);
}
Expand Down
2 changes: 2 additions & 0 deletions src/map/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -3227,6 +3227,8 @@ int unit_free(struct block_list *bl, clr_type clrtype)
pc_bonus_script_clear(sd, BSF_REM_ALL);

pc_itemgrouphealrate_clear(sd);
pc_resSC_clear(sd);
pc_resSC2_clear(sd);
break;
}
case BL_PET: {
Expand Down

0 comments on commit 97edf66

Please sign in to comment.