diff --git a/db/pre-re/skill_cast_db.txt b/db/pre-re/skill_cast_db.txt index 0ced622612..0a0b2c042c 100644 --- a/db/pre-re/skill_cast_db.txt +++ b/db/pre-re/skill_cast_db.txt @@ -159,7 +159,7 @@ //-- WZ_SIGHTRASHER 81,500,2000,0,500,0,0 //-- WZ_METEOR -83,15000,2000:3000:3000:4000:4000:5000:5000:6000:6000:7000,0,500,5000,0 +83,15000,2000:3000:3000:4000:4000:5000:5000:6000:6000:7000,0,2000:3000:3000:4000:4000:5000:5000:6000:6000:7000,5000,0 //-- WZ_JUPITEL 84,2500:3000:3500:4000:4500:5000:5500:6000:6500:7000,0,0,0,0,0 //-- WZ_VERMILION diff --git a/db/re/skill_cast_db.txt b/db/re/skill_cast_db.txt index 420b2feb72..dc68326e6b 100644 --- a/db/re/skill_cast_db.txt +++ b/db/re/skill_cast_db.txt @@ -160,7 +160,7 @@ //-- WZ_SIGHTRASHER 81,320,2000,0,500,0,0,80 //-- WZ_METEOR -83,9600,2000:3000:3000:4000:4000:5000:5000:6000:6000:7000,0,500,5000,0,2400 +83,9600,2000:3000:3000:4000:4000:5000:5000:6000:6000:7000,0,2000:3000:3000:4000:4000:5000:5000:6000:6000:7000,5000,0,2400 //-- WZ_JUPITEL 84,1600:1920:2240:2560:2880:3200:3520:3840:4160:4480,0,0,0,0,0,400:480:560:640:720:800:880:960:1040:1120 //-- WZ_VERMILION @@ -1778,7 +1778,7 @@ //-- SU_CN_POWDERING 5027,1500,1000,0,3000:4000:5000:6000:7000,0,0,0 //-- SU_CN_METEOR -5028,6000,1000,0,500,5000,2000:3000:4000:5000:6000,0 +5028,6000,1000,0,1500:2000:2500:3000:3500,20000,2000:3000:4000:5000:6000,0 //-- SU_SV_ROOTTWIST 5029,0,1000,0,7000:9000:11000:13000:15000,0,3000,0 //-- SU_SV_ROOTTWIST_ATK diff --git a/db/re/skill_unit_db.txt b/db/re/skill_unit_db.txt index b2183b6400..b3669359b7 100644 --- a/db/re/skill_unit_db.txt +++ b/db/re/skill_unit_db.txt @@ -178,7 +178,7 @@ 5013,0x102, , 3, 0, -1,all, 0x2002 //LG_KINGS_GRACE 5027,0x106, , 1:1:2:2:3, 0, -1,enemy, 0x2010 // SU_CN_POWDERING -5028,0x86, , 1, 0,1000,enemy, 0x10 // SU_CN_METEOR +5028,0x86, , 0, 1, 500,enemy, 0x10 // SU_CN_METEOR 5029,0x107, , 0, 0,1000,enemy, 0x10 // SU_SV_ROOTTWIST 8020,0xf5, , 3, 0,2300:2100:1900:1700:1500,enemy, 0x018 //MH_POISON_MIST diff --git a/src/map/skill.c b/src/map/skill.c index 5661746fa6..073621754a 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4110,20 +4110,6 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) break; switch( skl->skill_id ) { - case WZ_METEOR: - case SU_CN_METEOR: - if( skl->type >= 0 ) - { - int x = skl->type>>16, y = skl->type&0xFFFF; - if( path_search_long(NULL, src->m, src->x, src->y, x, y, CELL_CHKWALL) ) - skill_unitsetting(src,skl->skill_id,skl->skill_lv,x,y,skl->flag); - if( path_search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) - && !map_getcell(src->m, skl->x, skl->y, CELL_CHKLANDPROTECTOR) ) - clif_skill_poseffect(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,tick); - } - 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); @@ -11683,35 +11669,20 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case WZ_METEOR: case SU_CN_METEOR: { int area = skill_get_splash(skill_id, skill_lv); - short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0; - + short tmpx = 0, tmpy = 0; if (sd && skill_id == SU_CN_METEOR) { short item_idx = pc_search_inventory(sd, ITEMID_CATNIP_FRUIT); - if (item_idx >= 0) { pc_delitem(sd, item_idx, 1, 0, 1, LOG_TYPE_CONSUME); - skill_area_temp[3] = 1; - } else - skill_area_temp[3] = 0; + flag |= 1; + } } - - for( i = 0; i < 2 + (skill_lv>>1); i++ ) { + for (i = 1; i <= skill_get_time(skill_id, skill_lv)/skill_get_unit_interval(skill_id); i++) { // Creates a random Cell in the Splash Area tmpx = x - area + rnd()%(area * 2 + 1); tmpy = y - area + rnd()%(area * 2 + 1); - - if( i == 0 && path_search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL) - && !map_getcell(src->m, tmpx, tmpy, CELL_CHKLANDPROTECTOR)) - clif_skill_poseffect(src,skill_id,skill_lv,tmpx,tmpy,tick); - - if( i > 0 ) - skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skill_id,skill_lv,(x1<<16)|y1,0); - - x1 = tmpx; - y1 = tmpy; + skill_unitsetting(src, skill_id, skill_lv, tmpx, tmpy, flag+i*skill_get_unit_interval(skill_id)); } - - skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skill_id,skill_lv,-1,0); } break; @@ -12496,6 +12467,7 @@ static bool skill_dance_switch(struct skill_unit* unit, int flag) * @param x Position x * @param y Position y * @param flag &1: Used to determine when the skill 'morphs' (Warp portal becomes active, or Fire Pillar becomes active) + * xx_METEOR: flag &1 contains if the unit can cause curse, flag is also the duration of the unit in milliseconds * @return skill_unit_group */ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_id, uint16 skill_lv, int16 x, int16 y, int flag) @@ -12566,7 +12538,11 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_ case NPC_EVILLAND: val1=skill_lv+3; break; - + case WZ_METEOR: + case SU_CN_METEOR: + limit = flag - (flag&1); + val1 = (flag&1); + break; case WZ_FIREPILLAR: if( map_getcell(src->m, x, y, CELL_CHKLANDPROTECTOR) ) return NULL; @@ -13430,28 +13406,36 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns } while(sg->interval > 0 && x == bl->x && y == bl->y && ++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status_isdead(bl) ); } - break; + break; case WZ_HEAVENDRIVE: status_change_end(bl, SC_SV_ROOTTWIST, INVALID_TIMER); - break; + break; #ifndef RENEWAL // The storm gust counter was dropped in renewal case WZ_STORMGUST: //SG counter does not reset per stormgust. IE: One hit from a SG and two hits from another will freeze you. if (tsc) tsc->sg_counter++; //SG hit counter. if (skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0) <= 0 && tsc) tsc->sg_counter=0; //Attack absorbed. - break; + break; #endif case GS_DESPERADO: if (rnd()%100 < unit->val1) skill_attack(BF_WEAPON,ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - break; + break; + case SU_CN_METEOR: + if (sg->val1) + skill_area_temp[3] = 1; + else + skill_area_temp[3] = 0; + skill_attack(skill_get_type(sg->skill_id),ss,&unit->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; } + //Fall through default: skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0); } @@ -18165,7 +18149,12 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) break; default: + if (group->val2 == 1 && (group->skill_id == WZ_METEOR || group->skill_id == SU_CN_METEOR)) { + // Deal damage before expiration + break; + } skill_delunit(unit); + break; } } else {// skill unit is still active switch( group->unit_id ) { @@ -18220,6 +18209,20 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) skill_delunitgroup(group); } break; + default: + if (group->skill_id == WZ_METEOR || group->skill_id == SU_CN_METEOR) { + if (group->val2 == 0 && (DIFF_TICK(tick, group->tick) >= group->limit - group->interval || DIFF_TICK(tick, group->tick) >= unit->limit - group->interval)) { + // Unit will expire the next interval, start dropping Meteor + struct block_list* src; + if ((src = map_id2bl(group->src_id)) != NULL) { + clif_skill_poseffect(src, group->skill_id, group->skill_lv, bl->x, bl->y, tick); + group->val2 = 1; + } + } + // No damage until expiration + return 0; + } + break; } } @@ -18246,6 +18249,10 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) group->bl_flag= BL_NUL; } } + else if (group->skill_id == WZ_METEOR || group->skill_id == SU_CN_METEOR) { + skill_delunit(unit); + return 0; + } } if( dissonance )