diff options
author | rud0lp20 <rud0lp20@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-07-11 15:10:07 +0000 |
---|---|---|
committer | rud0lp20 <rud0lp20@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-07-11 15:10:07 +0000 |
commit | aa2704d3cc98ef565a24f3e59d6f8ee3bffcbfe7 (patch) | |
tree | d4138ae2654f476f6d7674c94d5bfd263ab06f17 /src | |
parent | a673d5b975c6e2fa3fc2984dcaa833b17e0e0dfe (diff) | |
download | hercules-aa2704d3cc98ef565a24f3e59d6f8ee3bffcbfe7.tar.gz hercules-aa2704d3cc98ef565a24f3e59d6f8ee3bffcbfe7.tar.bz2 hercules-aa2704d3cc98ef565a24f3e59d6f8ee3bffcbfe7.tar.xz hercules-aa2704d3cc98ef565a24f3e59d6f8ee3bffcbfe7.zip |
Fixed bugreport:6178 where SR_CRESCENTELBOW doesn't work with skills and WM_POEMOFNETHERWORLD should now work with single target and show proper animation.
Fixed bugreport:6182 Cloaking skills should now be reveal by AOE skills and additional to that is TF_HIDING should now be only reveal by ground skills(earth) and revealing skills.
Fixed bugreport:6188 Leech End should now show flinching damage and updated its damage formula
Fixed Guillotine Cross poisons where the effect should not stack to each other, updated Oblivion Curse status def formula and Pyrexia's blinding effect.
Fixed Fighting spirit's ASPD bonus thanks to Igniz for pointing it out..
Fixed WM_REVERBERATION display animation when triggers and activated by WM_DOMINION_IMPULSE.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16399 54d463be-8e91-2dee-dedb-b68131a5f0ec
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, |