summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorrud0lp20 <rud0lp20@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-09-03 02:50:41 +0000
committerrud0lp20 <rud0lp20@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-09-03 02:50:41 +0000
commit797e2b728c34e2037da494070913bbe2f84a91c2 (patch)
tree3bf01102da3eb9e33b1f9d52a502dace440fd7b2 /src/map
parent424936462f83dc689ae1863cba8b66308b89b416 (diff)
downloadhercules-797e2b728c34e2037da494070913bbe2f84a91c2.tar.gz
hercules-797e2b728c34e2037da494070913bbe2f84a91c2.tar.bz2
hercules-797e2b728c34e2037da494070913bbe2f84a91c2.tar.xz
hercules-797e2b728c34e2037da494070913bbe2f84a91c2.zip
Fixed bugreport:6581 applied balance update to MO_EXTREMITYFIST.
Fixed bugreport:6457 where SR_CURSEDCIRCLE is not remove when target dies. Fixed bugreport:6535 updated GN_CRAZY_WEED to its official behavior. Fixed bugreport:6592 added a missing break in Spiral Pierce skillratio at battle.c. Fixed a faulty skillratio formula of GN_CART_TORNADO. Thanks to Lighta git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16738 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battle.c5
-rw-r--r--src/map/pc.c10
-rw-r--r--src/map/script.c9
-rw-r--r--src/map/skill.c94
-rw-r--r--src/map/status.c16
-rw-r--r--src/map/status.h2
6 files changed, 78 insertions, 58 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 564c08a1f..a3a097c92 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -1997,6 +1997,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
ATK_ADD(weight * skill_lv)
skillratio += 50*skill_lv;
}
+ break;
#endif
case ASC_METEORASSAULT:
skillratio += 40*skill_lv-60;
@@ -2448,7 +2449,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
// ATK [( Skill Level x 50 ) + ( Cart Weight / ( 150 - Caster’s Base STR ))] + ( Cart Remodeling Skill Level x 50 )] %
skillratio = 50 * skill_lv;
if( sd && sd->cart_weight)
- skillratio += sd->cart_weight/10 / (150-sstatus->str) + pc_checkskill(sd, GN_REMODELING_CART) * 50;
+ skillratio += sd->cart_weight/10 / max(150-sstatus->str,1) + pc_checkskill(sd, GN_REMODELING_CART) * 50;
break;
case GN_CARTCANNON:
// ATK [{( Cart Remodeling Skill Level x 50 ) x ( INT / 40 )} + ( Cart Cannon Skill Level x 60 )] %
@@ -5050,7 +5051,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
case MS_MAGNUM:
case RA_DETONATOR:
case RA_SENSITIVEKEEN:
- case GN_CRAZYWEED:
+ case GN_CRAZYWEED_ATK:
case RK_STORMBLAST:
case RK_PHANTOMTHRUST:
case SR_RAMPAGEBLASTER:
diff --git a/src/map/pc.c b/src/map/pc.c
index 8ccccb46c..b370b6296 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -6948,6 +6948,16 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
hp += hp / 10;
sp += sp / 10;
}
+#ifdef RENEWAL
+ if( sd->sc.data[SC_EXTREMITYFIST] ){
+ const struct TimerData *timer;
+ int tick = skill_get_time2(MO_EXTREMITYFIST, sd->sc.data[SC_EXTREMITYFIST]->val1);
+
+ timer = get_timer(sd->sc.data[SC_EXTREMITYFIST]->timer);
+ if( DIFF_TICK(tick, DIFF_TICK(timer->tick, gettick())) < 10000 )// 10 sec
+ sp = 0;
+ }
+#endif
}
return status_heal(&sd->bl, hp, sp, 1);
diff --git a/src/map/script.c b/src/map/script.c
index dfa5cec7f..4e30268d8 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -5350,7 +5350,16 @@ BUILDIN_FUNC(percentheal)
sd = script_rid2sd(st);
if( sd == NULL )
return 0;
+#ifdef RENEWAL
+ if( sd->sc.data[SC_EXTREMITYFIST] ){
+ const struct TimerData *timer;
+ int tick = skill_get_time2(MO_EXTREMITYFIST, sd->sc.data[SC_EXTREMITYFIST]->val1);
+ timer = get_timer(sd->sc.data[SC_EXTREMITYFIST]->timer);
+ if( DIFF_TICK(tick, DIFF_TICK(timer->tick, gettick())) < 10000 )// 10 sec
+ sp = 0;
+ }
+#endif
pc_percentheal(sd,hp,sp);
return 0;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 95570eda6..7ca048ee4 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2398,6 +2398,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case EL_TYPOON_MIS:
case EL_TYPOON_MIS_ATK:
case KO_BAKURETSU:
+ case GN_CRAZYWEED_ATK:
dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,-1,5);
break;
case GN_SLINGITEM_RANGEMELEEATK:
@@ -3242,6 +3243,11 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
else if( path_search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
skill_unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,skl->flag);
break;
+ case GN_CRAZYWEED_ATK:
+ {
+ int dummy = 1, i = skill_get_unit_range(skl->skill_id,skl->skill_lv);
+ map_foreachinarea(skill_cell_overlap, src->m, skl->x-i, skl->y-i, skl->x+i, skl->y+i, BL_SKILL, skl->skill_id, &dummy, src);
+ }
case WL_EARTHSTRAIN:
skill_unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,(skl->type<<16)|skl->flag);
break;
@@ -4450,41 +4456,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
skill_addtimerskill(src, gettick() + skill_get_time(skillid, skilllv) - 1000, bl->id, 0, 0, skillid, skilllv, 0, 0);
}
break;
-
- case GN_CRAZYWEED:
- if( rnd()%100 < 75 ) {
- if( bl->type == BL_SKILL ) {
- struct skill_unit *su = (struct skill_unit *)bl;
- if( !su )
- break;
- if( skill_get_inf2(su->group->skill_id)&INF2_TRAP ) {// Still need confirm it.
- skill_delunit(su);
- break;
- }
- switch( su->group->skill_id ) {// Unconfirmed list, based on info from irowiki.
- case GN_WALLOFTHORN:
- case GN_THORNS_TRAP:
- case SC_BLOODYLUST:
- case SC_CHAOSPANIC:
- case SC_MAELSTROM:
- case WZ_FIREPILLAR:
- case SA_LANDPROTECTOR:
- case SA_VOLCANO:
- case SA_DELUGE:
- case SA_VIOLENTGALE:
- case MG_SAFETYWALL:
- case AL_PNEUMA:
- skill_delunit(su);
- break;
- }
- break;
- }
- else
- skill_attack(BF_WEAPON,src,src,bl,GN_CRAZYWEED_ATK,skilllv,tick,flag);
- }
- break;
-
case EL_FIRE_BOMB:
case EL_FIRE_WAVE:
case EL_WATER_SCREW:
@@ -4589,10 +4561,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
return 1;
}
- if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) { //Should only remove after the skill has been casted.
- sc->data[SC_CURSEDCIRCLE_ATKER]->val3 = 1;
+ if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) //Should only remove after the skill has been casted.
status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
- }
map_freeblock_unlock();
@@ -8850,10 +8820,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if(skillid != SR_CURSEDCIRCLE){
struct status_change *sc = status_get_sc(src);
- if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) { //Should only remove after the skill had been casted.
- sc->data[SC_CURSEDCIRCLE_ATKER]->val3 = 1;
+ if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] )//Should only remove after the skill had been casted.
status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
- }
}
if (dstmd) { //Mob skill event for no damage skills (damage ones are handled in battle_calc_damage) [Skotlex]
@@ -9962,14 +9930,17 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
flag|=1; // Should counsume 1 item per skill usage.
map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv),splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY, skill_castend_damage_id);
break;
+ case GN_CRAZYWEED: {
+ int area = skill_get_splash(GN_CRAZYWEED_ATK, skilllv);
+ short x1 = 0, y1 = 0;
- case GN_CRAZYWEED:
- i = skill_get_splash(skillid,skilllv);
- map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,BL_CHAR|BL_SKILL,
- src,skillid,skilllv,tick,flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- break;
-
+ for( i = 0; i < 3 + (skilllv/2); i++ ) {
+ x1 = x - area + rnd()%(area * 2 + 1);
+ y1 = y - area + rnd()%(area * 2 + 1);
+ skill_addtimerskill(src,tick+i*150,0,x1,y1,GN_CRAZYWEED_ATK,skilllv,-1,0);
+ }
+ }
+ break;
case GN_FIRE_EXPANSION: {
int i;
struct unit_data *ud = unit_bl2ud(src);
@@ -10022,10 +9993,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
return 1;
}
- if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) { //Should only remove after the skill has been casted.
- sc->data[SC_CURSEDCIRCLE_ATKER]->val3 = 1;
+ if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) //Should only remove after the skill has been casted.
status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
- }
if( sd )
{// ensure that the skill last-cast tick is recorded
@@ -11154,7 +11123,12 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if (rnd()%100 < src->val1)
skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
-
+ case GN_CRAZYWEED_ATK:
+ if( bl->type == BL_SKILL ){
+ struct skill_unit *su = (struct skill_unit *)bl;
+ if( su && !(skill_get_inf2(su->group->skill_id)&INF2_TRAP) )
+ break;
+ }
default:
skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
}
@@ -14391,6 +14365,24 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
return 1;
}
break;
+ case GN_CRAZYWEED_ATK:
+ switch(unit->group->unit_id){ //TODO: look for other ground skills that are affected.
+ case UNT_WALLOFTHORN:
+ case UNT_THORNS_TRAP:
+ case UNT_BLOODYLUST:
+ case UNT_CHAOSPANIC:
+ case UNT_MAELSTROM:
+ case UNT_FIREPILLAR_ACTIVE:
+ case UNT_LANDPROTECTOR:
+ case UNT_VOLCANO:
+ case UNT_DELUGE:
+ case UNT_VIOLENTGALE:
+ case UNT_SAFETYWALL:
+ case UNT_PNEUMA:
+ skill_delunit(unit);
+ return 1;
+ }
+ break;
}
if (unit->group->skill_id == SA_LANDPROTECTOR && !(skill_get_inf2(skillid)&(INF2_SONG_DANCE|INF2_TRAP))) { //It deletes everything except songs/dances/traps
diff --git a/src/map/status.c b/src/map/status.c
index bc25b124e..3b8d19114 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -312,7 +312,7 @@ void initChangeTables(void) {
add_sc( MO_BLADESTOP , SC_BLADESTOP_WAIT );
add_sc( MO_BLADESTOP , SC_BLADESTOP );
set_sc( MO_EXPLOSIONSPIRITS , SC_EXPLOSIONSPIRITS, SI_EXPLOSIONSPIRITS, SCB_CRI|SCB_REGEN );
- set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST , SI_BLANK , SCB_REGEN );
+ set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST , SI_EXTREMITYFIST , SCB_REGEN );
add_sc( SA_MAGICROD , SC_MAGICROD );
set_sc( SA_AUTOSPELL , SC_AUTOSPELL , SI_AUTOSPELL , SCB_NONE );
set_sc( SA_FLAMELAUNCHER , SC_FIREWEAPON , SI_FIREWEAPON , SCB_ATK_ELE );
@@ -9209,7 +9209,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
break;
case SC_CURSEDCIRCLE_ATKER:
- if( sce->val3 ) // used the default area size cause there is a chance the caster could knock back and can't clear the target.
+ if( sce->val2 ) // used the default area size cause there is a chance the caster could knock back and can't clear the target.
map_foreachinrange(status_change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
break;
case SC_RAISINGDRAGON:
@@ -9224,8 +9224,15 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
}
break;
- case SC_CURSEDCIRCLE_TARGET:
- clif_bladestop(bl, sce->val2, 0);
+ case SC_CURSEDCIRCLE_TARGET:
+ {
+ struct block_list *src = map_id2bl(sce->val2);
+ struct status_change *sc = status_get_sc(src);
+ if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] && --(sc->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ){
+ status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER);
+ clif_bladestop(bl, sce->val2, 0);
+ }
+ }
break;
case SC_BLOODSUCKER:
if( sce->val2 ){
@@ -10345,6 +10352,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
break;
case SC_CURSEDCIRCLE_TARGET:
if( tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id ) {
+ clif_bladestop(bl, tsc->data[SC_CURSEDCIRCLE_TARGET]->val2, 0);
status_change_end(bl, type, INVALID_TIMER);
}
break;
diff --git a/src/map/status.h b/src/map/status.h
index 5537064ae..442d59986 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -730,7 +730,7 @@ enum si_type {
// SI_BLADESTOP = 85,
SI_EXPLOSIONSPIRITS = 86,
SI_STEELBODY = 87,
-// SI_EXTREMITYFIST = 88,
+ SI_EXTREMITYFIST = 88,
// SI_COMBOATTACK = 89,
SI_FIREWEAPON = 90,
SI_WATERWEAPON = 91,