diff --git a/db/pre-re/skill_db.txt b/db/pre-re/skill_db.txt index 67c98a5e77..5e39d3bafe 100644 --- a/db/pre-re/skill_db.txt +++ b/db/pre-re/skill_db.txt @@ -48,7 +48,7 @@ // 14 attack type (none, weapon, magic, misc) // 15 Blowcount (amount of tiles skill knockbacks) // 16 inf3 (skill information 3): -// 0x00001 - skill ignores land protector (e.g. arrow shower) +// 0x00001 - skill ignores land protector // 0x00002 - skill that doesn't end camouflage // 0x00004 - usable skills while hiding // 0x00008 - skill that can be use while in dancing state diff --git a/db/pre-re/skill_unit_db.txt b/db/pre-re/skill_unit_db.txt index 8d0a9d9c9d..ec83ae701f 100644 --- a/db/pre-re/skill_unit_db.txt +++ b/db/pre-re/skill_unit_db.txt @@ -36,7 +36,6 @@ 21,0x86, , 0, 2:2:2:2:2:2:2:2:2:2:3,1000,enemy, 0x010 //MG_THUNDERSTORM 25,0x85, , 1, 0, -1,all, 0x6003 //AL_PNEUMA 27,0x81,0x80, 0, 0, -1,all, 0x00E //AL_WARP - 47,0x86, , 0, 2,1000,enemy, 0x080 //AC_SHOWER 70,0x83, , -1, 1,1000,all, 0x018 //PR_SANCTUARY 79,0x84, , -1, 1,3000,enemy, 0x8018 //PR_MAGNUS 80,0x87,0x88, 0, 1,2000,enemy, 0x4006 //WZ_FIREPILLAR @@ -84,7 +83,7 @@ 329,0xae, , 3, 0, -1,all, 0x140 //DC_FORTUNEKISS 330,0xaf, , 3, 0, -1,all, 0x140 //DC_SERVICEFORYOU 336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER -339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_DARKGRANDCROSS +339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_GRANDDARKNESS 362,0xb4, , 2, 0, 300,all, 0x2000 //HP_BASILICA 369,0xb3, , -1, 0,10000,all, 0x008 //PA_GOSPEL 395,0xb5, , 4, 0, -1,all, 0x200 //CG_MOONLIT @@ -95,7 +94,7 @@ 428,0x86, , 0, 1, 100,enemy, 0x000 //SG_SUN_WARM 429,0x86, , 0, 1, 100,enemy, 0x000 //SG_MOON_WARM 430,0x86, , 0, 1, 100,enemy, 0x000 //SG_STAR_WARM -484,0xb8, , 2, 0,1000,enemy, 0x8808 //HW_GRAVITATION +484,0xb8, , 2, 0,1000,enemy, 0x8818 //HW_GRAVITATION 488,0xb9, , 3, 0, -1,all, 0x200 //CG_HERMODE 516,0x86, , 3, 0, 100,enemy, 0x000 //GS_DESPERADO 521,0xbe, , 0, 1,1000,enemy, 0x000 //GS_GROUNDDRIFT @@ -182,7 +181,6 @@ 8041,0xf6, , 1:1:2:2:3, 0,2000,enemy, 0x01A //MH_LAVA_SLIDE 8043,0xf7, , 1, 0,-1,all, 0x2018 //MH_VOLCANIC_ASH -8208,0x86, , 0, 2,1000,enemy, 0x080 //MA_SHOWER 8209,0x90, , 0, 1,1000,enemy, 0x006 //MA_SKIDTRAP 8210,0x93, , 0, 0,1000,enemy, 0x006 //MA_LANDMINE 8211,0x95, , 0, 1,1000,enemy, 0x006 //MA_SANDMAN diff --git a/db/re/skill_db.txt b/db/re/skill_db.txt index 082706c9a5..82bd5fad5b 100644 --- a/db/re/skill_db.txt +++ b/db/re/skill_db.txt @@ -48,7 +48,7 @@ // 14 attack type (none, weapon, magic, misc) // 15 Blowcount (amount of tiles skill knockbacks) // 16 inf3 (skill information 3): -// 0x00001 - skill ignores land protector (e.g. arrow shower) +// 0x00001 - skill ignores land protector // 0x00002 - skill that doesn't end camouflage // 0x00004 - usable skills while hiding // 0x00008 - skill that can be use while in dancing state @@ -131,7 +131,7 @@ 44,0,0,0,0,0,0,10,0,no,0,0,0,none,0,0x0, AC_VULTURE,Vulture's Eye 45,0,6,4,0,0x3,3,10,1,no,0,0,0,weapon,0,0x0, AC_CONCENTRATION,Improve Concentration 46,-9,8,1,-1,0,0,10,2,no,0,0,0,weapon,0,0x80, AC_DOUBLE,Double Strafe -47,-9,6,2,-1,0x2,2,10,1,no,0,0x40000,0,weapon,2,0x81, AC_SHOWER,Arrow Shower +47,-9,6,2,-1,0x2,1:1:1:1:1:2:2:2:2:2,10,1,no,0,0x40000,0,weapon,2,0x81, AC_SHOWER,Arrow Shower //**** // Thief @@ -1382,7 +1382,7 @@ 8205,0,6,4,0,0x1,0,10,1,no,0,0,0,weapon,0,0x0, MS_REFLECTSHIELD,Shield_Reflect 8206,0,6,4,0,0x1,0,1,1,no,0,0,0,weapon,0,0x0, MS_BERSERK,Frenzy 8207,-9,8,1,-1,0,0,10,2,no,0,0,0,weapon,0,0x80, MA_DOUBLE,Double_Strafe -8208,-9,6,2,-1,0x2,2,10,1,no,0,0x40000,0,weapon,2,0x81, MA_SHOWER,Arrow_Shower +8208,-9,6,2,-1,0x2,1:1:1:1:1:2:2:2:2:2,10,1,no,0,0x40000,0,weapon,2,0x81, MA_SHOWER,Arrow_Shower 8209,3,6,2,0,0x1,0,5,1,no,0,0x80,0,misc,6:7:8:9:10,0x3000, MA_SKIDTRAP,Skid_Trap 8210,3,6,2,2,0xC0,0,5,1,no,0,0x80,0,misc,0,0x3800, MA_LANDMINE,Land_Mine 8211,3,6,2,0,0x3,2,5,1,no,0,0x80,0,misc,0,0x3000, MA_SANDMAN,Sandman diff --git a/db/re/skill_unit_db.txt b/db/re/skill_unit_db.txt index 91bdc85364..30dbe76ed6 100644 --- a/db/re/skill_unit_db.txt +++ b/db/re/skill_unit_db.txt @@ -36,7 +36,6 @@ 21,0x86, , 0, 2:2:2:2:2:2:2:2:2:2:3,1000,enemy, 0x010 //MG_THUNDERSTORM 25,0x85, , 1, 0, -1,all, 0x6003 //AL_PNEUMA 27,0x81,0x80, 0, 0, -1,all, 0x00E //AL_WARP - 47,0x86, , 0, 1:1:1:1:1:2:2:2:2:2,1000,enemy, 0x080 //AC_SHOWER 70,0x83, , -1, 1,1000,all, 0x018 //PR_SANCTUARY 79,0x84, , -1, 1,3000,enemy, 0x8018 //PR_MAGNUS 80,0x87,0x88, 0, 1,2000,enemy, 0x4006 //WZ_FIREPILLAR @@ -84,7 +83,7 @@ 329,0xae, , 3, 0, -1,all, 0x140 //DC_FORTUNEKISS 330,0xaf, , 3, 0, -1,all, 0x140 //DC_SERVICEFORYOU 336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER -339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_DARKGRANDCROSS +339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_GRANDDARKNESS 362,0xb4, , 2, 0, 300,all, 0x2000 //HP_BASILICA 369,0xb3, , -1, 0,10000,all, 0x008 //PA_GOSPEL 395,0xb5, , 4, 0, -1,all, 0x200 //CG_MOONLIT @@ -95,7 +94,7 @@ 428,0x86, , 0, 1, 100,enemy, 0x000 //SG_SUN_WARM 429,0x86, , 0, 1, 100,enemy, 0x000 //SG_MOON_WARM 430,0x86, , 0, 1, 100,enemy, 0x000 //SG_STAR_WARM -484,0xb8, , 2, 0, 500,enemy, 0x8808 //HW_GRAVITATION +484,0xb8, , 2, 0, 500,enemy, 0x8818 //HW_GRAVITATION 488,0xb9, , 3, 0, -1,all, 0x200 //CG_HERMODE 516,0x86, , 3, 0, 100,enemy, 0x000 //GS_DESPERADO 521,0xbe, , 0, 1,1000,enemy, 0x000 //GS_GROUNDDRIFT @@ -183,7 +182,6 @@ 8041,0xf6, , 1:1:2:2:3, 0,2000,enemy, 0x01A //MH_LAVA_SLIDE 8043,0xf7, , 1, 0,-1,all, 0x2018 //MH_VOLCANIC_ASH -8208,0x86, , 0, 2,1000,enemy, 0x080 //MA_SHOWER 8209,0x90, , 0, 1,1000,enemy, 0x8006 //MA_SKIDTRAP 8210,0x93, , 0, 0,1000,enemy, 0x8006 //MA_LANDMINE 8211,0x95, , 0, 1,1000,enemy, 0x8006 //MA_SANDMAN diff --git a/src/map/map.c b/src/map/map.c index a8d5ebe6d3..986b22469d 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -742,6 +742,76 @@ int map_foreachinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0 bl_list_count = blockcount; return returnCount; //[Skotlex] } + +/*========================================== [Playtester] +* Same as foreachinarea, but there must be a shoot-able range between area center and target. +* @param m: ID of map +* @param x0: West end of area +* @param y0: South end of area +* @param x1: East end of area +* @param y1: North end of area +* @param type: Type of bl to search for +*------------------------------------------*/ +int map_foreachinshootarea(int(*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...) +{ + int bx, by, cx, cy; + int returnCount = 0; //total sum of returned values of func() + struct block_list *bl; + int blockcount = bl_list_count, i; + va_list ap; + + if (m < 0 || m >= map_num) + return 0; + + if (x1 < x0) + swap(x0, x1); + if (y1 < y0) + swap(y0, y1); + + x0 = i16max(x0, 0); + y0 = i16max(y0, 0); + x1 = i16min(x1, map[m].xs - 1); + y1 = i16min(y1, map[m].ys - 1); + + cx = x0 + (x1 - x0) / 2; + cy = y0 + (y1 - y0) / 2; + + if (type&~BL_MOB) + for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) + for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) + for (bl = map[m].block[bx + by * map[m].bxs]; bl != NULL; bl = bl->next) + if (bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 + && path_search_long(NULL, m, cx, cy, bl->x, bl->y, CELL_CHKWALL) + && bl_list_count < BL_LIST_MAX) + bl_list[bl_list_count++] = bl; + + if (type&BL_MOB) + for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) + for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) + for (bl = map[m].block_mob[bx + by * map[m].bxs]; bl != NULL; bl = bl->next) + if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1 + && path_search_long(NULL, m, cx, cy, bl->x, bl->y, CELL_CHKWALL) + && bl_list_count < BL_LIST_MAX) + bl_list[bl_list_count++] = bl; + + if (bl_list_count >= BL_LIST_MAX) + ShowWarning("map_foreachinarea: block count too many!\n"); + + map_freeblock_lock(); + + for (i = blockcount; i < bl_list_count; i++) + if (bl_list[i]->prev) { //func() may delete this bl_list[] slot, checking for prev ensures it wasn't queued for deletion. + va_start(ap, type); + returnCount += func(bl_list[i], ap); + va_end(ap); + } + + map_freeblock_unlock(); + + bl_list_count = blockcount; + return returnCount; +} + /*========================================== * Adapted from forcountinarea for an easier invocation. [pakpil] *------------------------------------------*/ diff --git a/src/map/map.h b/src/map/map.h index 5a43f222a3..cc331ffeb5 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -822,7 +822,8 @@ int map_delblock(struct block_list* bl); int map_moveblock(struct block_list *, int, int, unsigned int); int map_foreachinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, ...); int map_foreachinshootrange(int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, ...); -int map_foreachinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...); +int map_foreachinarea(int(*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...); +int map_foreachinshootarea(int(*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...); int map_forcountinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int count, int type, ...); int map_forcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...); int map_foreachinmovearea(int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...); diff --git a/src/map/path.c b/src/map/path.c index 238bdc28f0..b653da9d52 100644 --- a/src/map/path.c +++ b/src/map/path.c @@ -172,7 +172,7 @@ bool path_search_long(struct shootpath_data *spd,int16 m,int16 x0,int16 y0,int16 spd->y[spd->len] = y0; spd->len++; } - if (map_getcellp(md,x0,y0,cell)) + if ((x0 != x1 || y0 != y1) && map_getcellp(md,x0,y0,cell)) return false; } diff --git a/src/map/skill.c b/src/map/skill.c index 26a4bf8c43..9892ad0345 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2887,16 +2887,16 @@ void skill_attack_blow(struct block_list *src, struct block_list *dsrc, struct b if(!battle_config.stormgust_knockback) dir = rnd()%8; break; - case WL_CRIMSONROCK: - dir = map_calc_dir(target,skill_area_temp[4],skill_area_temp[5]); - break; case MC_CARTREVOLUTION: if (battle_config.cart_revo_knockback) dir = 6; // Official servers push target to the West break; case AC_SHOWER: - if (!battle_config.arrow_shower_knockback) + case WL_CRIMSONROCK: + if (!battle_config.arrow_shower_knockback && skill_id == AC_SHOWER) dir = map_calc_dir(target, src->x, src->y); + else + dir = map_calc_dir(target, skill_area_temp[4], skill_area_temp[5]); break; } @@ -4427,7 +4427,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case MO_COMBOFINISH: if (!(flag&1) && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK) { //Becomes a splash attack when Soul Linked. - map_foreachinrange(skill_area_sub, bl, + map_foreachinshootrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv),splash_target(src), src,skill_id,skill_lv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id); @@ -4438,7 +4438,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case TK_STORMKICK: // Taekwon kicks [Dralnu] clif_skill_nodamage(src,bl,skill_id,skill_lv,1); skill_area_temp[1] = 0; - map_foreachinrange(skill_attack_area, src, + map_foreachinshootrange(skill_attack_area, src, skill_get_splash(skill_id, skill_lv), splash_target(src), BF_WEAPON, src, src, skill_id, skill_lv, tick, flag, BCT_ENEMY); break; @@ -4708,7 +4708,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, (skill_id == AS_SPLASHER)?1:skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill_area_sub_count); // recursive invocation of skill_castend_damage_id() with flag|1 - if (battle_config.skill_wall_check && skill_id == RA_ARROWSTORM) + if (battle_config.skill_wall_check && skill_id != NPC_EARTHQUAKE) map_foreachinshootrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), starget, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id); else map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), starget, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id); @@ -6293,7 +6293,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SM_MAGNUM: case MS_MAGNUM: skill_area_temp[1] = 0; - map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv), BL_SKILL|BL_CHAR, + map_foreachinshootrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv), BL_SKILL|BL_CHAR, src,skill_id,skill_lv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id); clif_skill_nodamage (src,src,skill_id,skill_lv,1); // Initiate 20% of your damage becomes fire element. @@ -6804,7 +6804,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui //Passive side of the attack. status_change_end(src, SC_SIGHT, INVALID_TIMER); clif_skill_nodamage(src,bl,skill_id,skill_lv,1); - map_foreachinrange(skill_area_sub,src, + map_foreachinshootrange(skill_area_sub,src, skill_get_splash(skill_id, skill_lv),BL_CHAR|BL_SKILL, src,skill_id,skill_lv,tick, flag|BCT_ENEMY|SD_ANIMATION|1, skill_castend_damage_id); @@ -6813,7 +6813,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case WZ_FROSTNOVA: clif_skill_nodamage(src,bl,skill_id,skill_lv,1); skill_area_temp[1] = 0; - map_foreachinrange(skill_attack_area, src, + map_foreachinshootrange(skill_attack_area, src, skill_get_splash(skill_id, skill_lv), splash_target(src), BF_MAGIC, src, src, skill_id, skill_lv, tick, flag, BCT_ENEMY); break; @@ -6826,7 +6826,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui BCT_ENEMY:BCT_ALL; clif_skill_nodamage(src, src, skill_id, -1, 1); map_delblock(src); //Required to prevent chain-self-destructions hitting back. - map_foreachinrange(skill_area_sub, bl, + map_foreachinshootrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|i, skill_castend_damage_id); @@ -10984,7 +10984,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) break; } #ifdef OFFICIAL_WALKPATH - if( !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL) ) + if(skill_get_casttype(ud->skill_id) != CAST_NODAMAGE && !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL)) { if (sd) { clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0); @@ -11358,7 +11358,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case BS_HAMMERFALL: i = skill_get_splash(skill_id, skill_lv); - map_foreachinarea (skill_area_sub, + map_foreachinarea(skill_area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|2, skill_castend_nodamage_id); @@ -11434,8 +11434,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case WE_CALLPARTNER: case WE_CALLPARENT: case WE_CALLBABY: - case AC_SHOWER: //Ground-placed skill implementation. - case MA_SHOWER: case SA_LANDPROTECTOR: case BD_LULLABY: case BD_RICHMANKIM: @@ -11768,13 +11766,18 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case RK_WINDCUTTER: clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + case AC_SHOWER: + case MA_SHOWER: case NC_COLDSLOWER: case NC_ARMSCANNON: case RK_DRAGONBREATH: case RK_DRAGONBREATH_WATER: + // Cast center might be relevant later (e.g. for knockback direction) + skill_area_temp[4] = x; + skill_area_temp[5] = y; i = skill_get_splash(skill_id,skill_lv); if (battle_config.skill_wall_check) - map_foreachinshootrange(skill_area_sub,src,skill_get_splash(skill_id, skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id); + map_foreachinshootarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id); else map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id); break; @@ -12744,8 +12747,8 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_ if( !group->state.song_dance && !map_getcell(src->m,ux,uy,CELL_CHKREACH) ) continue; // don't place skill units on walls (except for songs/dances/encores) - if( battle_config.skill_wall_check && unit_flag&UF_PATHCHECK && !path_search_long(NULL,src->m,ux,uy,x,y,CELL_CHKWALL) ) - continue; // no path between cell and center of casting. + if( battle_config.skill_wall_check && unit_flag&UF_PATHCHECK && !path_search_long(NULL,src->m,ux,uy,src->x,src->y,CELL_CHKWALL) ) + continue; // no path between cell and caster switch( skill_id ) { // HP for Skill unit that can be damaged, see also skill_unit_ondamaged @@ -13445,18 +13448,23 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns case UNT_FREEZINGTRAP: case UNT_FIREPILLAR_ACTIVE: case UNT_CLAYMORETRAP: + { + int bl_flag = sg->bl_flag; if (tsc && tsc->data[SC__MANHOLE]) break; if (sg->unit_id == UNT_FIRINGTRAP || sg->unit_id == UNT_ICEBOUNDTRAP || sg->unit_id == UNT_CLAYMORETRAP) - map_foreachinrange(skill_trap_splash, &unit->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag|BL_SKILL|~BCT_SELF, &unit->bl, tick); + bl_flag = bl_flag|BL_SKILL|~BCT_SELF; + if(battle_config.skill_wall_check && !(skill_get_nk(skill_id)&NK_NO_DAMAGE)) + map_foreachinshootrange(skill_trap_splash, &unit->bl, skill_get_splash(sg->skill_id, sg->skill_lv), bl_flag, &unit->bl, tick); else - map_foreachinrange(skill_trap_splash, &unit->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &unit->bl, tick); + map_foreachinrange(skill_trap_splash, &unit->bl, skill_get_splash(sg->skill_id, sg->skill_lv), bl_flag, &unit->bl, tick); if (sg->unit_id != UNT_FIREPILLAR_ACTIVE) clif_changetraplook(&unit->bl,(sg->unit_id == UNT_LANDMINE ? UNT_FIREPILLAR_ACTIVE : UNT_USED_TRAPS)); sg->limit = DIFF_TICK(tick, sg->tick) + (sg->unit_id == UNT_CLUSTERBOMB || sg->unit_id == UNT_ICEBOUNDTRAP ? 1000 : 0) + // Cluster Bomb/Icebound has 1s to disappear once activated. (sg->unit_id == UNT_FIRINGTRAP ? 0 : 1500); // Firing Trap gets removed immediately once activated. sg->unit_id = UNT_USED_TRAPS; // Change ID so it does not invoke a for each in area again. + } break; case UNT_TALKIEBOX: @@ -16796,10 +16804,16 @@ int skill_detonator(struct block_list *bl, va_list ap) case UNT_CLAYMORETRAP: case UNT_FIRINGTRAP: case UNT_ICEBOUNDTRAP: - map_foreachinrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag|BL_SKILL|~BCT_SELF,bl,unit->group->tick); + if (battle_config.skill_wall_check) + map_foreachinshootrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag|BL_SKILL|~BCT_SELF,bl,unit->group->tick); + else + map_foreachinrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag|BL_SKILL|~BCT_SELF,bl,unit->group->tick); break; default: - map_foreachinrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag,bl,unit->group->tick); + if(battle_config.skill_wall_check && !(skill_get_nk(unit->group->skill_id)&NK_NO_DAMAGE)) + map_foreachinshootrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag,bl,unit->group->tick); + else + map_foreachinrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag,bl,unit->group->tick); break; } clif_changetraplook(bl, UNT_USED_TRAPS); @@ -19337,7 +19351,10 @@ static int skill_destroy_trap(struct block_list *bl, va_list ap) case UNT_CLAYMORETRAP: case UNT_FIRINGTRAP: case UNT_ICEBOUNDTRAP: - map_foreachinrange(skill_trap_splash,&su->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag|BL_SKILL|~BCT_SELF, &su->bl,tick); + if(battle_config.skill_wall_check) + map_foreachinshootrange(skill_trap_splash,&su->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag|BL_SKILL|~BCT_SELF, &su->bl,tick); + else + map_foreachinrange(skill_trap_splash,&su->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag|BL_SKILL|~BCT_SELF, &su->bl,tick); break; case UNT_LANDMINE: case UNT_BLASTMINE: @@ -19346,7 +19363,10 @@ static int skill_destroy_trap(struct block_list *bl, va_list ap) case UNT_FLASHER: case UNT_FREEZINGTRAP: case UNT_CLUSTERBOMB: - map_foreachinrange(skill_trap_splash,&su->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &su->bl,tick); + if (battle_config.skill_wall_check && !(skill_get_nk(sg->skill_id)&NK_NO_DAMAGE)) + map_foreachinshootrange(skill_trap_splash,&su->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &su->bl,tick); + else + map_foreachinrange(skill_trap_splash,&su->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &su->bl,tick); break; } // Traps aren't recovered. diff --git a/src/map/unit.c b/src/map/unit.c index f579ed62d4..4c722a046e 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1986,13 +1986,6 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui return 0; } - if( map_getcell(src->m, skill_x, skill_y, CELL_CHKWALL) ) { // Can't cast ground targeted spells on wall cells - if (sd) - clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - - return 0; - } - // Check range and obstacle bl.type = BL_NUL; bl.m = src->m;