diff options
Diffstat (limited to 'src/map/skill.c')
-rw-r--r-- | src/map/skill.c | 124 |
1 files changed, 85 insertions, 39 deletions
diff --git a/src/map/skill.c b/src/map/skill.c index 93eb3bf36..bb0f5fb0f 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -591,6 +591,7 @@ int skillnotok (int skillid, struct map_session_data *sd) break; case WM_LULLABY_DEEPSLEEP: case WM_SIRCLEOFNATURE: + case WM_SATURDAY_NIGHT_FEVER: if( !map_flag_vs(m) ) { clif_skill_teleportmessage(sd,2); // This skill uses this msg instead of skill fails. return 1; @@ -3069,19 +3070,19 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) do { if(src->prev == NULL) - break; + break; // Source not on Map if(skl->target_id) { target = map_id2bl(skl->target_id); if( ( skl->skill_id == RG_INTIMIDATE || skl->skill_id == SC_FATALMENACE ) && (!target || target->prev == NULL || !check_distance_bl(src,target,AREA_SIZE)) ) target = src; //Required since it has to warp. if(target == NULL) - break; + break; // Target offline? if(target->prev == NULL) - break; + break; // Target not on Map if(src->m != target->m) - break; + break; // Different Maps if(status_isdead(src)) - break; + break; // Caster is Dead if(status_isdead(target) && skl->skill_id != RG_INTIMIDATE && skl->skill_id != WZ_WATERBALL) break; @@ -8335,7 +8336,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if( src->id != bl->id && battle_check_target(src,bl,BCT_ENEMY) > 0 ) status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,0,0)); } else if( sd ) { - if( !sd->status.party_id ) { + short chance = sstatus->int_/6 + sd->status.job_level/5 + skilllv*4; + if( !sd->status.party_id || (rnd()%100 > chance)) { clif_skill_fail(sd,skillid,USESKILL_FAIL_NEED_HELPER,0); break; } @@ -11567,6 +11569,23 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_EARTH_INSIGNIA: case UNT_ZEPHYR: sc_start(bl,type, 100, sg->skill_lv, sg->interval); + if (!battle_check_undead(tstatus->race, tstatus->def_ele)) { + int hp = tstatus->max_hp / 100; //+1% each 5s + if ((sg->val3) % 5) { //each 5s + if (tstatus->def_ele == skill_get_ele(sg->skill_id,sg->skill_lv)){ + status_heal(bl, hp, 0, 2); + } else if((sg->unit_id == UNT_FIRE_INSIGNIA && tstatus->def_ele == ELE_EARTH) + ||(sg->unit_id == UNT_WATER_INSIGNIA && tstatus->def_ele == ELE_FIRE) + ||(sg->unit_id == UNT_WIND_INSIGNIA && tstatus->def_ele == ELE_WATER) + ||(sg->unit_id == UNT_EARTH_INSIGNIA && tstatus->def_ele == ELE_WIND) + ){ + status_heal(bl, -hp, 0, 0); + } + } + } + sg->val3++; //timer + if (sg->val3 > 5) + sg->val3 = 0; break; case UNT_VACUUM_EXTREME: @@ -12554,19 +12573,6 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh return 0; } break; - case GC_CROSSRIPPERSLASHER: - if( !(sc && sc->data[SC_ROLLINGCUTTER]) ) { - clif_skill_fail(sd, skill, USESKILL_FAIL_CONDITION, 0); - return 0; - } - break; - case GC_POISONSMOKE: - case GC_VENOMPRESSURE: - if( !(sc && sc->data[SC_POISONINGWEAPON]) ) { - clif_skill_fail(sd, skill, USESKILL_FAIL_GC_POISONINGWEAPON, 0); - return 0; - } - break; /** * Ranger **/ @@ -12848,6 +12854,18 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh return 0; } break; + case ST_POISONINGWEAPON: + if (!(sc && sc->data[SC_POISONINGWEAPON])) { + clif_skill_fail(sd, skill, USESKILL_FAIL_GC_POISONINGWEAPON, 0); + return 0; + } + break; + case ST_ROLLINGCUTTER: + if (!(sc && sc->data[SC_ROLLINGCUTTER])) { + clif_skill_fail(sd, skill, USESKILL_FAIL_CONDITION, 0); + return 0; + } + break; } if(require.mhp > 0 && get_percentage(status->hp, status->max_hp) > require.mhp) { @@ -13218,6 +13236,10 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short case SO_SUMMON_AQUA: case SO_SUMMON_VENTUS: case SO_SUMMON_TERA: + case SO_WATER_INSIGNIA: + case SO_FIRE_INSIGNIA: + case SO_WIND_INSIGNIA: + case SO_EARTH_INSIGNIA: if( i < 3 ) continue; break; @@ -13258,6 +13280,10 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short case SO_SUMMON_AQUA: case SO_SUMMON_VENTUS: case SO_SUMMON_TERA: + case SO_WATER_INSIGNIA: + case SO_FIRE_INSIGNIA: + case SO_WIND_INSIGNIA: + case SO_EARTH_INSIGNIA: req.itemid[lv-1] = skill_db[j].itemid[lv-1]; req.amount[lv-1] = skill_db[j].amount[lv-1]; break; @@ -13386,7 +13412,10 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) { if (battle_config.cast_rate != 100) time = time * battle_config.cast_rate / 100; // return final cast time - return (time > 0) ? time : 0; + time = max(time, 0); + +// ShowInfo("Castime castfix = %d\n",time); + return time; } /*========================================== @@ -13416,8 +13445,10 @@ int skill_castfix_sc (struct block_list *bl, int time) if (sc->data[SC_IZAYOI]) time -= time * 50 / 100; } - - return (time > 0) ? time : 0; + time = max(time, 0); + +// ShowInfo("Castime castfix_sc = %d\n",time); + return time; } #ifdef RENEWAL_CAST int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill_lv) @@ -13475,6 +13506,8 @@ int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill VARCAST_REDUCTION(sc->data[SC_POEMBRAGI]->val2); if (sc->data[SC_IZAYOI]) VARCAST_REDUCTION(50); + if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WATER)) + VARCAST_REDUCTION(30); //Reduces 30% Variable Cast Time of Water spells. // Fixed cast reduction bonuses if( sc->data[SC__LAZINESS] ) fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2); @@ -13486,7 +13519,7 @@ int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill if( sc->data[SC_MANDRAGORA] && (skill_id >= SM_BASH && skill_id <= RETURN_TO_ELDICASTES) ) fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2; if (sc->data[SC_IZAYOI] && (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN)) - fixed = 0; + fixed = 0; } if( sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){ @@ -13500,7 +13533,8 @@ int skill_vfcastfix (struct block_list *bl, double time, int skill_id, int skill 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; - + + // ShowInfo("Casttime vfcastfix = %d\n",time); return (int)time; } #endif @@ -13580,7 +13614,10 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv) if (sc && sc->count) { if (sc->data[SC_POEMBRAGI]) time -= time * sc->data[SC_POEMBRAGI]->val3 / 100; + if (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WIND)) + time /= 2; // After Delay of Wind element spells reduced by 50%. } + } if( !(delaynodex&4) && sd && sd->delayrate != 100 ) @@ -13589,10 +13626,12 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv) if (battle_config.delay_rate != 100) time = time * battle_config.delay_rate / 100; - if (time < status_get_amotion(bl)) - time = status_get_amotion(bl); // Delay can never be below amotion [Playtester] - - return max(time, battle_config.min_skill_delay_limit); + //min delay + time = max(time, status_get_amotion(bl)); // Delay can never be below amotion [Playtester] + time = max(time, battle_config.min_skill_delay_limit); + +// ShowInfo("Delay delayfix = %d\n",time); + return time; } /*========================================= @@ -17071,16 +17110,8 @@ void skill_cooldown_load(struct map_session_data * sd) } /*========================================== - * DB reading. + * sub-function of DB reading. * skill_db.txt - * skill_require_db.txt - * skill_cast_db.txt - * skill_castnodex_db.txt - * skill_nocast_db.txt - * skill_unit_db.txt - * produce_db.txt - * create_arrow_db.txt - * abra_db.txt *------------------------------------------*/ static bool skill_parse_row_skilldb(char* split[], int columns, int current) @@ -17148,7 +17179,7 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current) skill_split_atoi(split[5],skill_db[i].sp_rate); skill_split_atoi(split[6],skill_db[i].zeny); - //FIXME: document this + //Wich weapon type are required, see doc/item_db for types p = split[7]; for( j = 0; j < 32; j++ ) { @@ -17206,6 +17237,9 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current) else if( strcmpi(split[10],"ridingwarg")==0 ) skill_db[i].state = ST_RIDINGWUG; else if( strcmpi(split[10],"mado")==0 ) skill_db[i].state = ST_MADO; else if( strcmpi(split[10],"elementalspirit")==0 ) skill_db[i].state = ST_ELEMENTALSPIRIT; + else if (strcmpi(split[10], "poisonweapon") == 0) skill_db[i].state = ST_POISONINGWEAPON; + else if (strcmpi(split[10], "rollingcutter") == 0) skill_db[i].state = ST_ROLLINGCUTTER; + /** * Unknown or no state **/ @@ -17215,7 +17249,7 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current) for( j = 0; j < MAX_SKILL_ITEM_REQUIRE; j++ ) { skill_db[i].itemid[j] = atoi(split[12+ 2*j]); skill_db[i].amount[j] = atoi(split[13+ 2*j]); - } + } return true; } @@ -17482,6 +17516,18 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur return true; } +/*=============================== + * DB reading. + * skill_db.txt + * skill_require_db.txt + * skill_cast_db.txt + * skill_castnodex_db.txt + * skill_nocast_db.txt + * skill_unit_db.txt + * produce_db.txt + * create_arrow_db.txt + * abra_db.txt + *------------------------------*/ static void skill_readdb(void) { // init skill db structures |