소스 검색

Modified the map_setcell() code to to use a boolean flag instead of needing SET_ / CLR_ pairs of defines (topic:174323).
Also removed script object 'setcell', added script function 'setcell'.
- Now you can manipulate cell information without needing @loadnpc
- You can also manipulate the terrain ('gat') type itself, using the new cell_walkable, cell_shootable and cell_water constants
(currently the implementation uses bit flags too, so to get the type you want, you need to adjust the flags one by one)
- This breaks current scripts, so please adjust places that use setcell
(also be sure to _only_ use predefined constants, not direct numbers)
- Details can be found in the script reference.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12009 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 17 년 전
부모
커밋
e7bb626a80
11개의 변경된 파일182개의 추가작업 그리고 177개의 파일을 삭제
  1. 12 1
      Changelog-Trunk.txt
  2. 8 6
      db/const.txt
  3. 42 11
      doc/script_commands.txt
  4. 27 26
      src/map/map.c
  5. 29 38
      src/map/map.h
  6. 2 47
      src/map/npc.c
  7. 2 2
      src/map/path.c
  8. 2 2
      src/map/path.h
  9. 28 0
      src/map/script.c
  10. 30 43
      src/map/skill.c
  11. 0 1
      src/map/skill.h

+ 12 - 1
Changelog-Trunk.txt

@@ -4,6 +4,17 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2008/01/04
+	* Modified the map_setcell() code to to use a boolean flag instead of
+	  needing SET_ / CLR_ pairs of defines (topic:174323) [ultramage].
+	  Also removed script object 'setcell', added script function 'setcell'
+	- Now you can manipulate cell information without needing @loadnpc
+	- You can also manipulate the terrain ('gat') type itself, using the
+	  new cell_walkable, cell_shootable and cell_water constants
+	  (currently the implementation uses bit flags too, so to get the type
+	  you want, you need to adjust the flags one by one)
+	- This breaks current scripts, so please adjust places that use setcell
+	  (also be sure to _only_ use predefined constants, not direct numbers)
+	- Details can be found in the script reference.
 	* Fixed Music Lesson's effect on Assassin Cross of Sunset.
 	* Fixed a possible crash in status_change_timer when debug mode is
 	  disabled. [Skotlex]
@@ -13,7 +24,7 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 	- removed unused CELL_SAFETYWALL
 	- removed custom CELL_REGEN, it just increased regen rate (r1192, r1518)
 	* Fixed npc unloading not clearing NPC touch cells (bugreport:595)	
-	* Map cell mechanism rewrite
+	* Map cell mechanism rewrite (bugreport:426)
 	- defined a data structure for map cells (replaces 3 various cell arrays)
 	- both terrain (gat) and dynamic (cell) information is now stored as
 	  C-style bit flags instead of #defines and bitmasks

+ 8 - 6
db/const.txt

@@ -224,12 +224,14 @@ mf_nochat	43
 mf_noexppenalty	44
 mf_guildlock	45
 
-cell_wall	1
-cell_water	3
-cell_ground	5
-cell_regen	32
-cell_basilica	64
-cell_npc	128
+cell_walkable	0
+cell_shootable	1
+cell_water	2
+cell_npc	3
+cell_basilica	4
+cell_landprotector	5
+cell_icewall	6
+cell_novending	7
 
 StatusPoint	9	1
 BaseLevel	11	1

+ 42 - 11
doc/script_commands.txt

@@ -95,6 +95,8 @@
 //=       Corrected various mistakes mentioned in bugreport:373 [ultramage]
 //= 3.12.20071227
 //=       Corrected description of scope and npc variables. [FlavioJS]
+//= 3.13.20080104
+//=       Updated 'setcell' desc to match latest code changes [ultramage]
 //=========================================================
 
 This document is a reference manual for all the scripting commands and functions 
@@ -390,17 +392,6 @@ The code part is the script code that will execute whenever the function is
 called with 'callfunc'. It has to be in curly brackets, unlike elsewhere where 
 we use curly brackets, these do NOT signify an optional parameter.
 
-** Alter a map cell
-
-<map name>%TAB%setcell%TAB%<type>,<x1>,<y1>,<x2>,<y2>
-
-This is sneaky, and isn't used in any official scripts, but it will let you 
-define an area (x1/y1-x2/y2 square) of a map as having cell type 'type', where 
-type is a number, which, among other things, defines whether the area is 
-walkable or not, whether it has Basilica working in it or not, and some other 
-things. This is a solution just itching for a problem and there's a number of 
-interesting things you could use it for. Further investigation on what types are 
-valid and mean what exactly is pending.
 
 Once an object is defined which has a 'code' field to it's definition, it 
 contains script commands which can actually be triggered and executed. 
