diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/battle.c | 29 | ||||
-rw-r--r-- | src/map/skill.c | 84 | ||||
-rw-r--r-- | src/map/status.c | 49 | ||||
-rw-r--r-- | src/map/status.h | 43 |
4 files changed, 104 insertions, 101 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index 20b8fa3dc..0857de951 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -784,7 +784,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag } } if( sc->data[SC_POISONINGWEAPON] && skill_num != GC_VENOMPRESSURE && (flag&BF_WEAPON) && damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3 ) - sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON,sc->data[SC_POISONINGWEAPON]->val1)); + sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1)); if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 ) status_change_spread(src, bl); } @@ -4218,7 +4218,18 @@ int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int int max_damage = status_get_max_hp(bl) * status_get_lv(bl) / 100; rdamage = (*dmg) * sc->data[SC_REFLECTDAMAGE]->val2 / 100; if( rdamage > max_damage ) rdamage = max_damage; - } else if (flag & BF_SHORT) {//Bounces back part of the damage. + }else if( sc && sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){ + //ATK [{(Target’s HP / 100) x Skill Level} x Caster’s Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}] + int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status_get_lv(bl) / 125; + if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK + rdamage = rdamage * ratio / 100 + (*dmg) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10; + clif_damage(src, bl, gettick(), status_get_amotion(src)+1000, 0, status_damage(src, bl, rdamage/10, 0, 0, 1), 1, 0, 0); + skill_blown(bl, src, skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit_getdir(src), 0); + clif_skill_damage(bl, src, gettick(), status_get_amotion(src), 0, status_damage(src, bl, rdamage, 0, 0, 1), + 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does + status_change_end(bl, SC_CRESCENTELBOW, INVALID_TIMER); + return 0; // Just put here to minimize redundancy + }else if (flag & BF_SHORT) {//Bounces back part of the damage. if ( sd && sd->bonus.short_weapon_damage_return ) { rdamage += damage * sd->bonus.short_weapon_damage_return / 100; if(rdamage < 1) rdamage = 1; @@ -4241,11 +4252,6 @@ int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int if (rdamage < 1) rdamage = 1; } } - if( sc && sc->data[SC_CRESCENTELBOW] && !(flag&BF_SKILL) && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ) - { // Stimated formula from test - rdamage += (int)((*dmg) + (*dmg) * status_get_hp(src) * 2.15 / 100000); - if( rdamage < 1 ) rdamage = 1; - } } } else { if (sd && sd->bonus.long_weapon_damage_return) { @@ -4532,15 +4538,8 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if( rdamage > 0 ) { if( tsc && tsc->data[SC_REFLECTDAMAGE] ) { if( src != target )// Don't reflect your own damage (Grand Cross) - map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,wd.dmotion,rdamage,tstatus->race,0); + map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,wd.dmotion,rdamage,tstatus->race,0); } else { - if( tsc && tsc->data[SC_CRESCENTELBOW] ) { // Deal rdamage to src and 10% damage back to target. - clif_skill_nodamage(target,target,SR_CRESCENTELBOW_AUTOSPELL,tsc->data[SC_CRESCENTELBOW]->val1,1); - skill_blown(target,src,skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL,tsc->data[SC_CRESCENTELBOW]->val1),unit_getdir(src),0); - status_damage(NULL,target,rdamage/10,0,0,1); - clif_damage(target, target, tick, wd.amotion, wd.dmotion, rdamage/10, wd.div_ , wd.type, wd.damage2); - status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER); - } rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0); //Use Reflect Shield to signal this kind of skill trigger. [Skotlex] skill_additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); diff --git a/src/map/skill.c b/src/map/skill.c index 122a3fb8d..98bb181a3 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2620,7 +2620,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds battle_delay_damage(tick, dmg.amotion,bl,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,0); else status_fix_damage(bl,src,rdamage,0); - clif_damage(src,src,tick, dmg.amotion,0,rdamage,dmg.div_>1?dmg.div_:1,4,0); + clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0); // in aegis damage reflected is shown in single hit. //Use Reflect Shield to signal this kind of skill trigger. [Skotlex] if( tsd && src != bl ) battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); @@ -2638,7 +2638,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds case GC_VENOMPRESSURE: { struct status_change *ssc = status_get_sc(src); if( ssc && ssc->data[SC_POISONINGWEAPON] && rnd()%100 < 70 + 5*skilllv ) { - sc_start(bl,ssc->data[SC_POISONINGWEAPON]->val2,100,ssc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON,ssc->data[SC_POISONINGWEAPON]->val1)); + sc_start(bl,ssc->data[SC_POISONINGWEAPON]->val2,100,ssc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1)); status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); clif_skill_nodamage(src,bl,skillid,skilllv,1); } @@ -3234,9 +3234,8 @@ static int skill_ative_reverberation( struct block_list *bl, va_list ap) { if( bl->type != BL_SKILL ) return 0; if( su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION ) { - clif_changetraplook(bl, UNT_USED_TRAPS); map_foreachinrange(skill_trap_splash, bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, gettick()); - su->limit=DIFF_TICK(gettick(),sg->tick)+1500; + su->limit=DIFF_TICK(gettick(),sg->tick); sg->unit_id = UNT_USED_TRAPS; } return 0; @@ -3388,7 +3387,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case NPC_HELLPOWER: case RK_SONICWAVE: case RK_HUNDREDSPEAR: - case RK_WINDCUTTER: case AB_DUPLELIGHT_MELEE: case RA_AIMEDBOLT: case NC_AXEBOOMERANG: @@ -3402,7 +3400,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case LG_RAGEBURST: case LG_RAYOFGENESIS: case LG_HESPERUSLIT: - case SR_SKYNETBLOW: case SR_FALLENEMPIRE: case SR_CRESCENTELBOW_AUTOSPELL: case SR_GATEOFHELL: @@ -3423,7 +3420,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case NC_COLDSLOWER: case NC_ARMSCANNON: if (sd) pc_overheat(sd,1); - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); + case RK_WINDCUTTER: + skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag|SD_ANIMATION); break; case LK_JOINTBEAT: // decide the ailment first (affects attack damage and effect) @@ -3620,6 +3618,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case WL_SOULEXPANSION: case WL_CRIMSONROCK: case WL_COMET: + case WL_JACKFROST: case RA_ARROWSTORM: case RA_WUGDASH: case NC_SELFDESTRUCTION: @@ -3630,6 +3629,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case LG_EARTHDRIVE: case SR_TIGERCANNON: case SR_RAMPAGEBLASTER: + case SR_SKYNETBLOW: case SR_WINDMILL: case SR_RIDEINLIGHTNING: case WM_SOUND_OF_DESTRUCTION: @@ -3666,7 +3666,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int break; case NPC_EARTHQUAKE://FIXME: Isn't EarthQuake a ground skill after all? skill_addtimerskill(src,tick+250,src->id,0,0,skillid,skilllv,2,flag|BCT_ENEMY|SD_SPLASH|1); - break; default: break; } @@ -3678,6 +3677,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int skill_area_temp[4] = bl->x; skill_area_temp[5] = bl->y; } + if( skillid == WM_REVERBERATION_MELEE || skillid == WM_REVERBERATION_MAGIC ) + skill_area_temp[1] = 0; // if skill damage should be split among targets, count them //SD_LEVEL -> Forced splash damage for Auto Blitz-Beat -> count targets //special case: Venom Splasher uses a different range for searching than for splashing @@ -4185,24 +4186,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int } break; case WL_FROSTMISTY: - { - struct status_change *tsc = status_get_sc(bl); - if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY]) ) - break; // Doesn't hit/cause Freezing to invisible enemy // Causes Freezing status through walls. sc_start(bl,status_skill2sc(skillid),20+12*skilllv+(sd ? sd->status.job_level : 50)/5,skilllv,skill_get_time(skillid,skilllv)); // Doesn't deal damage through non-shootable walls. if( path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKWALL) ) - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - } - break; - - case WL_JACKFROST: { - struct status_change *tsc = status_get_sc(bl); - if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY]) ) - break; // Do not hit invisible enemy - skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag); - } + skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag|SD_ANIMATION); break; case WL_HELLINFERNO: skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); @@ -4325,7 +4313,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER); status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER); status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER); - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag); + skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag|SD_ANIMATION); break; case SR_EARTHSHAKER: @@ -9579,7 +9567,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk } clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skillid,skilllv,6); skill_unitsetting(src, skillid, skilllv, x, y, flag); - status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); + //status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); // 08/31/2011 - When using poison smoke, you no longer lose the poisoning weapon effect. break; /** * Arch Bishop @@ -10312,7 +10300,6 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli case GC_POISONSMOKE: if( !(sc && sc->data[SC_POISONINGWEAPON]) ) return NULL; - val1 = sc->data[SC_POISONINGWEAPON]->val1; // Level of Poison, to determine poisoning time val2 = sc->data[SC_POISONINGWEAPON]->val2; // Type of Poison limit = 4000 + 2000 * skilllv; break; @@ -11161,7 +11148,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns **/ case UNT_POISONSMOKE: if( battle_check_target(ss,bl,BCT_ENEMY) > 0 && !(tsc && tsc->data[sg->val2]) && rnd()%100 < 20 ) - sc_start(bl,sg->val2,100,sg->val1,skill_get_time2(GC_POISONINGWEAPON,sg->val1)); + sc_start(bl,sg->val2,100,sg->val1,skill_get_time2(GC_POISONINGWEAPON, 1)); break; case UNT_EPICLESIS: @@ -11209,7 +11196,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_REVERBERATION: clif_changetraplook(&src->bl,UNT_USED_TRAPS); map_foreachinrange(skill_trap_splash,&src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick); - sg->limit = DIFF_TICK(tick,sg->tick) + 1500; + sg->limit = DIFF_TICK(tick,sg->tick)+1000; sg->unit_id = UNT_USED_TRAPS; break; @@ -11218,9 +11205,12 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns skill_attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0); break; case UNT_NETHERWORLD: - if( !(status_get_mode(bl)&MD_BOSS) ) { - if( !(tsc && tsc->data[type]) ) + if( !(status_get_mode(bl)&MD_BOSS) && ss != bl && battle_check_target(&src->bl, bl, BCT_PARTY) ) { + if( !(tsc && tsc->data[type]) ){ sc_start(bl, type, 100, sg->skill_lv, skill_get_time2(sg->skill_id,sg->skill_lv)); + sg->limit = DIFF_TICK(tick,sg->tick); + sg->unit_id = UNT_USED_TRAPS; + } } break; case UNT_THORNS_TRAP: @@ -12317,9 +12307,10 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh if( !(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO) ) return 0; break; + case SR_CRESCENTELBOW: if( sc && sc->data[SC_CRESCENTELBOW] ) { - clif_skill_fail(sd,skill,0,0); + clif_skill_fail(sd, skill, USESKILL_FAIL_DUPLICATE, 0); return 0; } break; @@ -14037,8 +14028,8 @@ static int skill_trap_splash (struct block_list *bl, va_list ap) clif_skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,5); break; case UNT_REVERBERATION: - skill_addtimerskill(ss,tick+50,bl->id,0,0,WM_REVERBERATION_MELEE,sg->skill_lv,BF_WEAPON,SD_LEVEL); // for proper skill delay animation when use with Dominion Impulse - skill_addtimerskill(ss,tick+250,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,SD_LEVEL); + skill_addtimerskill(ss,tick+50,bl->id,0,0,WM_REVERBERATION_MELEE,sg->skill_lv,BF_WEAPON,0); // for proper skill delay animation when use with Dominion Impulse + skill_addtimerskill(ss,tick+250,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,0); break; case UNT_SEVERE_RAINSTORM: skill_attack(BF_WEAPON,ss,ss,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0); @@ -14687,8 +14678,8 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) } clif_changetraplook(bl,UNT_USED_TRAPS); map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); - group->limit = DIFF_TICK(tick,group->tick) + 1500; - unit->limit = DIFF_TICK(tick,group->tick) + 1500; + group->limit = DIFF_TICK(tick,group->tick)+1000; + unit->limit = DIFF_TICK(tick,group->tick)+1000; group->unit_id = UNT_USED_TRAPS; break; @@ -14753,8 +14744,8 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) if( unit->val1 <= 0 ){ clif_changetraplook(bl,UNT_USED_TRAPS); map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); - group->limit = DIFF_TICK(tick,group->tick) + 1500; - unit->limit = DIFF_TICK(tick,group->tick) + 1500; + group->limit = DIFF_TICK(tick,group->tick)+1000; + unit->limit = DIFF_TICK(tick,group->tick)+1000; group->unit_id = UNT_USED_TRAPS; } break; @@ -15668,7 +15659,7 @@ int skill_arrow_create (struct map_session_data *sd, int nameid) } int skill_poisoningweapon( struct map_session_data *sd, int nameid) { sc_type type; - int t_lv = 0, chance, i; + int chance, i; nullpo_ret(sd); if( nameid <= 0 || (i = pc_search_inventory(sd,nameid)) < 0 || pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) ) { clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0); @@ -15676,21 +15667,22 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) { } switch( nameid ) { // t_lv used to take duration from skill_get_time2 - case PO_PARALYSE: type = SC_PARALYSE; t_lv = 1; break; - case PO_PYREXIA: type = SC_PYREXIA; t_lv = 2; break; - case PO_DEATHHURT: type = SC_DEATHHURT; t_lv = 3; break; - case PO_LEECHESEND: type = SC_LEECHESEND; t_lv = 4; break; - case PO_VENOMBLEED: type = SC_VENOMBLEED; t_lv = 6; break; - case PO_TOXIN: type = SC_TOXIN; t_lv = 7; break; - case PO_MAGICMUSHROOM: type = SC_MAGICMUSHROOM; t_lv = 8; break; - case PO_OBLIVIONCURSE: type = SC_OBLIVIONCURSE; t_lv = 9; break; + case PO_PARALYSE: type = SC_PARALYSE; break; + case PO_PYREXIA: type = SC_PYREXIA; break; + case PO_DEATHHURT: type = SC_DEATHHURT; break; + case PO_LEECHESEND: type = SC_LEECHESEND; break; + case PO_VENOMBLEED: type = SC_VENOMBLEED; break; + case PO_TOXIN: type = SC_TOXIN; break; + case PO_MAGICMUSHROOM: type = SC_MAGICMUSHROOM; break; + case PO_OBLIVIONCURSE: type = SC_OBLIVIONCURSE; break; default: clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0); return 0; } chance = 2 + 2 * sd->menuskill_val; // 2 + 2 * skill_lv - sc_start4(&sd->bl,SC_POISONINGWEAPON,100,t_lv,type,chance,0,skill_get_time(GC_POISONINGWEAPON,sd->menuskill_val)); + sc_start4(&sd->bl, SC_POISONINGWEAPON, 100, pc_checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1 + type, chance, 0, skill_get_time(GC_POISONINGWEAPON, sd->menuskill_val)); return 0; } diff --git a/src/map/status.c b/src/map/status.c index 80e27844a..5bd894336 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -640,7 +640,7 @@ void initChangeTables(void) { set_sc( MI_RUSH_WINDMILL , SC_RUSHWINDMILL , SI_RUSHWINDMILL , SCB_BATK ); set_sc( MI_ECHOSONG , SC_ECHOSONG , SI_ECHOSONG , SCB_DEF2 ); set_sc( MI_HARMONIZE , SC_HARMONIZE , SI_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK ); - set_sc( WM_POEMOFNETHERWORLD , SC_STOP , SI_NETHERWORLD , SCB_NONE ); + set_sc_with_vfx( WM_POEMOFNETHERWORLD , SC_NETHERWORLD , SI_NETHERWORLD , SCB_NONE ); set_sc( WM_VOICEOFSIREN , SC_VOICEOFSIREN , SI_VOICEOFSIREN , SCB_NONE ); set_sc( WM_LULLABY_DEEPSLEEP , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE ); set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE ); @@ -980,6 +980,7 @@ void initChangeTables(void) { StatusChangeStateTable[SC_CURSEDCIRCLE_ATKER] |= SCS_NOMOVE; StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOMOVE; StatusChangeStateTable[SC_CRYSTALIZE] |= SCS_NOMOVE|SCS_NOMOVECOND; + StatusChangeStateTable[SC_NETHERWORLD] |= SCS_NOMOVE; /* StatusChangeState (SCS_) NOPICKUPITEMS */ StatusChangeStateTable[SC_HIDING] |= SCS_NOPICKITEM; @@ -1645,6 +1646,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int if(sc->option&OPTION_MOUNTING) return 0;//New mounts can't attack nor use skills in the client; this check makes it cheat-safe [Ind] } + if (target == NULL || target == src) //No further checking needed. return 1; @@ -1668,7 +1670,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int //You cannot hide from ground skills. if( skill_get_ele(skill_num,1) == ELE_EARTH ) //TODO: Need Skill Lv here :/ hide_flag &= ~OPTION_HIDE; - + switch( target->type ) { case BL_PC: { struct map_session_data *sd = (TBL_PC*) target; @@ -1681,8 +1683,6 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int return 0; if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_num ) return 0; - if( tsc->data[SC_CLOAKINGEXCEED] && !is_boss ) - return 0; if( tsc->data[SC_STEALTHFIELD] && !is_boss ) return 0; } @@ -5118,7 +5118,7 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] ) skills2 -= 50; if( sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 ) - skills2 += sc->data[SC_FIGHTINGSPIRIT]->val2; + skills2 += 4; if( sc->data[SC_PARALYSE] ) skills2 -= 10; if( sc->data[SC__BODYPAINT] ) @@ -6036,8 +6036,9 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti tick -= 1000 * ((status->vit + status->dex) / 20); tick = max(tick,10000); // Minimum Duration 10s. break; - case SC_OBLIVIONCURSE: - sc_def = status->int_*4/5; //FIXME: info said this is the formula of status chance. Check again pls. [Jobbie] + case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT) + sc_def = 100 - ( 100 - status->int_* 8 / 10 ); + sc_def = max(sc_def, 5); // minimum of 5% break; case SC_ELECTRICSHOCKER: case SC_BITE: { @@ -6494,6 +6495,20 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; + case SC_TOXIN: + case SC_PARALYSE: + case SC_VENOMBLEED: + case SC_MAGICMUSHROOM: + case SC_DEATHHURT: + case SC_PYREXIA: + case SC_OBLIVIONCURSE: + case SC_LEECHESEND: + { // it doesn't stack or even renewed + int i = SC_TOXIN; + for(; i<= SC_LEECHESEND; i++) + if(sc->data[i]) return 0; + } + break; } //Check for BOSS resistances @@ -7761,6 +7776,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val tick_time = 4000; // [GodLesZ] tick time break; 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 break; @@ -8246,6 +8262,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_CURSEDCIRCLE_ATKER: case SC_CURSEDCIRCLE_TARGET: case SC_FEAR: + case SC_NETHERWORLD: unit_stop_walking(bl,1); break; case SC_HIDING: @@ -9677,11 +9694,9 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_PYREXIA: if( --(sce->val4) >= 0 ) { map_freeblock_lock(); - clif_damage(bl,bl,tick,status_get_amotion(bl),0,100,0,0,0); + clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0); status_fix_damage(NULL,bl,100,0); if( sc->data[type] ) { - if( sce->val4 == 10 ) - sc_start(bl,SC_BLIND,100,sce->val1,30000); // Blind status for the final 30 seconds sc_timer_next(3000+tick,status_change_timer,bl->id,data); } map_freeblock_unlock(); @@ -9691,16 +9706,11 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_LEECHESEND: if( --(sce->val4) >= 0 ) { - int damage = status->max_hp/100; - if( sd && (sd->status.class_ == JOB_GUILLOTINE_CROSS || sd->status.class_ == JOB_GUILLOTINE_CROSS_T ) ) - damage += 3 * status->vit; - else - damage += 7 * status->vit; - - unit_skillcastcancel(bl,0); - + int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100) + damage += status->vit * (sce->val1 - 3); + unit_skillcastcancel(bl,0); map_freeblock_lock(); - status_zap(bl,damage,0); + status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1); if( sc->data[type] ) { sc_timer_next(1000 + tick, status_change_timer, bl->id, data ); } @@ -10287,6 +10297,7 @@ int status_change_clear_buffs (struct block_list* bl, int type) case SC_BURNING: case SC_FEAR: case SC_MAGNETICFIELD: + case SC_NETHERWORLD: if (!(type&2)) continue; break; diff --git a/src/map/status.h b/src/map/status.h index 532eb8d13..b5a00b91e 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -478,13 +478,14 @@ typedef enum sc_type { SC_BEYONDOFWARCRY, SC_UNLIMITEDHUMMINGVOICE,//410 SC_SITDOWN_FORCE, + SC_NETHERWORLD, /** * Sura **/ SC_CRESCENTELBOW, SC_CURSEDCIRCLE_ATKER, SC_CURSEDCIRCLE_TARGET, - SC_LIGHTNINGWALK,//415 + SC_LIGHTNINGWALK,//416 SC_RAISINGDRAGON, SC_GT_ENERGYGAIN, SC_GT_CHANGE, @@ -492,27 +493,27 @@ typedef enum sc_type { /** * Genetic **/ - SC_GN_CARTBOOST,//420 + SC_GN_CARTBOOST,//427 SC_THORNSTRAP, SC_BLOODSUCKER, SC_SMOKEPOWDER, SC_TEARGAS, - SC_MANDRAGORA,//425 + SC_MANDRAGORA,//426 SC_STOMACHACHE, SC_MYSTERIOUS_POWDER, SC_MELON_BOMB, SC_BANANA_BOMB, - SC_BANANA_BOMB_SITDOWN,//430 + SC_BANANA_BOMB_SITDOWN,//431 SC_SAVAGE_STEAK, SC_COCKTAIL_WARG_BLOOD, SC_MINOR_BBQ, SC_SIROMA_ICE_TEA, - SC_DROCERA_HERB_STEAMED,//435 + SC_DROCERA_HERB_STEAMED,//436 SC_PUTTI_TAILS_NOODLES, SC_BOOST500, SC_FULL_SWING_K, SC_MANA_PLUS, - SC_MUSTLE_M,//440 + SC_MUSTLE_M,//441 SC_LIFE_FORCE_F, SC_EXTRACT_WHITE_POTION_Z, SC_VITATA_500, @@ -520,21 +521,21 @@ typedef enum sc_type { /** * Shadow Chaser **/ - SC__REPRODUCE,//445 + SC__REPRODUCE,//446 SC__AUTOSHADOWSPELL, SC__SHADOWFORM, SC__BODYPAINT, SC__INVISIBILITY, - SC__DEADLYINFECT,//450 + SC__DEADLYINFECT,//451 SC__ENERVATION, SC__GROOMY, SC__IGNORANCE, SC__LAZINESS, - SC__UNLUCKY,//455 + SC__UNLUCKY,//456 SC__WEAKNESS, SC__STRIPACCESSORY, SC__MANHOLE, - SC__BLOODYLUST,//459 + SC__BLOODYLUST,//460 /** * Elemental Spirits **/ @@ -542,53 +543,53 @@ typedef enum sc_type { SC_CIRCLE_OF_FIRE_OPTION, SC_FIRE_CLOAK, SC_FIRE_CLOAK_OPTION, - SC_WATER_SCREEN,//464 + SC_WATER_SCREEN,//465 SC_WATER_SCREEN_OPTION, SC_WATER_DROP, SC_WATER_DROP_OPTION, SC_WATER_BARRIER, - SC_WIND_STEP,//469 + SC_WIND_STEP,//470 SC_WIND_STEP_OPTION, SC_WIND_CURTAIN, SC_WIND_CURTAIN_OPTION, SC_ZEPHYR, - SC_SOLID_SKIN,//474 + SC_SOLID_SKIN,//475 SC_SOLID_SKIN_OPTION, SC_STONE_SHIELD, SC_STONE_SHIELD_OPTION, SC_POWER_OF_GAIA, - SC_PYROTECHNIC,//479 + SC_PYROTECHNIC,//480 SC_PYROTECHNIC_OPTION, SC_HEATER, SC_HEATER_OPTION, SC_TROPIC, - SC_TROPIC_OPTION,//484 + SC_TROPIC_OPTION,//485 SC_AQUAPLAY, SC_AQUAPLAY_OPTION, SC_COOLER, SC_COOLER_OPTION, - SC_CHILLY_AIR,//489 + SC_CHILLY_AIR,//490 SC_CHILLY_AIR_OPTION, SC_GUST, SC_GUST_OPTION, SC_BLAST, - SC_BLAST_OPTION,//494 + SC_BLAST_OPTION,//495 SC_WILD_STORM, SC_WILD_STORM_OPTION, SC_PETROLOGY, SC_PETROLOGY_OPTION, - SC_CURSED_SOIL,//499 + SC_CURSED_SOIL,//500 SC_CURSED_SOIL_OPTION, SC_UPHEAVAL, SC_UPHEAVAL_OPTION, SC_TIDAL_WEAPON, - SC_TIDAL_WEAPON_OPTION,//504 + SC_TIDAL_WEAPON_OPTION,//505 SC_ROCK_CRUSHER, SC_ROCK_CRUSHER_ATK, /* Guild Aura */ SC_LEADERSHIP, SC_GLORYWOUNDS, - SC_SOULCOLD, //509 + SC_SOULCOLD, //508 SC_HAWKEYES, /* ... */ SC_ODINS_POWER, @@ -596,7 +597,7 @@ typedef enum sc_type { /* Sorcerer .extra */ SC_FIRE_INSIGNIA, SC_WATER_INSIGNIA, - SC_WIND_INSIGNIA, //515 + SC_WIND_INSIGNIA, //516 SC_EARTH_INSIGNIA, /* new pushcart */ SC_PUSH_CART, |