summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/battle.c29
-rw-r--r--src/map/skill.c84
-rw-r--r--src/map/status.c49
-rw-r--r--src/map/status.h43
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,