@@ -6117,6 +6108,46 @@ invoking character.
 This will recalculate the homunculus stats acording to its level, of the 
 current invoking character.
 
+---------------------------------------
+
+*setcell "<map name>",<x1>,<y1>,<x2>,<y2>,<type>,<flag>;
+
+Each map cell has several 'flags' that specify the properties of that cell.
+These include terrain properties (walkability, shootability, presence of water),
+skills (basilica, land protector, ...) and other (npc nearby, no vending, ...).
+Each of these can be 'on' or 'off'. Together they define a cell's behavior.
+
+This command lets you alter these flags for all map cells in the specified
+(x1,y1)-(x2,y2) rectangle. The 'flag' can be 0 or 1 (0:clear flag, 1:set flag).
+The 'type' defines which flag to modify. Possible options include cell_walkable,
+cell_shootable, cell_basilica. For a full list, see const.txt.
+
+Example:
+
+	setcell "arena",0,0,300,300,cell_basilica,1;
+	setcell "arena",140,140,160,160,cell_basilica,0;
+	setcell "arena",135,135,165,165,cell_walkable,0;
+	setcell "arena",140,140,160,160,cell_walkable,1;
+
+This will add a makeshift ring into the center of the map. The ring will be
+surrounded by a 5-cell wide 'gap' to prevent interference from outside, and
+the rest of the map will be marked as 'basilica', preventing observers from
+casting any offensive skills or fighting among themselves. Note that the wall
+will not be shown nor known client-side, which may cause movement problems.
+
+Another example:
+
+OnBarricadeDeploy:
+	setcell "schg_cas05",114,51,125,51,cell_walkable,0;
+	end;
+OnBarricadeBreak:
+	setcell "schg_cas05",114,51,125,51,cell_walkable,1;
+	end;
+
+This could be a part of the WoE:SE script, where attackers are not allowed
+to proceed until all barricades are destroyed. This script would place and
+remove a nonwalkable row of cells after the barricade mobs.
+	
 ---------------------------------------
 Whew.
 That's about all of them.

+ 27 - 26
src/map/map.c

@@ -468,7 +468,7 @@ int map_count_oncell(int m, int x, int y, int type)
 /*
  * ォサォ・セェホ��ェヒフクェトェアェソォケォュォ・讚ヒォテォネェ��ケ
  */
-struct skill_unit *map_find_skill_unit_oncell(struct block_list *target,int x,int y,int skill_id,struct skill_unit *out_unit)
+struct skill_unit* map_find_skill_unit_oncell(struct block_list* target,int x,int y,int skill_id,struct skill_unit* out_unit)
 {
 	int m,bx,by;
 	struct block_list *bl;
@@ -485,10 +485,11 @@ struct skill_unit *map_find_skill_unit_oncell(struct block_list *target,int x,in
 	{
 		if (bl->x != x || bl->y != y || bl->type != BL_SKILL)
 			continue;
+
 		unit = (struct skill_unit *) bl;
-		if (unit==out_unit || !unit->alive || !unit->group || unit->group->skill_id!=skill_id)
+		if( unit == out_unit || !unit->alive || !unit->group || unit->group->skill_id != skill_id )
 			continue;
-		if (battle_check_target(&unit->bl,target,unit->group->target_flag)>0)
+		if( battle_check_target(&unit->bl,target,unit->group->target_flag) > 0 )
 			return unit;
 	}
 	return NULL;
@@ -2136,12 +2137,12 @@ static int map_cell2gat(struct mapcell cell)
 /*==========================================
  * (m,x,y)の状態を調べる
  *------------------------------------------*/
-int map_getcell(int m,int x,int y,cell_t cellchk)
+int map_getcell(int m,int x,int y,cell_chk cellchk)
 {
 	return (m < 0 || m >= MAX_MAP_PER_SERVER) ? 0 : map_getcellp(&map[m],x,y,cellchk);
 }
 
-int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk)
+int map_getcellp(struct map_data* m,int x,int y,cell_chk cellchk)
 {
 	struct mapcell cell;
 
@@ -2149,10 +2150,7 @@ int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk)
 
 	//NOTE: this intentionally overrides the last row and column
 	if(x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1)
-	{
-		if(cellchk==CELL_CHKNOPASS) return 1;
-		return 0;
-	}
+		return( cellchk == CELL_CHKNOPASS );
 
 	cell = m->cell[x + y*m->xs];
 
@@ -2213,28 +2211,31 @@ int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk)
 }
 
 /*==========================================
- * (m,x,y)の状態を設定する
+ * Change the type/flags of a map cell
+ * 'cell' - which flag to modify
+ * 'flag' - true = on, false = off
  *------------------------------------------*/
