Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Bonuses: bResSC and bResSC2 #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -488,6 +488,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 @@ -60,6 +60,8 @@ struct eri *pc_sc_display_ers = NULL;
struct eri *pc_itemgrouphealrate_ers = NULL;
struct eri *num_reg_ers;
struct eri *str_reg_ers;
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 @@ -1258,6 +1260,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 @@ -2497,6 +2504,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 @@ -3807,6 +3956,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 @@ -12426,6 +12585,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 @@ -12470,6 +12631,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 @@ -190,6 +190,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 @@ -705,6 +711,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 @@ -740,6 +749,8 @@ struct map_session_data {

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

/**
* ERS for the bulk of pc vars
Expand Down Expand Up @@ -1326,6 +1337,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 @@ -706,6 +706,8 @@
export_constant2("bIgnoreDefClassRate", SP_IGNORE_DEF_CLASS_RATE);
export_constant2("bRegenPercentHP", SP_REGEN_PERCENT_HP);
export_constant2("bRegenPercentSP", SP_REGEN_PERCENT_SP);
export_constant2("bResSC", SP_RES_SC);
export_constant2("bResSC2", SP_RES_SC2);

/* equip indices */
export_constant(EQI_COMPOUND_ON);
Expand Down
14 changes: 14 additions & 0 deletions src/map/status.c
Original file line number Diff line number Diff line change
Expand Up @@ -3448,6 +3448,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 @@ -8041,6 +8043,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 @@ -8093,6 +8101,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 @@ -8108,6 +8119,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 @@ -3244,6 +3244,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