From 86aafca6da0a843db09a33e74faf8d9bb77e2508 Mon Sep 17 00:00:00 2001 From: rud0lp20 Date: Fri, 29 Jun 2012 15:52:29 +0000 Subject: Implemented new item script bonuses: - bSkillCooldown,n,x; - bSkillFixedCast,n,x; - *bSkillVariableCast,n,x; - bFixedCastrate,x; - *bVariableCastrate,x; *Pending until RE Casting system is fully implemented. ATM bCastrate is used to manipulate variable cast time where it should not. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16355 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/map.h | 3 ++- src/map/pc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/map/pc.h | 4 ++-- src/map/script.c | 3 +++ src/map/skill.c | 26 ++++++++++++++++++++++--- src/map/status.c | 9 +++++++++ 6 files changed, 96 insertions(+), 7 deletions(-) (limited to 'src/map') diff --git a/src/map/map.h b/src/map/map.h index c51353b26..2095caf44 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -392,7 +392,8 @@ enum _sp { SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD, // 2034-2037 SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040 SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045 - SP_WEAPON_MATK, SP_BASE_MATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SP_RATE_SKILL //2046-2050 + SP_WEAPON_MATK, SP_BASE_MATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SP_RATE_SKILL, //2046-2050 + SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE //2051-2055 }; enum _look { diff --git a/src/map/pc.c b/src/map/pc.c index c4a2c4ef9..928eec87c 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -2583,6 +2583,14 @@ int pc_bonus(struct map_session_data *sd,int type,int val) if(sd->state.lr_flag != 2) sd->bonus.sp_base_matk += val; break; + case SP_FIXCASTRATE: + if(sd->state.lr_flag != 2) + sd->fixcastrate+=val; + break; + case SP_VARCASTRATE: + if(sd->state.lr_flag != 2) + sd->varcastrate+=val; + break; default: ShowWarning("pc_bonus: unknown type %d %d !\n",type,val); break; @@ -3064,7 +3072,55 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->sprateskill[i].id = type2; sd->sprateskill[i].val = val; } - break; + break; + case SP_SKILL_COOLDOWN: + if(sd->state.lr_flag == 2) + break; + ARR_FIND(0, ARRAYLENGTH(sd->skillcooldown), i, sd->skillcooldown[i].id == 0 || sd->skillcooldown[i].id == type2); + if (i == ARRAYLENGTH(sd->skillcooldown)) + { + ShowDebug("run_script: bonus2 bSkillCoolDown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcooldown), type2, val); + break; + } + if (sd->skillcooldown[i].id == type2) + sd->skillcooldown[i].val += val; + else { + sd->skillcooldown[i].id = type2; + sd->skillcooldown[i].val = val; + } + break; + case SP_SKILL_FIXEDCAST: + if(sd->state.lr_flag == 2) + break; + ARR_FIND(0, ARRAYLENGTH(sd->skillfixcast), i, sd->skillfixcast[i].id == 0 || sd->skillfixcast[i].id == type2); + if (i == ARRAYLENGTH(sd->skillfixcast)) + { + ShowDebug("run_script: bonus2 bSkillFixedCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcast), type2, val); + break; + } + if (sd->skillfixcast[i].id == type2) + sd->skillfixcast[i].val += val; + else { + sd->skillfixcast[i].id = type2; + sd->skillfixcast[i].val = val; + } + break; + case SP_SKILL_VARIABLECAST: + if(sd->state.lr_flag == 2) + break; + ARR_FIND(0, ARRAYLENGTH(sd->skillvarcast), i, sd->skillvarcast[i].id == 0 || sd->skillvarcast[i].id == type2); + if (i == ARRAYLENGTH(sd->skillvarcast)) + { + ShowDebug("run_script: bonus2 bSkillVariableCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillvarcast), type2, val); + break; + } + if (sd->skillvarcast[i].id == type2) + sd->skillvarcast[i].val += val; + else { + sd->skillvarcast[i].id = type2; + sd->skillvarcast[i].val = val; + } + break; default: ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val); break; diff --git a/src/map/pc.h b/src/map/pc.h index 817ad7a5c..15ce14152 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -261,7 +261,7 @@ struct map_session_data { struct { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills. unsigned short id; short val; - } skillatk[MAX_PC_BONUS], sprateskill[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS]; + } skillatk[MAX_PC_BONUS], sprateskill[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS], skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS]; struct { short value; int rate; @@ -322,7 +322,7 @@ struct map_session_data { // zeroed vars end here. - int castrate,delayrate,hprate,sprate,dsprate; + int castrate,delayrate,hprate,sprate,dsprate,fixcastrate,varcastrate; int hprecov_rate,sprecov_rate; int matk_rate; int critical_rate,hit_rate,flee_rate,flee2_rate,def_rate,def2_rate,mdef_rate,mdef2_rate; diff --git a/src/map/script.c b/src/map/script.c index f83264315..4b2cedea4 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -7358,6 +7358,9 @@ BUILDIN_FUNC(bonus) case SP_CASTRATE: case SP_ADDEFF_ONSKILL: case SP_SP_RATE_SKILL: + case SP_SKILL_COOLDOWN: + case SP_SKILL_FIXEDCAST: + case SP_SKILL_VARIABLECAST: // these bonuses support skill names val1 = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) ); break; diff --git a/src/map/skill.c b/src/map/skill.c index 3a479e4bc..8854cf2cc 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -8837,8 +8837,16 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) if( !sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv) ) ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv); //Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish] - if( sd && skill_get_cooldown(ud->skillid,ud->skilllv) > 0 ) - skill_blockpc_start(sd, ud->skillid, skill_get_cooldown(ud->skillid, ud->skilllv)); + if( sd && skill_get_cooldown(ud->skillid,ud->skilllv) > 0 ){ + int i, cooldown = skill_get_cooldown(ud->skillid, ud->skilllv); + for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { // Increases/Decreases cooldown of a skill by item/card bonuses. + if (sd->skillcooldown[i].id == ud->skillid){ + cooldown += sd->skillcooldown[i].val; + break; + } + } + skill_blockpc_start(sd, ud->skillid, cooldown); + } if( battle_config.display_status_timers && sd ) clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, ud->skillid, ud->skilllv), 0, 0, 0); if( sd ) @@ -13001,12 +13009,24 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) *------------------------------------------*/ int skill_castfix_sc (struct block_list *bl, int time, int skill_id, int skill_lv) { struct status_change *sc = status_get_sc(bl); + struct map_session_data *sd = BL_CAST(BL_PC,bl); #ifdef RENEWAL_CAST int fixed = skill_get_fixed_cast(skill_id, skill_lv); if( !fixed ) { fixed = skill_get_cast(skill_id, skill_lv); fixed = ( fixed > 1 ? ( fixed * 20 / 100 ) : 0 ); } + if(sd){// Increases/Decreases fixed cast time of a skill by item/card bonuses. + int i; + if( sd->fixcastrate != 100 ) + fixed = fixed * sd->fixcastrate / 100; + for (i = 0; i < ARRAYLENGTH(sd->skillfixcast) && sd->skillfixcast[i].id; i++) { + if (sd->skillfixcast[i].id == skill_id){ + fixed += sd->skillfixcast[i].val; + break; + } + } + } #endif if (sc && sc->count) { if (sc->data[SC_SLOWCAST]) @@ -13038,7 +13058,7 @@ int skill_castfix_sc (struct block_list *bl, int time, int skill_id, int skill_l /** * WL_RADIUS decreases 10/15/20% fixed cast time from warlock skills **/ - if( bl->type == BL_PC && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP && ( skill_lv = pc_checkskill((TBL_PC*)bl, WL_RADIUS) ) ) + if( sd && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP && ( skill_lv = pc_checkskill(sd, WL_RADIUS) ) ) fixed -= fixed * (5+(skill_lv*5)) / 100; return (time > 0 || fixed > 0) ? cap_value( time , fixed , INT_MAX ) : 0; #else diff --git a/src/map/status.c b/src/map/status.c index f46b12f7f..701d2db9b 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2274,6 +2274,8 @@ int status_calc_pc_(struct map_session_data* sd, bool first) sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100; sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100; sd->regen.state.block = 0; + sd->fixcastrate=100; + sd->varcastrate=100; // zeroed arrays, order follows the order in pc.h. // add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo] @@ -2354,6 +2356,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) + sizeof(sd->add_drop) + sizeof(sd->itemhealrate) + sizeof(sd->subele2) + + sizeof(sd->skillcooldown) + + sizeof(sd->skillfixcast) + + sizeof(sd->skillvarcast) ); memset (&sd->bonus, 0,sizeof(sd->bonus)); @@ -2908,6 +2913,10 @@ int status_calc_pc_(struct map_session_data* sd, bool first) sd->hprecov_rate = 0; if(sd->sprecov_rate < 0) sd->sprecov_rate = 0; + if(sd->fixcastrate < 0) + sd->fixcastrate = 0; + if(sd->varcastrate < 0) + sd->varcastrate = 0; // Anti-element and anti-race if((skill=pc_checkskill(sd,CR_TRUST))>0) -- cgit v1.2.3-60-g2f50