Browse Source

Cleaned up the warp functions
* Fixes #2173.
* Created a central warp function to check for Random, SavePoint, and Save arguments.
* Script commands areawarp, warppartner, warpwaitingpc, and areawarp now support Random, SavePoint and Save as destinations.
Thanks to @jezznar!

aleos 8 years ago
parent
commit
22812b4de3
2 changed files with 119 additions and 66 deletions
  1. 19 2
      doc/script_commands.txt
  2. 100 64
      src/map/script.c

+ 19 - 2
doc/script_commands.txt

@@ -3912,8 +3912,10 @@ the affected area to a random set of co-ordinates on "place2".
 By using the optional x4 and y4 parameters, the destination coordinates will be a 
 By using the optional x4 and y4 parameters, the destination coordinates will be a 
 random place within the defined x3/y3-x4/y4 square.
 random place within the defined x3/y3-x4/y4 square.
 
 
-Like 'warp', areawarp will also explicitly warp characters randomly into the 
-current map if you give the 'to map name' as "Random".
+There are also three special 'map names' you can use.
+
+"Random" will warp the player randomly on the current map.
+"Save" and "SavePoint" will warp the player back to their save point.
 
 
 See also 'warp'.
 See also 'warp'.
 
 
@@ -3974,6 +3976,11 @@ warp them to the map and coordinates given. It will return 1 upon success and
 0 if the partner is not online, the character is not married, or if there's no 
 0 if the partner is not online, the character is not married, or if there's no 
 invoking character (no RID). 0,0 will, as usual, normally translate to random coordinates.
 invoking character (no RID). 0,0 will, as usual, normally translate to random coordinates.
 
 
+There are also three special 'map names' you can use.
+
+"Random" will warp the player randomly on the current map.
+"Save" and "SavePoint" will warp the player back to their save point.
+
 ---------------------------------------
 ---------------------------------------
 
 
 *savepoint "<map name>",<x>,<y>{,{<range x>,<range y>,}<char_id>};
 *savepoint "<map name>",<x>,<y>{,{<range x>,<range y>,}<char_id>};
@@ -6716,6 +6723,11 @@ The obvious way of using this effectively would be to set up a waiting room for
 two characters to be warped onto a random PVP map for a one-on-one duel, for 
 two characters to be warped onto a random PVP map for a one-on-one duel, for 
 example.
 example.
 
 
+There are also three special 'map names' you can use.
+
+"Random" will warp the player randomly on the current map.
+"Save" and "SavePoint" will warp the player back to their save point.
+
 ---------------------------------------
 ---------------------------------------
 
 
 *waitingroomkick "<NPC object name>" , "<character name>";
 *waitingroomkick "<NPC object name>" , "<character name>";
@@ -6854,6 +6866,11 @@ Example:
 // Will warp all members of guild with ID 63 on map prontera to map alberta.
 // Will warp all members of guild with ID 63 on map prontera to map alberta.
 	mapwarp "prontera","alberta",150,150,1,63;
 	mapwarp "prontera","alberta",150,150,1,63;
 
 
+There are also three special 'map names' you can use for <to map>.
+
+"Random" will warp the player randomly on the current map.
+"Save" and "SavePoint" will warp the player back to their save point.
+
 ---------------------------------------
 ---------------------------------------
 \\
 \\
 5,2.- Guild-related commands
 5,2.- Guild-related commands

+ 100 - 64
src/map/script.c