-void map_setcell(int m,int x,int y,int cell)
+void map_setcell(int m, int x, int y, cell_t cell, bool flag)
 {
 	int j;
-	if(x<0 || x>=map[m].xs || y<0 || y>=map[m].ys)
+
+	if( m < 0 || m >= map_num || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys )
 		return;
-	j=x+y*map[m].xs;
-
-	switch (cell) {
-		case CELL_SETNPC:           map[m].cell[j].npc = 1;           break;
-		case CELL_CLRNPC:           map[m].cell[j].npc = 0;           break;
-		case CELL_SETICEWALL:       map[m].cell[j].icewall = 1;       break;
-		case CELL_CLRICEWALL:       map[m].cell[j].icewall = 0;       break;
-		case CELL_SETBASILICA:      map[m].cell[j].basilica = 1;      break;
-		case CELL_CLRBASILICA:      map[m].cell[j].basilica = 0;      break;
-		case CELL_SETLANDPROTECTOR: map[m].cell[j].landprotector = 1; break;
-		case CELL_CLRLANDPROTECTOR: map[m].cell[j].landprotector = 0; break;
-		case CELL_SETNOVENDING:     map[m].cell[j].novending = 1;     break;
-		case CELL_CLRNOVENDING:     map[m].cell[j].novending = 0;     break;
+
+	j = x + y*map[m].xs;
+
+	switch( cell ) {
+		case CELL_WALKABLE:      map[m].cell[j].walkable = flag;      break;
+		case CELL_SHOOTABLE:     map[m].cell[j].shootable = flag;     break;
+		case CELL_WATER:         map[m].cell[j].water = flag;         break;
+
+		case CELL_NPC:           map[m].cell[j].npc = flag;           break;
+		case CELL_ICEWALL:       map[m].cell[j].icewall = flag;       break;
+		case CELL_BASILICA:      map[m].cell[j].basilica = flag;      break;
+		case CELL_LANDPROTECTOR: map[m].cell[j].landprotector = flag; break;
+		case CELL_NOVENDING:     map[m].cell[j].novending = flag;     break;
 		default:
-			//map[m].gat[j] = cell; FIXME
+			ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
 			break;
 	}
 }

+ 29 - 38
src/map/map.h

@@ -1107,48 +1107,39 @@ enum _look {
 	LOOK_SHOES
 };
 
-// CELLs for non-permanent cell-based effects (Pneuma, Basilica, Npcs, etc)
-#define CELL_NPC	0x1
-#define CELL_LANDPROTECTOR	0x10
-#define CELL_BASILICA	0x20
-#define CELL_NOVENDING	0x40
-#define CELL_ICEWALL	0x80
-/*
- * map_getcell()で使用されるフラグ
- */
+// used by map_setcell()
 typedef enum {
-	CELL_GETTYPE,		// セルタイプを返す
+	CELL_WALKABLE,
+	CELL_SHOOTABLE,
+	CELL_WATER,
+
+	CELL_NPC,
+	CELL_BASILICA,
+	CELL_LANDPROTECTOR,
+	CELL_ICEWALL,
+	CELL_NOVENDING,
+} cell_t;
+
+// used by map_getcell()
+typedef enum {
+	CELL_GETTYPE,		// retrieves a cell's 'gat' type
 
-	CELL_CHKWALL,		// 壁(セルタイプ1)
-	CELL_CHKWATER,		// 水場(セルタイプ3)
-	CELL_CHKCLIFF,		// 地面障害物(セルタイプ5)
+	CELL_CHKWALL,		// wall (gat type 1)
+	CELL_CHKWATER,		// water (gat type 3)
+	CELL_CHKCLIFF,		// cliff/gap (gat type 5)
 
-	CELL_CHKPASS,		// 通過可能(セルタイプ1,5以外)
+	CELL_CHKPASS,		// passable cell (gat type non-1/5)
 	CELL_CHKREACH,		// Same as PASS, but ignores the cell-stacking mod.
-	CELL_CHKNOPASS,		// 通過不可(セルタイプ1,5)
+	CELL_CHKNOPASS,		// non-passable cell (gat types 1 and 5)
 	CELL_CHKNOREACH,	// Same as NOPASS, but ignores the cell-stacking mod.
+	CELL_CHKSTACK,		// whether cell is full (reached cell stacking limit) 
 
-	CELL_CHKNPC=0x10,	// タッチタイプのNPC(セルタイプ0x80フラグ)
-	CELL_CHKBASILICA,	// バジリカ(セルタイプ0x40フラグ)
+	CELL_CHKNPC,
+	CELL_CHKBASILICA,
 	CELL_CHKLANDPROTECTOR,
 	CELL_CHKICEWALL,
-	CELL_CHKSTACK,
 	CELL_CHKNOVENDING,
-} cell_t;
-
-// map_setcell()で使用されるフラグ
-enum {
-	CELL_SETNPC=0x10,	// タッチタイプのNPCをセット
-	CELL_CLRNPC,
-	CELL_SETBASILICA,	// バジリカをセット
-	CELL_CLRBASILICA,	// バジリカをクリア
-	CELL_SETLANDPROTECTOR=0x15, //Set/Clear Magnetic Earth
-	CELL_CLRLANDPROTECTOR,
-	CELL_SETICEWALL=0x1b,
-	CELL_CLRICEWALL,
-	CELL_SETNOVENDING,
-	CELL_CLRNOVENDING,
-};
+} cell_chk;
 
 struct mapcell
 {
@@ -1254,8 +1245,13 @@ struct map_data_other_server {
 	uint16 port;
 };
 
+int map_getcell(int,int,int,cell_chk);
+int map_getcellp(struct map_data*,int,int,cell_chk);
+void map_setcell(int m, int x, int y, cell_t cell, bool flag);
+
 extern struct map_data map[];
 extern int map_num;
+
 extern int autosave_interval;
 extern int minsave_interval;
 extern int save_settings;
@@ -1264,11 +1260,6 @@ extern int night_flag; // 0=day, 1=night [Yor]
 extern int enable_spy; //Determines if @spy commands are active.
 extern char db_path[256];
 
-// gat?ヨァ
-int map_getcell(int,int,int,cell_t);
-int map_getcellp(struct map_data*,int,int,cell_t);
-void map_setcell(int,int,int,int);
-
 extern char motd_txt[];
 extern char help_txt[];
 extern char help2_txt[];

+ 2 - 47
src/map/npc.c

@@ -1970,7 +1970,7 @@ void npc_setcells(struct npc_data* nd)
 		for (j = x-xs; j <= x+xs; j++) {
 			if (map_getcell(m, j, i, CELL_CHKNOPASS))
 				continue;
-			map_setcell(m, j, i, CELL_SETNPC);
+			map_setcell(m, j, i, CELL_NPC, true);
 		}
 	}
 }
