diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 60 | ||||
-rw-r--r-- | src/map/pc.c | 4 | ||||
-rw-r--r-- | src/map/skill.c | 124 | ||||
-rw-r--r-- | src/map/skill.h | 2 | ||||
-rw-r--r-- | src/map/status.c | 42 |
5 files changed, 142 insertions, 90 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index 53d3061ce..5e9fb1bc1 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -352,34 +352,38 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag } if( tsc && tsc->count ) { //since an atk can only have one type let's optimise this a bit switch(atk_elem){ - case ELE_FIRE: - if (tsc->data[SC_SPIDERWEB]) { - tsc->data[SC_SPIDERWEB]->val1 = 0; // free to move now - if( tsc->data[SC_SPIDERWEB]->val2-- > 0 ) - damage <<= 1; // double damage - if( tsc->data[SC_SPIDERWEB]->val2 == 0 ) - status_change_end(target, SC_SPIDERWEB, INVALID_TIMER); - } - if( tsc->data[SC_THORNSTRAP]) - status_change_end(target, SC_THORNSTRAP, INVALID_TIMER); - if( tsc->data[SC_FIRE_CLOAK_OPTION]) - damage -= damage * tsc->data[SC_FIRE_CLOAK_OPTION]->val2 / 100; - if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB){ - status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER); - } - break; - case ELE_HOLY: - if( tsc->data[SC_ORATIO]) - ratio += tsc->data[SC_ORATIO]->val1 * 2; - break; - case ELE_POISON: - if( tsc->data[SC_VENOMIMPRESS]) - ratio += tsc->data[SC_VENOMIMPRESS]->val2; - break; - case ELE_WIND: - if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB) - damage = damage * 150 / 100; - break; + case ELE_FIRE: + if( tsc->data[SC_SPIDERWEB]) { + tsc->data[SC_SPIDERWEB]->val1 = 0; // free to move now + if( tsc->data[SC_SPIDERWEB]->val2-- > 0 ) + damage <<= 1; // double damage + if( tsc->data[SC_SPIDERWEB]->val2 == 0 ) + status_change_end(target, SC_SPIDERWEB, INVALID_TIMER); + } + if( tsc->data[SC_THORNSTRAP]) + status_change_end(target, SC_THORNSTRAP, INVALID_TIMER); + if( tsc->data[SC_FIRE_CLOAK_OPTION]) + damage -= damage * tsc->data[SC_FIRE_CLOAK_OPTION]->val2 / 100; + if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB) + status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER); + if( tsc->data[SC_EARTH_INSIGNIA]) damage += damage/2; + break; + case ELE_HOLY: + if( tsc->data[SC_ORATIO]) ratio += tsc->data[SC_ORATIO]->val1 * 2; + break; + case ELE_POISON: + if( tsc->data[SC_VENOMIMPRESS]) ratio += tsc->data[SC_VENOMIMPRESS]->val2; + break; + case ELE_WIND: + if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB) damage += damage/2; + if( tsc->data[SC_WATER_INSIGNIA]) damage += damage/2; + break; + case ELE_WATER: + if( tsc->data[SC_FIRE_INSIGNIA]) damage += damage/2; + break; + case ELE_EARTH: + if( tsc->data[SC_WIND_INSIGNIA]) damage += damage/2; + break; } } //end tsc check if( src && src->type == BL_PC ){ diff --git a/src/map/pc.c b/src/map/pc.c index d87ea9277..779a8fb22 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -2020,7 +2020,7 @@ int pc_bonus_subele(struct map_session_data* sd, unsigned char ele, short rate, } /*========================================== - * ? ???i????\????~{??i?X??? + * Add a bonus(type) to player sd *------------------------------------------*/ int pc_bonus(struct map_session_data *sd,int type,int val) { @@ -8944,7 +8944,7 @@ void pc_setstand(struct map_session_data *sd){ nullpo_retv(sd); status_change_end(&sd->bl, SC_TENSIONRELAX, INVALID_TIMER); - + clif_status_load(&sd->bl,SI_SIT,0); //Reset sitting tick. sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0; sd->state.dead_sit = sd->vd.dead_sit = 0; 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 diff --git a/src/map/skill.h b/src/map/skill.h index 5225afb77..effb6164b 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -398,6 +398,8 @@ enum { ST_RIDINGWUG, ST_MADO, ST_ELEMENTALSPIRIT, + ST_POISONINGWEAPON, + ST_ROLLINGCUTTER, }; enum e_skill { diff --git a/src/map/status.c b/src/map/status.c index 9300a2082..695548e88 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -670,10 +670,10 @@ void initChangeTables(void) { set_sc( SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE ); set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE ); set_sc( SO_ARRULLO , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE ); - set_sc( SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SI_FIRE_INSIGNIA , SCB_MATK ); - set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_NONE ); - set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_NONE ); - set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK ); + set_sc( SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SI_FIRE_INSIGNIA , SCB_MATK | SCB_BATK | SCB_WATK | SCB_ATK_ELE | SCB_REGEN ); + set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN ); + set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN ); + set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN ); /** * Genetic **/ @@ -3433,6 +3433,11 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str regen->hp = cap_value(regen->hp*sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX); regen->state.walk= 1; } + if ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1) //if insignia lvl 1 + || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1) + || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1) + || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)) + regen->rate.hp *= 2; } void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start ) { @@ -5283,9 +5288,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change * if(sc->data[SC_BERSERK]) aspd_rate -= 300; - else - - if(sc->data[SC_MADNESSCANCEL]) + else if(sc->data[SC_MADNESSCANCEL]) aspd_rate -= 200; } @@ -5496,21 +5499,16 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch if(sc->data[SC_ENCHANTARMS]) return sc->data[SC_ENCHANTARMS]->val2; if(sc->data[SC_WATERWEAPON] - || sc->data[SC_TIDAL_WEAPON_OPTION] - || sc->data[SC_TIDAL_WEAPON] - || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) ) + || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) ) return ELE_WATER; - if(sc->data[SC_EARTHWEAPON] || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) ) - return ELE_EARTH; - if(sc->data[SC_FIREWEAPON] || (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) ) - return ELE_FIRE; - if(sc->data[SC_WINDWEAPON] || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2) ) - return ELE_WIND; - if(sc->data[SC_EARTHWEAPON]) + if(sc->data[SC_EARTHWEAPON] + || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) ) return ELE_EARTH; - if(sc->data[SC_FIREWEAPON]) + if(sc->data[SC_FIREWEAPON] + || (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) ) return ELE_FIRE; - if(sc->data[SC_WINDWEAPON]) + if(sc->data[SC_WINDWEAPON] + || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2) ) return ELE_WIND; if(sc->data[SC_ENCPOISON]) return ELE_POISON; @@ -6378,7 +6376,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_INCREASEAGI: if(sd && pc_issit(sd)){ pc_setstand(sd); - clif_status_load(&sd->bl,SI_SIT,0); } case SC_CONCENTRATE: @@ -6572,6 +6569,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val if(sc->data[i]) return 0; } break; + case SC_INTRAVISION: + if(sd && sd->special_state.intravision) return 0; //we already have the status by maya P + break; } //Check for BOSS resistances @@ -10118,7 +10118,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_SATURDAYNIGHTFEVER: - // 1% HP/SP drain every 3 seconds [Jobbie] + // 1% HP/SP drain every val4 seconds [Jobbie] if( --(sce->val3) >= 0 ) { int hp = status->hp / 100; |