@@ -5635,12 +5635,44 @@ BUILDIN_FUNC(rand)
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
-/*==========================================
- * Warp sd to str,x,y or Random or SavePoint/Save
- *------------------------------------------*/
+/**
+ * Warp character based on given parameters
+ * @param sd: Player data
+ * @param map: Map name/Warp type
+ * @param x: X location
+ * @param y: Y location
+ * @return 0 on success and failure otherwise
+ */
+static int buildin_warp_sub(struct map_session_data *sd, const char *map, int x, int y) {
+	int ret = 0;
+
+	nullpo_retr(1, sd);
+
+	if (strcmp(map, "Random") == 0)
+		ret = pc_randomwarp(sd, CLR_TELEPORT);
+	else if (strcmp(map, "SavePoint") == 0 || strcmp(map, "Save") == 0)
+		ret = pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
+	else {
+		int16 index = 0;
+
+		if (!(index = mapindex_name2id(map)))
+			return 1;
+
+		ret = pc_setpos(sd, index, x, y, CLR_OUTSIGHT);
+	}
+
+	if (ret)
+		ShowError("buildin_warp_sub: Moving player '%s' to \"%s\",%d,%d failed.\n", sd->status.name, map, x, y);
+
+	return ret;
+}
+
+/**
+ * Warp a player
+ * warp "map name",x,y{,char id};
+ */
 BUILDIN_FUNC(warp)
 BUILDIN_FUNC(warp)
 {
 {
-	int ret;
 	int x,y;
 	int x,y;
 	const char* str;
 	const char* str;
 	struct map_session_data* sd;
 	struct map_session_data* sd;
@@ -5652,36 +5684,33 @@ BUILDIN_FUNC(warp)
 	x = script_getnum(st,3);
 	x = script_getnum(st,3);
 	y = script_getnum(st,4);
 	y = script_getnum(st,4);
 
 
-	if(strcmp(str,"Random")==0)
-		ret = pc_randomwarp(sd,CLR_TELEPORT);
-	else if(strcmp(str,"SavePoint")==0 || strcmp(str,"Save")==0)
-		ret = pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
-	else
-		ret = pc_setpos(sd,mapindex_name2id(str),x,y,CLR_OUTSIGHT);
-
-	if( ret ) {
-		ShowError("buildin_warp: moving player '%s' to \"%s\",%d,%d failed.\n", sd->status.name, str, x, y);
+	if (buildin_warp_sub(sd, str, x, y))
 		return SCRIPT_CMD_FAILURE;
 		return SCRIPT_CMD_FAILURE;
-	}
 
 
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
-/*==========================================
+
+/**
  * Warp a specified area
  * Warp a specified area
- *------------------------------------------*/
+ * @param bl: Player to warp
+ * @param va_list: map index, x2, xy2, x3, y3, warp type
+ * @return 0 on success and failure otherwise
+ */
 static int buildin_areawarp_sub(struct block_list *bl,va_list ap)
 static int buildin_areawarp_sub(struct block_list *bl,va_list ap)
 {
 {
 	int x2,y2,x3,y3;
 	int x2,y2,x3,y3;
 	unsigned int index;
 	unsigned int index;
+	const char *str;
 
 
 	index = va_arg(ap,unsigned int);
 	index = va_arg(ap,unsigned int);
 	x2 = va_arg(ap,int);
 	x2 = va_arg(ap,int);
 	y2 = va_arg(ap,int);
 	y2 = va_arg(ap,int);
 	x3 = va_arg(ap,int);
 	x3 = va_arg(ap,int);
 	y3 = va_arg(ap,int);
 	y3 = va_arg(ap,int);
+	str = va_arg(ap,char *);
 
 
-	if(index == 0)
-		pc_randomwarp((TBL_PC *)bl,CLR_TELEPORT);
+	if (index == 0)
+		pc_randomwarp((TBL_PC *)bl, CLR_TELEPORT);
 	else if(x3 && y3) {
 	else if(x3 && y3) {
 		int max, tx, ty, j = 0;
 		int max, tx, ty, j = 0;
 		int16 m;
 		int16 m;
@@ -5699,13 +5728,19 @@ static int buildin_areawarp_sub(struct block_list *bl,va_list ap)
 			j++;
 			j++;
 		} while( map_getcell(m,tx,ty,CELL_CHKNOPASS) && j < max );
 		} while( map_getcell(m,tx,ty,CELL_CHKNOPASS) && j < max );
 
 
-		pc_setpos((TBL_PC *)bl,index,tx,ty,CLR_OUTSIGHT);
+		if (buildin_warp_sub((TBL_PC *)bl, str, tx, ty))
+			return 1;
+	} else {
+		if (buildin_warp_sub((TBL_PC *)bl, str, x2, y2))
+			return 1;
 	}
 	}
-	else
-		pc_setpos((TBL_PC *)bl,index,x2,y2,CLR_OUTSIGHT);
 	return 0;
 	return 0;
 }
 }
 
 
