diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 15 | ||||
-rw-r--r-- | src/map/battle.h | 1 | ||||
-rw-r--r-- | src/map/pc.c | 20 | ||||
-rw-r--r-- | src/map/pc.h | 3 | ||||
-rw-r--r-- | src/map/script.c | 10 | ||||
-rw-r--r-- | src/map/skill.c | 141 | ||||
-rw-r--r-- | src/map/skill.h | 5 | ||||
-rw-r--r-- | src/map/status.c | 61 | ||||
-rw-r--r-- | src/map/unit.c | 19 |
9 files changed, 193 insertions, 82 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index bde3bfb65..47cb4a88c 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1587,6 +1587,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if(sd && flag.arrow) hitrate += sd->bonus.arrow_hit; +#ifdef RENEWAL + if( sd ) //in Renewal hit bonus from Vultures Eye is not anymore shown in status window + hitrate += pc_checkskill(sd,AC_VULTURE); +#endif if(skill_num) switch(skill_num) { //Hit skill modifiers @@ -4258,6 +4262,10 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * } hitrate+= sstatus->hit - flee; +#ifdef RENEWAL + if( sd ) //in Renewal hit bonus from Vultures Eye is not anymore shown in status window + hitrate += pc_checkskill(sd,AC_VULTURE); +#endif hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate); if(rnd()%100 < hitrate) @@ -4676,6 +4684,12 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t skill_get_time(MO_CALLSPIRITS, sc->data[SC_GT_ENERGYGAIN]->val1), sc->data[SC_GT_ENERGYGAIN]->val1); } + if( tsc && tsc->data[SC_GT_ENERGYGAIN] ) { + if( tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GT_ENERGYGAIN]->val1) + pc_addspiritball(tsd, + skill_get_time(MO_CALLSPIRITS, tsc->data[SC_GT_ENERGYGAIN]->val1), + tsc->data[SC_GT_ENERGYGAIN]->val1); + } } @@ -5577,6 +5591,7 @@ static const struct _battle_data { { "max_cloth_color", &battle_config.max_cloth_color, 4, 0, INT_MAX, }, { "pet_hair_style", &battle_config.pet_hair_style, 100, 0, INT_MAX, }, { "castrate_dex_scale", &battle_config.castrate_dex_scale, 150, 1, INT_MAX, }, + { "vcast_stat_scale", &battle_config.vcast_stat_scale, 530, 1, INT_MAX, }, { "area_size", &battle_config.area_size, 14, 0, INT_MAX, }, { "zeny_from_mobs", &battle_config.zeny_from_mobs, 0, 0, 1, }, { "mobs_level_up", &battle_config.mobs_level_up, 0, 0, 1, }, diff --git a/src/map/battle.h b/src/map/battle.h index 962ca81a7..a67fd15f5 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -473,6 +473,7 @@ extern struct Battle_Config int max_baby_third_parameter; int atcommand_max_stat_bypass; int max_third_aspd; + int vcast_stat_scale; int mvp_tomb_enabled; diff --git a/src/map/pc.c b/src/map/pc.c index bea5b5c0a..82e650111 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -2599,11 +2599,11 @@ int pc_bonus(struct map_session_data *sd,int type,int val) break; case SP_FIXCASTRATE: if(sd->state.lr_flag != 2) - sd->fixcastrate+=val; + sd->bonus.fixcastrate -= val; break; case SP_VARCASTRATE: if(sd->state.lr_flag != 2) - sd->varcastrate+=val; + sd->bonus.varcastrate -= val; break; default: ShowWarning("pc_bonus: unknown type %d %d !\n",type,val); @@ -3135,6 +3135,22 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->skillvarcast[i].val = val; } break; + case SP_VARCASTRATE: + if(sd->state.lr_flag == 2) + break; + ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2); + if (i == ARRAYLENGTH(sd->skillcast)) + { + ShowDebug("run_script: bonus2 bVariableCastrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",ARRAYLENGTH(sd->skillcast), type2, val); + break; + } + if(sd->skillcast[i].id == type2) + sd->skillcast[i].val -= val; + else { + sd->skillcast[i].id = type2; + sd->skillcast[i].val -= val; + } + break; case SP_SKILL_USE_SP: //bonus2 bSkillUseSP,n,x; if(sd->state.lr_flag == 2) break; diff --git a/src/map/pc.h b/src/map/pc.h index a87544d0c..589605753 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -317,11 +317,12 @@ struct map_session_data { unsigned short unbreakable; // chance to prevent ANY equipment breaking [celest] unsigned short unbreakable_equip; //100% break resistance on certain equipment unsigned short unstripable_equip; + int fixcastrate,varcastrate; } bonus; // zeroed vars end here. - int castrate,delayrate,hprate,sprate,dsprate,fixcastrate,varcastrate; + int castrate,delayrate,hprate,sprate,dsprate; 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 e33e1c643..79668f736 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -7718,6 +7718,7 @@ BUILDIN_FUNC(bonus) case SP_SKILL_COOLDOWN: case SP_SKILL_FIXEDCAST: case SP_SKILL_VARIABLECAST: + case SP_VARCASTRATE: case SP_SKILL_USE_SP: // these bonuses support skill names val1 = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) ); @@ -16886,20 +16887,13 @@ BUILDIN_FUNC(checkre) #endif break; case 5: - #ifdef RENEWAL_CAST_VMIN - script_pushint(st, 1); - #else - script_pushint(st, 0); - #endif - break; - case 6: #ifdef RENEWAL_EDP script_pushint(st, 1); #else script_pushint(st, 0); #endif break; - case 7: + case 6: #ifdef RENEWAL_ASPD script_pushint(st, 1); #else diff --git a/src/map/skill.c b/src/map/skill.c index f15c972aa..001386dfd 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -39,6 +39,7 @@ #include <stdlib.h> #include <string.h> #include <time.h> +#include <math.h> #define SKILLUNITTIMER_INTERVAL 100 @@ -3182,7 +3183,15 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) case GN_SPORE_EXPLOSION: map_foreachinrange(skill_area_sub, target, skill_get_splash(skl->skill_id, skl->skill_lv), BL_CHAR, src, skl->skill_id, skl->skill_lv, 0, skl->flag|1|BCT_ENEMY, skill_castend_damage_id); - break; + break; + case CH_PALMSTRIKE: + { + struct status_change* tsc = status_get_sc(target); + if( tsc && tsc->option&OPTION_HIDE ){ + skill_blown(src,target,skill_get_blewcount(skl->skill_id, skl->skill_lv), -1, 0x0 ); + break; + } + } default: skill_attack(skl->type,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag); break; @@ -13353,12 +13362,12 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) nullpo_ret(bl); sd = BL_CAST(BL_PC, bl); - +#ifndef RENEWAL_CAST // calculate base cast time (reduced by dex) if( !(skill_get_castnodex(skill_id, skill_lv)&1) ) { - int scale = CONST_CASTRATE_SCALE - CONST_CASTRATE_CALC; + int scale = battle_config.castrate_dex_scale - status_get_dex(bl); if( scale > 0 ) // not instant cast - time = time * scale / CONST_CASTRATE_SCALE; + time = time * scale / battle_config.castrate_dex_scale; else return 0; // instant cast } @@ -13378,6 +13387,7 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) } } } +#endif // config cast time multiplier if (battle_config.cast_rate != 100) time = time * battle_config.cast_rate / 100; @@ -13388,69 +13398,116 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) /*========================================== * Does cast-time reductions based on sc data. *------------------------------------------*/ -int skill_castfix_sc (struct block_list *bl, int time, int skill_id, int skill_lv) { +int skill_castfix_sc (struct block_list *bl, int time) +{ struct status_change *sc = status_get_sc(bl); + + if( time < 0 ) + return 0; + + if (sc && sc->count) { + if (sc->data[SC_SLOWCAST]) + time += time * sc->data[SC_SLOWCAST]->val2 / 100; + if (sc->data[SC_SUFFRAGIUM]) { + time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100; + status_change_end(bl, SC_SUFFRAGIUM, -1); + } + if (sc->data[SC_MEMORIZE]) { + time>>=1; + if ((--sc->data[SC_MEMORIZE]->val2) <= 0) + status_change_end(bl, SC_MEMORIZE, -1); + } + if (sc->data[SC_POEMBRAGI]) + time -= time * sc->data[SC_POEMBRAGI]->val2 / 100; + if (sc->data[SC_IZAYOI]) + time -= time * 50 / 100; + } + + return (time > 0) ? time : 0; +} #ifdef RENEWAL_CAST +int skill_vfcastfix (struct block_list *bl, double 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); - 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){ + int fixed = skill_get_fixed_cast(skill_id, skill_lv), fixcast_r = 0, varcast_r = 0, i = 0; + + if( time < 0 ) + return 0; + + if( !fixed ) + fixed = (int)time * 20 / 100; // fixed time + time = time * 80 / 100; // variable time + + if(sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){ // Increases/Decreases fixed/variable cast time of a skill by item/card bonuses. + if( sd->bonus.varcastrate < 0 ) + VARCAST_REDUCTION(sd->bonus.varcastrate); + for (i = 0; i < ARRAYLENGTH(sd->skillfixcast) && sd->skillfixcast[i].id; i++) + if (sd->skillfixcast[i].id == skill_id){ // bonus2 bSkillFixedCast fixed += sd->skillfixcast[i].val; break; } - } + for( i = 0; i < ARRAYLENGTH(sd->skillvarcast) && sd->skillvarcast[i].id; i++ ) + if( sd->skillvarcast[i].id == skill_id ){ // bonus2 bSkillVariableCast + time += sd->skillvarcast[i].val; + break; + } + for( i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++ ) + if( sd->skillcast[i].id == skill_id ){ // bonus2 bVariableCastrate + if( (i=sd->skillcast[i].val) < 0) + VARCAST_REDUCTION(i); + break; + } } -#endif - if( time < 0 ) return 0; // due to fixed castime so use -1 to nullify the casting. [malufett] - if (sc && sc->count) { + + if (sc && sc->count && !(skill_get_castnodex(skill_id, skill_lv)&2) ) { + // All variable cast additive bonuses must come first if (sc->data[SC_SLOWCAST]) - time += time * sc->data[SC_SLOWCAST]->val2 / 100; + VARCAST_REDUCTION(-sc->data[SC_SLOWCAST]->val2); + + // Variable cast reduction bonuses if (sc->data[SC_SUFFRAGIUM]) { - time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100; + VARCAST_REDUCTION(sc->data[SC_SUFFRAGIUM]->val2); status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER); } if (sc->data[SC_MEMORIZE]) { - time>>=1; + VARCAST_REDUCTION(50); if ((--sc->data[SC_MEMORIZE]->val2) <= 0) status_change_end(bl, SC_MEMORIZE, INVALID_TIMER); } if (sc->data[SC_POEMBRAGI]) - time -= time * sc->data[SC_POEMBRAGI]->val2 / 100; + VARCAST_REDUCTION(sc->data[SC_POEMBRAGI]->val2); if (sc->data[SC_IZAYOI]) - time -= time * 50 / 100; -#ifdef RENEWAL_CAST + VARCAST_REDUCTION(50); + // Fixed cast reduction bonuses if( sc->data[SC__LAZINESS] ) - fixed += fixed * sc->data[SC__LAZINESS]->val2 / 100; - /** - * AB Sacrament reduces fixed cast time by (10 x Level)% (up to 50%) - **/ + fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2); if( sc->data[SC_SECRAMENT] ) - fixed -= fixed * sc->data[SC_SECRAMENT]->val2 / 100; + fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2); + if( sd && ( skill_lv = pc_checkskill(sd, WL_RADIUS) ) && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP ) + fixcast_r = max(fixcast_r, 5 + skill_lv * 5); + // Fixed cast non percentage bonuses if( sc->data[SC_MANDRAGORA] && (skill_id >= SM_BASH && skill_id <= RETURN_TO_ELDICASTES) ) fixed += 2000; if (sc->data[SC_IZAYOI] && (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN)) fixed = 0; -#endif } -#ifdef RENEWAL_CAST - /** - * WL_RADIUS decreases 10/15/20% fixed cast time from warlock skills - **/ - 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 - return (time > 0) ? time : 0; -#endif + + if( sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){ + VARCAST_REDUCTION( max(sd->bonus.varcastrate, 0) + max(i, 0) ); + fixcast_r = max(fixcast_r, sd->bonus.fixcastrate) + min(sd->bonus.fixcastrate,0); + } + + if( varcast_r < 0 ) // now compute overall factors + time = time * (1 - (float)varcast_r / 100); + if( !(skill_get_castnodex(skill_id, skill_lv)&1) )// reduction from status point + time = (1 - sqrt( ((float)(status_get_dex(bl)*2 + status_get_int(bl)) / battle_config.vcast_stat_scale) )) * time; + // underflow checking/capping + time = max(time, 0) + (1 - (float)min(fixcast_r, 100) / 100) * fixed; + + return (int)time; } +#endif /*========================================== * Does delay reductions based on dex/agi, sc data, item bonuses, ... diff --git a/src/map/skill.h b/src/map/skill.h index f3b254b61..5752ca301 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -297,7 +297,10 @@ int skill_clear_group(struct block_list *bl, int flag); int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl,int damage,unsigned int tick); 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); +int skill_castfix_sc( struct block_list *bl, int time); +#ifdef RENEWAL_CAST +int skill_vfcastfix( struct block_list *bl, double time, int skill_id, int skill_lv); +#endif int skill_delayfix( struct block_list *bl, int skill_id, int skill_lv); // Skill conditions check and remove [Inkfish] diff --git a/src/map/status.c b/src/map/status.c index c314aae3f..9f4692cd3 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2315,8 +2315,6 @@ 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] @@ -2836,7 +2834,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) if((skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0) status->hit += skill*2; if((skill=pc_checkskill(sd,AC_VULTURE))>0){ +#ifndef RENEWAL status->hit += skill; +#endif if(sd->status.weapon == W_BOW) status->rhw.range += skill; } @@ -2978,10 +2978,6 @@ 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) @@ -7853,7 +7849,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_PYREXIA: status_change_start(bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds val4 = tick / 3000; - tick_time = 4000; // [GodLesZ] tick time + tick_time = 3000; // [GodLesZ] tick time break; case SC_LEECHESEND: val4 = tick / 1000; @@ -10488,13 +10484,10 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) { switch( i ) { //Debuffs that can be spreaded. // NOTE: We'll add/delte SCs when we are able to confirm it. - case SC_POISON: case SC_CURSE: case SC_SILENCE: case SC_CONFUSION: case SC_BLIND: - case SC_BLEEDING: - case SC_DPOISON: case SC_NOCHAT: case SC_HALLUCINATION: case SC_SIGNUMCRUCIS: @@ -10511,16 +10504,9 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) { //case SC__STRIPACCESSORY: case SC_BITE: case SC_FREEZING: - case SC_BURNING: - case SC_FEAR: - case SC_PYREXIA: - case SC_PARALYSE: - case SC_DEATHHURT: - case SC_MAGICMUSHROOM: case SC_VENOMBLEED: - case SC_TOXIN: - case SC_OBLIVIONCURSE: - case SC_LEECHESEND: + case SC_DEATHHURT: + case SC_PARALYSE: if( sc->data[i]->timer != INVALID_TIMER ) { timer = get_timer(sc->data[i]->timer); if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0) @@ -10528,17 +10514,42 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) { data.tick = DIFF_TICK(timer->tick,tick); } else data.tick = INVALID_TIMER; - data.val1 = sc->data[i]->val1; - data.val2 = sc->data[i]->val2; - data.val3 = sc->data[i]->val3; - data.val4 = sc->data[i]->val4; - status_change_start(bl,i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8); - flag = 1; + break; + // Special cases + case SC_POISON: + case SC_DPOISON: + data.tick = sc->data[i]->val3 * 1000; + break; + case SC_FEAR: + case SC_LEECHESEND: + data.tick = sc->data[i]->val4 * 1000; + break; + case SC_BURNING: + data.tick = sc->data[i]->val4 * 2000; + break; + case SC_PYREXIA: + case SC_OBLIVIONCURSE: + data.tick = sc->data[i]->val4 * 3000; + break; + case SC_MAGICMUSHROOM: + data.tick = sc->data[i]->val4 * 4000; + break; + case SC_TOXIN: + case SC_BLEEDING: + data.tick = sc->data[i]->val4 * 10000; break; default: continue; break; } + if( i ){ + data.val1 = sc->data[i]->val1; + data.val2 = sc->data[i]->val2; + data.val3 = sc->data[i]->val3; + data.val4 = sc->data[i]->val4; + status_change_start(bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8); + flag = 1; + } } return flag; diff --git a/src/map/unit.c b/src/map/unit.c index 089a5520e..5568ec1de 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1040,6 +1040,9 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh target_id = sc->data[SC_COMBO]->val2; else target_id = ud->target; + + if( skill_get_inf(skill_num)&INF_SELF_SKILL && skill_get_nk(skill_num)&NK_NO_DAMAGE )// exploit fix + target_id = src->id; temp = 1; } else if ( target_id == src->id && @@ -1250,8 +1253,13 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh } // moved here to prevent Suffragium from ending if skill fails - if (!(skill_get_castnodex(skill_num, skill_lv)&2)) - casttime = skill_castfix_sc(src, casttime, skill_num, skill_lv); +#ifndef RENEWAL_CAST + if (!(skill_get_castnodex(skill_num, skill_lv)&2)) + casttime = skill_castfix_sc(src, casttime); +#else + casttime = skill_vfcastfix(src, casttime, skill_num, skill_lv); +#endif + // in official this is triggered even if no cast time. clif_skillcasting(src, src->id, target_id, 0,0, skill_num, skill_get_ele(skill_num, skill_lv), casttime); if( casttime > 0 || temp ) @@ -1408,8 +1416,13 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, sh unit_stop_attack(src); // moved here to prevent Suffragium from ending if skill fails +#ifndef RENEWAL_CAST if (!(skill_get_castnodex(skill_num, skill_lv)&2)) - casttime = skill_castfix_sc(src, casttime, skill_num, skill_lv); + casttime = skill_castfix_sc(src, casttime); +#else + casttime = skill_vfcastfix(src, casttime, skill_num, skill_lv ); +#endif + ud->state.skillcastcancel = castcancel&&casttime>0?1:0; if( !sd || sd->skillitem != skill_num || skill_get_cast(skill_num,skill_lv) ) |