@@ -2010,7 +2010,7 @@ void npc_unsetcells(struct npc_data* nd)
 	//Erase this npc's cells
 	for (i = y-ys; i <= y+ys; i++)
 		for (j = x-xs; j <= x+xs; j++)
-			map_setcell(m, j, i, CELL_CLRNPC);
+			map_setcell(m, j, i, CELL_NPC, false);
 
 	//Re-deploy NPC cells for other nearby npcs.
 	map_foreachinarea( npc_unsetcells_sub, m, x0, y0, x1, y1, BL_NPC, nd->bl.id );
@@ -2512,47 +2512,6 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 	return strchr(start,'\n');// continue
 }
 
-/*==========================================
- * Setting up map cells
- *------------------------------------------*/
-static const char* npc_parse_mapcell(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
-{
-	int m, cell, x, y, x0, y0, x1, y1;
-	char type[32], mapname[32];
-
-	// w1=<mapname>
-	// w3=<type>,<x1>,<y1>,<x2>,<y2>
-	if( sscanf(w1, "%31[^,]", mapname) != 1
-	||	sscanf(w3, "%31[^,],%d,%d,%d,%d", type, &x0, &y0, &x1, &y1) < 5 )
-	{
-		ShowError("npc_parse_mapcell: Invalid mapcell definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
-		return strchr(start,'\n');// skip and continue
-	}
-	m = map_mapname2mapid(mapname);
-	if( m < 0 )
-	{
-		ShowWarning("npc_parse_mapcell: Unknown map in file '%s', line '%d' : %s\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", mapname, filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
-		return strchr(start,'\n');// skip and continue
-	}
-
-	cell = strtol(type, (char **)NULL, 0);
-
-	if( x0 > x1 )
-		swap(x0, x1);
-	if( y0 > y1 )
-		swap(y0, y1);
-
-	for( x = x0; x <= x1; ++x )
-		for( y = y0; y <= y1; ++y )
-		{
-			if( map_getcell(m, x, y, CELL_CHKWALL) || map_getcell(m, x, y, CELL_CHKCLIFF) )
-				continue;
-			map_setcell(m, x, y, cell);
-		}
-
-	return strchr(start,'\n');// continue
-}
-
 void npc_parsesrcfile(const char* filepath)
 {
 	int m, lines = 0;
@@ -2678,10 +2637,6 @@ void npc_parsesrcfile(const char* filepath)
 		{
 			p = npc_parse_mapflag(w1, w2, w3, w4, p, buffer, filepath);
 		}
-		else if( strcmpi(w2,"setcell") == 0 && count >= 3 )
-		{
-			p = npc_parse_mapcell(w1, w2, w3, w4, p, buffer, filepath);
-		}
 		else
 		{
 			ShowError("npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4);

+ 2 - 2
src/map/path.c

@@ -197,7 +197,7 @@ int path_blownpos(int m,int x0,int y0,int dx,int dy,int count)
 /*==========================================
  * is ranged attack from (x0,y0) to (x1,y1) possible?
  *------------------------------------------*/
-bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_t cell)
+bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_chk cell)
 {
 	int dx, dy;
 	int wx = 0, wy = 0;
@@ -270,7 +270,7 @@ bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int
  * flag: &1 = easy path search only
  * cell: type of obstruction to check for
  *------------------------------------------*/
-bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_t cell)
+bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_chk cell)
 {
 	int heap[MAX_HEAP+1];
 	struct tmp_path tp[MAX_WALKPATH*MAX_WALKPATH];

+ 2 - 2
src/map/path.h

@@ -8,10 +8,10 @@
 int path_blownpos(int m,int x0,int y0,int dx,int dy,int count);
 
 // tries to find a walkable path
-bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_t cell);
+bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int flag,cell_chk cell);
 
 // tries to find a shootable path
-bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_t cell);
+bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int y1,cell_chk cell);
 
 
 // distance related functions