+/**
+ * Warp a given area of a map
+ * areawarp "<from map name>",<x1>,<y1>,<x2>,<y2>,"<to map name>",<x3>,<y3>{,<x4>,<y4>};
+ */
 BUILDIN_FUNC(areawarp)
 BUILDIN_FUNC(areawarp)
 {
 {
 	int16 m, x0,y0,x1,y1, x2,y2,x3=0,y3=0;
 	int16 m, x0,y0,x1,y1, x2,y2,x3=0,y3=0;
@@ -5741,7 +5776,7 @@ BUILDIN_FUNC(areawarp)
 	else if( !(index=mapindex_name2id(str)) )
 	else if( !(index=mapindex_name2id(str)) )
 		return SCRIPT_CMD_FAILURE;
 		return SCRIPT_CMD_FAILURE;
 
 
-	map_foreachinallarea(buildin_areawarp_sub, m,x0,y0,x1,y1, BL_PC, index,x2,y2,x3,y3);
+	map_foreachinallarea(buildin_areawarp_sub, m,x0,y0,x1,y1, BL_PC, index,x2,y2,x3,y3,NULL);
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
@@ -11970,12 +12005,7 @@ BUILDIN_FUNC(warpwaitingpc)
 
 
 		mapreg_setreg(reference_uid(add_str("$@warpwaitingpc"), i), sd->bl.id);
 		mapreg_setreg(reference_uid(add_str("$@warpwaitingpc"), i), sd->bl.id);
 
 
-		if( strcmp(map_name,"Random") == 0 )
-			pc_randomwarp(sd,CLR_TELEPORT);
-		else if( strcmp(map_name,"SavePoint") == 0 )
-			pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
-		else
-			pc_setpos(sd, mapindex_name2id(map_name), x, y, CLR_OUTSIGHT);
+		buildin_warp_sub(sd, map_name, x, y);
 	}
 	}
 	mapreg_setreg(add_str("$@warpwaitingpcnum"), i);
 	mapreg_setreg(add_str("$@warpwaitingpcnum"), i);
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
@@ -13117,58 +13147,56 @@ BUILDIN_FUNC(failedremovecards) {
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
-/* ================================================================
- * mapwarp "<from map>","<to map>",<x>,<y>,<type>,<ID for Type>;
- * type: 0=everyone, 1=guild, 2=party;	[Reddozen]
- * improved by [Lance]
- * ================================================================*/
-BUILDIN_FUNC(mapwarp)	// Added by RoVeRT
+/**
+ * Warp a given map
+ * mapwarp "<from map>","<to map>",<x>,<y>{,<type>,<ID>};
+ * @author [Reddozen], [RoVeRT]; improved by [Lance]
+ */
+BUILDIN_FUNC(mapwarp)
 {
 {
-	int x,y,m,check_val=0,check_ID=0,i=0;
+	int x, y, m, check_val = 0, check_ID = 0, i = 0;
 	struct guild *g = NULL;
 	struct guild *g = NULL;
 	struct party_data *p = NULL;
 	struct party_data *p = NULL;
-	const char *str;
-	const char *mapname;
+	const char *str, *mapname;
 	unsigned int index;
 	unsigned int index;
-	mapname=script_getstr(st,2);
-	str=script_getstr(st,3);
-	x=script_getnum(st,4);
-	y=script_getnum(st,5);
-	if(script_hasdata(st,7)){
-		check_val=script_getnum(st,6);
-		check_ID=script_getnum(st,7);
+
+	mapname = script_getstr(st, 2);
+	str = script_getstr(st, 3);
+	x = script_getnum(st, 4);
+	y = script_getnum(st, 5);
+
+	if (script_hasdata(st, 7)){
+		check_val = script_getnum(st, 6);
+		check_ID = script_getnum(st, 7);
 	}
 	}
 
 
-	if((m=map_mapname2mapid(mapname))< 0)
-		return SCRIPT_CMD_SUCCESS;
+	if ((m = map_mapname2mapid(mapname)) < 0)
+		return SCRIPT_CMD_FAILURE;
 
 
-	if(!(index=mapindex_name2id(str)))
-		return SCRIPT_CMD_SUCCESS;
+	if (!(index = mapindex_name2id(str)))
+		return SCRIPT_CMD_FAILURE;
 
 
-	switch(check_val){
+	switch (check_val) {
 		case 1:
 		case 1:
 			g = guild_search(check_ID);
 			g = guild_search(check_ID);
-			if (g){
-				for( i=0; i < g->max_member; i++)
-				{
-					if(g->member[i].sd && g->member[i].sd->bl.m==m){
-						pc_setpos(g->member[i].sd,index,x,y,CLR_TELEPORT);
-					}
+			if (g) {
+				for (i = 0; i < g->max_member; i++) {
+					if (g->member[i].sd && g->member[i].sd->bl.m == m)
+						buildin_warp_sub(g->member[i].sd, str, x, y);
 				}
 				}
 			}
 			}
 			break;
 			break;
 		case 2:
 		case 2:
 			p = party_search(check_ID);
 			p = party_search(check_ID);
-			if(p){
-				for(i=0;i<MAX_PARTY; i++){
-					if(p->data[i].sd && p->data[i].sd->bl.m == m){
-						pc_setpos(p->data[i].sd,index,x,y,CLR_TELEPORT);
-					}
+			if (p) {
+				for (i = 0; i < MAX_PARTY; i++) {
+					if (p->data[i].sd && p->data[i].sd->bl.m == m)
+						buildin_warp_sub(p->data[i].sd, str, x, y);
 				}
 				}
 			}
 			}
 			break;
 			break;
 		default:
 		default:
-			map_foreachinmap(buildin_areawarp_sub,m,BL_PC,index,x,y,0,0);
+			map_foreachinmap(buildin_areawarp_sub, m, BL_PC, index, x, y, 0, 0, str);
 			break;
 			break;
 	}
 	}
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
@@ -13336,6 +13364,10 @@ BUILDIN_FUNC(getfatherid)
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
+/**
+ * Warp a marriage partner
+ * warppartner("<map name>",<x>,<y>);
+ */
 BUILDIN_FUNC(warppartner)
 BUILDIN_FUNC(warppartner)
 {
 {
 	int x,y;
 	int x,y;
@@ -13356,11 +13388,15 @@ BUILDIN_FUNC(warppartner)
 
 
 	mapindex = mapindex_name2id(str);
 	mapindex = mapindex_name2id(str);
 	if (mapindex) {
 	if (mapindex) {
-		pc_setpos(p_sd,mapindex,x,y,CLR_OUTSIGHT);
-		script_pushint(st,1);
+		if (buildin_warp_sub(p_sd, str, x, y))
+			script_pushint(st, 0);
+		else {
+			script_pushint(st, 1);
+			return SCRIPT_CMD_SUCCESS;
+		}
 	} else
 	} else
 		script_pushint(st,0);
 		script_pushint(st,0);
-	return SCRIPT_CMD_SUCCESS;
+	return SCRIPT_CMD_FAILURE;
 }
 }
 
 
 /*================================================
 /*================================================