From 797e2b728c34e2037da494070913bbe2f84a91c2 Mon Sep 17 00:00:00 2001 From: rud0lp20 Date: Mon, 3 Sep 2012 02:50:41 +0000 Subject: 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 --- src/map/battle.c | 5 +-- src/map/pc.c | 10 ++++++ src/map/script.c | 9 ++++++ src/map/skill.c | 94 ++++++++++++++++++++++++++------------------------------ src/map/status.c | 16 +++++++--- src/map/status.h | 2 +- 6 files changed, 78 insertions(+), 58 deletions(-) (limited to 'src/map') 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, -- cgit v1.2.3-70-g09d2