+ 28 - 0
src/map/script.c

@@ -12943,6 +12943,33 @@ BUILDIN_FUNC(openmail)
 	return 0;
 }
 
+/// Modifies flags of cells in the specified area.
+///
+/// setcell "<map name>",<x1>,<y1>,<x2>,<y2>,<type>,<flag>;
+///
+/// @see cell_* constants in const.txt for the types
+BUILDIN_FUNC(setcell)
+{
+	int m = map_mapname2mapid(script_getstr(st,2));
+	int x1 = script_getnum(st,3);
+	int y1 = script_getnum(st,4);
+	int x2 = script_getnum(st,5);
+	int y2 = script_getnum(st,6);
+	cell_t type = (cell_t)script_getnum(st,7);
+	bool flag = (bool)script_getnum(st,8);
+
+	int x,y;
+
+	if( x1 > x2 ) swap(x1,x2);
+	if( y1 > y2 ) swap(y1,y2);
+
+	for( y = y1; y <= y2; ++y )
+		for( x = x1; x <= x2; ++x )
+			map_setcell(m, x, y, type, flag);
+
+	return 0;
+}
+
 
 // declarations that were supposed to be exported from npc_chat.c
 #ifdef PCRE_SUPPORT
@@ -13285,5 +13312,6 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(checkvending,"*"),
 	BUILDIN_DEF(checkchatting,"*"),
 	BUILDIN_DEF(openmail,""),
+	BUILDIN_DEF(setcell,"siiiiii"),
 	{NULL,NULL,NULL},
 };

+ 30 - 43
src/map/skill.c

@@ -1996,24 +1996,27 @@ int skill_area_sub_count (struct block_list *src, struct block_list *target, int
 
 int skill_count_water (struct block_list *src, int range)
 {
-	int i,x,y,cnt = 0,size = range*2+1;
+	int x,y,cnt = 0;
 	struct skill_unit *unit;
 
-	for (i=0;i<size*size;i++) {
-		x = src->x+(i%size-range);
-		y = src->y+(i/size-range);
-		if (map_getcell(src->m,x,y,CELL_CHKWATER)) {
-			cnt++;
-			continue;
-		}
-		unit = map_find_skill_unit_oncell(src,x,y,SA_DELUGE,NULL);
-		if (!unit)
-		  unit = map_find_skill_unit_oncell(src,x,y,NJ_SUITON,NULL);
-		if (unit) {
-			cnt++;
-			skill_delunit(unit);
+	for( y = src->y - range; y <= src->y + range; ++y )
+	{
+		for( x = src->x - range; x <= src->x + range; ++x )
+		{
+			if (map_getcell(src->m,x,y,CELL_CHKWATER)) {
+				cnt++;
+				continue;
+			}
+			unit = map_find_skill_unit_oncell(src,x,y,SA_DELUGE,NULL);
+			if (!unit)
+			  unit = map_find_skill_unit_oncell(src,x,y,NJ_SUITON,NULL);
+			if (unit) {
+				cnt++;
+				skill_delunit(unit);
+			}
 		}
 	}
+
 	return cnt;
 }
 
@@ -7066,6 +7069,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
 		if (sce)
 			status_change_end(bl,type,-1);
 		break;
+
 	case UNT_HERMODE:	//Clear Hermode if the owner moved.
 		if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id)
 			status_change_end(bl,type,-1);
@@ -8758,33 +8762,16 @@ int skill_frostjoke_scream (struct block_list *bl, va_list ap)
 /*==========================================
  *
  *------------------------------------------*/
-void skill_unitsetmapcell (struct skill_unit *src, int skill_num, int skill_lv, int flag)
+static void skill_unitsetmapcell (struct skill_unit *src, int skill_num, int skill_lv, cell_t cell, bool flag)
 {
-	int i,x,y,range = skill_get_unit_range(skill_num,skill_lv);
-	int size = range*2+1;
+	int range = skill_get_unit_range(skill_num,skill_lv);
+	int x,y;
 
-	for (i=0;i<size*size;i++) {
-		x = src->bl.x+(i%size-range);
-		y = src->bl.y+(i/size-range);
-		map_setcell(src->bl.m,x,y,flag);
-	}
+	for( y = src->bl.y - range; y <= src->bl.y + range; ++y )
+		for( x = src->bl.x - range; x <= src->bl.x + range; ++x )
+			map_setcell(src->bl.m, x, y, cell, flag);
 }
 
-/*==========================================
- * Sets a map cell around the caster, according to the skill's splash range.
- *------------------------------------------*/
-void skill_setmapcell (struct block_list *src, int skill_num, int skill_lv, int flag)
-{
-	int i,x,y,range = skill_get_splash(skill_num, skill_lv);
-	int size = range*2+1;
-
-	for (i=0;i<size*size;i++) {
-		x = src->x+(i%size-range);
-		y = src->y+(i/size-range);
-		map_setcell(src->m,x,y,flag);
-	}
-}
-	
 /*==========================================
  *
  *------------------------------------------*/
@@ -9241,13 +9228,13 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int
 
 	switch (group->skill_id) {
 	case SA_LANDPROTECTOR:
-		skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_SETLANDPROTECTOR);
+		skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,true);
 		break;
 	case HP_BASILICA:
-		skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_SETBASILICA);
+		skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,true);
 		break;
 	case WZ_ICEWALL:
-		skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_SETICEWALL);
+		skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,true);
 		break;
 	default:
 		if (group->state.song_dance&0x1) //Check for dissonance.
@@ -9282,13 +9269,13 @@ int skill_delunit (struct skill_unit* unit)
 
 	switch (group->skill_id) {
 	case SA_LANDPROTECTOR:
-		skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_CLRLANDPROTECTOR);
+		skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,false);
 		break;
 	case HP_BASILICA:
-		skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_CLRBASILICA);
+		skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,false);
 		break;
 	case WZ_ICEWALL:
-		skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_CLRICEWALL);
+		skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,false);
 		break;
 	}
 

+ 0 - 1
src/map/skill.h

@@ -225,7 +225,6 @@ int skill_check_unit_cell(int skillid,int m,int x,int y,int unit_id);
 int skill_unit_out_all( struct block_list *bl,unsigned int tick,int range);
 int skill_unit_move(struct block_list *bl,unsigned int tick,int flag);
 int skill_unit_move_unit_group( struct skill_unit_group *group, int m,int dx,int dy);
-void skill_setmapcell(struct block_list *src, int skill_num, int skill_lv, int flag);
 
 struct skill_unit_group *skill_check_dancing( struct block_list *src );
 void skill_stop_dancing(struct block_list *src);