Follow up to 22812b4
* Created a define for maximum warp attempts. * Added SETPOS_MAX_ATTEMPTS for pc_setpos. * Adjusted buildin_warp_sub to return enum e_setpos. * Removed pc_randomwarp since it was just duplicate code and pc_setpos already contained the same exact functions. * Fixed a few locations where a destination point would fail when searching for the map index. * Added clan type to script command mapwarp. * Adjusted various variable types to match. Thanks to @Lemongrass3110's suggestions!
This commit is contained in:
parent
22812b4de3
commit
e248246257
@ -3917,6 +3917,8 @@ 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.
|
||||
|
||||
Use 0,0 as the x3/y3 values when using a special 'map name'.
|
||||
|
||||
See also 'warp'.
|
||||
|
||||
---------------------------------------
|
||||
@ -3972,8 +3974,8 @@ warpguild "prontera",x,y,Guild_ID;
|
||||
*warppartner("<map name>",<x>,<y>);
|
||||
|
||||
This function will find the invoking character's marriage partner, if any, and
|
||||
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
|
||||
warp them to the map and coordinates given. It will return true upon success and
|
||||
false 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.
|
||||
|
||||
There are also three special 'map names' you can use.
|
||||
@ -6860,6 +6862,7 @@ Optionally, a type and ID can be specified. Available types are:
|
||||
0 - Everyone
|
||||
1 - Guild
|
||||
2 - Party
|
||||
3 - Clan
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@ -162,6 +162,8 @@
|
||||
#define EL_CLASS_BASE 2114
|
||||
#define EL_CLASS_MAX (EL_CLASS_BASE+MAX_ELEMENTAL_CLASS-1)
|
||||
|
||||
#define MAX_WARP_ATTEMPTS 1000 /// Max amount of attempts to randomly warp a character onto valid coordinates
|
||||
|
||||
enum item_types {
|
||||
IT_HEALING = 0,
|
||||
IT_UNKNOWN, //1
|
||||
|
||||
62
src/map/pc.c
62
src/map/pc.c
@ -5351,19 +5351,20 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *target)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
/**
|
||||
* Set's a player position.
|
||||
* @param sd
|
||||
* @param mapindex
|
||||
* @param x
|
||||
* @param y
|
||||
* @param clrtype
|
||||
* @param sd: Player's data
|
||||
* @param mapindex: Map index of destination
|
||||
* @param x: X location
|
||||
* @param y: Y location
|
||||
* @param clrtype: Warp type
|
||||
* @return SETPOS_OK Success
|
||||
* SETPOS_MAPINDEX Invalid map index
|
||||
* SETPOS_NO_MAPSERVER Map not in this map-server, and failed to locate alternate map-server.
|
||||
* SETPOS_AUTOTRADE Player is in autotrade state
|
||||
*------------------------------------------*/
|
||||
enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype)
|
||||
* SETPOS_MAX_ATTEMPTS Maximum number of warp attempts met
|
||||
*/
|
||||
enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, int16 x, int16 y, clr_type clrtype)
|
||||
{
|
||||
int16 m;
|
||||
|
||||
@ -5480,18 +5481,17 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
|
||||
}
|
||||
|
||||
if( x == 0 && y == 0 ) { // pick a random walkable cell
|
||||
int c=0;
|
||||
int c = 0;
|
||||
|
||||
do {
|
||||
x = rnd()%(map[m].xs-2)+1;
|
||||
y = rnd()%(map[m].ys-2)+1;
|
||||
c++;
|
||||
} while((map_getcell(m, x, y, CELL_CHKNOPASS) || (!battle_config.teleport_on_portal && npc_check_areanpc(1, m, x, y, 1))) && (c++) < MAX_WARP_ATTEMPTS);
|
||||
|
||||
if(c > (map[m].xs * map[m].ys)*3){ //force out
|
||||
ShowError("pc_setpos: couldn't found a valid coordinates for player '%s' (%d:%d) on (%s), preventing warp\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex));
|
||||
return SETPOS_OK; //preventing warp
|
||||
//break; //allow warp anyway
|
||||
}
|
||||
} while(map_getcell(m,x,y,CELL_CHKNOPASS) || (!battle_config.teleport_on_portal && npc_check_areanpc(1,m,x,y,1)));
|
||||
if (c == MAX_WARP_ATTEMPTS) {
|
||||
ShowError("pc_setpos: Couldn't find valid coordinates for player '%s' (%d:%d) on (%s), preventing warp.\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex));
|
||||
return SETPOS_MAX_ATTEMPTS;
|
||||
}
|
||||
}
|
||||
|
||||
if (sd->state.vending && map_getcell(m,x,y,CELL_CHKNOVENDING)) {
|
||||
@ -5560,36 +5560,6 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
|
||||
return SETPOS_OK;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Warp player sd to random location on current map.
|
||||
* May fail if no walkable cell found (1000 attempts).
|
||||
* Return:
|
||||
* 0 = Success
|
||||
* 1,2,3 = Fail
|
||||
*------------------------------------------*/
|
||||
char pc_randomwarp(struct map_session_data *sd, clr_type type)
|
||||
{
|
||||
int x,y,i=0;
|
||||
int16 m;
|
||||
|
||||
nullpo_ret(sd);
|
||||
|
||||
m=sd->bl.m;
|
||||
|
||||
if (map[sd->bl.m].flag.noteleport) //Teleport forbidden
|
||||
return 3;
|
||||
|
||||
do {
|
||||
x = rnd()%(map[m].xs-2)+1;
|
||||
y = rnd()%(map[m].ys-2)+1;
|
||||
} while((map_getcell(m,x,y,CELL_CHKNOPASS) || (!battle_config.teleport_on_portal && npc_check_areanpc(1,m,x,y,1))) && (i++) < 1000);
|
||||
|
||||
if (i < 1000)
|
||||
return pc_setpos(sd,map[sd->bl.m].index,x,y,type);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Records a memo point at sd's current position
|
||||
* pos - entry to replace, (-1: shift oldest entry out)
|
||||
|
||||
10
src/map/pc.h
10
src/map/pc.h
@ -1014,14 +1014,14 @@ void pc_clean_skilltree(struct map_session_data *sd);
|
||||
|
||||
enum e_setpos{
|
||||
SETPOS_OK = 0,
|
||||
SETPOS_MAPINDEX = 1,
|
||||
SETPOS_NO_MAPSERVER = 2,
|
||||
SETPOS_AUTOTRADE = 3
|
||||
SETPOS_MAPINDEX,
|
||||
SETPOS_NO_MAPSERVER,
|
||||
SETPOS_AUTOTRADE,
|
||||
SETPOS_MAX_ATTEMPTS
|
||||
};
|
||||
|
||||
enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype);
|
||||
enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, int16 x, int16 y, clr_type clrtype);
|
||||
void pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y);
|
||||
char pc_randomwarp(struct map_session_data *sd,clr_type type);
|
||||
bool pc_memo(struct map_session_data* sd, int pos);
|
||||
|
||||
char pc_checkadditem(struct map_session_data *sd, unsigned short nameid, int amount);
|
||||
|
||||
125
src/map/script.c
125
src/map/script.c
@ -5641,30 +5641,23 @@ BUILDIN_FUNC(rand)
|
||||
* @param map: Map name/Warp type
|
||||
* @param x: X location
|
||||
* @param y: Y location
|
||||
* @return 0 on success and failure otherwise
|
||||
* @return SETPOS_OK on success and failure otherwise (see pc.h::e_setpos)
|
||||
*/
|
||||
static int buildin_warp_sub(struct map_session_data *sd, const char *map, int x, int y) {
|
||||
int ret = 0;
|
||||
|
||||
nullpo_retr(1, sd);
|
||||
static enum e_setpos buildin_warp_sub(struct map_session_data *sd, const char *map, int16 x, int16 y) {
|
||||
nullpo_retr(SETPOS_OK, sd);
|
||||
|
||||
if (strcmp(map, "Random") == 0)
|
||||
ret = pc_randomwarp(sd, CLR_TELEPORT);
|
||||
return pc_setpos(sd, sd->mapindex, 0, 0, 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);
|
||||
return pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
|
||||
else {
|
||||
int16 index = 0;
|
||||
int16 index;
|
||||
|
||||
if (!(index = mapindex_name2id(map)))
|
||||
return 1;
|
||||
return SETPOS_MAPINDEX;
|
||||
|
||||
ret = pc_setpos(sd, index, x, y, CLR_OUTSIGHT);
|
||||
return 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5673,7 +5666,7 @@ static int buildin_warp_sub(struct map_session_data *sd, const char *map, int x,
|
||||
*/
|
||||
BUILDIN_FUNC(warp)
|
||||
{
|
||||
int x,y;
|
||||
int16 x, y;
|
||||
const char* str;
|
||||
struct map_session_data* sd;
|
||||
|
||||
@ -5698,39 +5691,35 @@ BUILDIN_FUNC(warp)
|
||||
*/
|
||||
static int buildin_areawarp_sub(struct block_list *bl,va_list ap)
|
||||
{
|
||||
int x2,y2,x3,y3;
|
||||
int16 x2,y2,x3,y3;
|
||||
unsigned int index;
|
||||
const char *str;
|
||||
|
||||
index = va_arg(ap,unsigned int);
|
||||
x2 = va_arg(ap,int);
|
||||
y2 = va_arg(ap,int);
|
||||
x3 = va_arg(ap,int);
|
||||
y3 = va_arg(ap,int);
|
||||
str = va_arg(ap,char *);
|
||||
x2 = va_arg(ap,int16);
|
||||
y2 = va_arg(ap,int16);
|
||||
x3 = va_arg(ap,int16);
|
||||
y3 = va_arg(ap,int16);
|
||||
str = va_arg(ap, char *);
|
||||
|
||||
if (index == 0)
|
||||
pc_randomwarp((TBL_PC *)bl, CLR_TELEPORT);
|
||||
else if(x3 && y3) {
|
||||
int max, tx, ty, j = 0;
|
||||
int16 m;
|
||||
if (x3 && y3) { // Warp within given area
|
||||
int16 max, tx, ty, j = 0, m;
|
||||
|
||||
m = map_mapindex2mapid(index);
|
||||
|
||||
// choose a suitable max number of attempts
|
||||
if( (max = (y3-y2+1)*(x3-x2+1)*3) > 1000 )
|
||||
max = 1000;
|
||||
if( (max = (y3-y2+1)*(x3-x2+1)*3) > MAX_WARP_ATTEMPTS )
|
||||
max = MAX_WARP_ATTEMPTS;
|
||||
|
||||
// find a suitable map cell
|
||||
do {
|
||||
tx = rnd()%(x3-x2+1)+x2;
|
||||
ty = rnd()%(y3-y2+1)+y2;
|
||||
j++;
|
||||
} while( map_getcell(m,tx,ty,CELL_CHKNOPASS) && j < max );
|
||||
} while (map_getcell(m, tx, ty, CELL_CHKNOPASS) && (j++) < max);
|
||||
|
||||
if (buildin_warp_sub((TBL_PC *)bl, str, tx, ty))
|
||||
return 1;
|
||||
} else {
|
||||
} else { // Warp to set location
|
||||
if (buildin_warp_sub((TBL_PC *)bl, str, x2, y2))
|
||||
return 1;
|
||||
}
|
||||
@ -5744,7 +5733,6 @@ static int buildin_areawarp_sub(struct block_list *bl,va_list ap)
|
||||
BUILDIN_FUNC(areawarp)
|
||||
{
|
||||
int16 m, x0,y0,x1,y1, x2,y2,x3=0,y3=0;
|
||||
unsigned int index;
|
||||
const char *str;
|
||||
const char *mapname;
|
||||
|
||||
@ -5768,15 +5756,10 @@ BUILDIN_FUNC(areawarp)
|
||||
}
|
||||
}
|
||||
|
||||
if( (m = map_mapname2mapid(mapname)) < 0 )
|
||||
if ((m = map_mapname2mapid(mapname)) < 0)
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
if( strcmp(str,"Random") == 0 )
|
||||
index = 0;
|
||||
else if( !(index=mapindex_name2id(str)) )
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
map_foreachinallarea(buildin_areawarp_sub, m,x0,y0,x1,y1, BL_PC, index,x2,y2,x3,y3,NULL);
|
||||
map_foreachinallarea(buildin_areawarp_sub, m, x0, y0, x1, y1, BL_PC, mapindex_name2id(str), x2, y2, x3, y3, str);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -5888,7 +5871,7 @@ BUILDIN_FUNC(warpparty)
|
||||
{
|
||||
case 0: // Random
|
||||
if(!map[pl_sd->bl.m].flag.nowarp)
|
||||
pc_randomwarp(pl_sd,CLR_TELEPORT);
|
||||
pc_setpos(pl_sd, pl_sd->bl.m, 0, 0, CLR_TELEPORT);
|
||||
break;
|
||||
case 1: // SavePointAll
|
||||
if(!map[pl_sd->bl.m].flag.noreturn)
|
||||
@ -5972,7 +5955,7 @@ BUILDIN_FUNC(warpguild)
|
||||
{
|
||||
case 0: // Random
|
||||
if(!map[pl_sd->bl.m].flag.nowarp)
|
||||
pc_randomwarp(pl_sd,CLR_TELEPORT);
|
||||
pc_setpos(pl_sd, pl_sd->bl.m, 0, 0, CLR_TELEPORT);
|
||||
break;
|
||||
case 1: // SavePointAll
|
||||
if(!map[pl_sd->bl.m].flag.noreturn)
|
||||
@ -11965,10 +11948,7 @@ BUILDIN_FUNC(getwaitingroomstate)
|
||||
/// warpwaitingpc "<map name>",<x>,<y>;
|
||||
BUILDIN_FUNC(warpwaitingpc)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int i;
|
||||
int n;
|
||||
int16 x, y, i, n;
|
||||
const char* map_name;
|
||||
struct npc_data* nd;
|
||||
struct chat_data* cd;
|
||||
@ -11989,10 +11969,8 @@ BUILDIN_FUNC(warpwaitingpc)
|
||||
{
|
||||
TBL_PC* sd = cd->usersd[0];
|
||||
|
||||
if( strcmp(map_name,"SavePoint") == 0 && map[sd->bl.m].flag.noteleport )
|
||||
{// can't teleport on this map
|
||||
if ((strcmp(map_name, "SavePoint") == 0 || strcmp(map_name, "Save") == 0) && map[sd->bl.m].flag.noteleport) // Can't teleport on the current map
|
||||
break;
|
||||
}
|
||||
|
||||
if( cd->zeny )
|
||||
{// fee set
|
||||
@ -13154,11 +13132,12 @@ BUILDIN_FUNC(failedremovecards) {
|
||||
*/
|
||||
BUILDIN_FUNC(mapwarp)
|
||||
{
|
||||
int x, y, m, check_val = 0, check_ID = 0, i = 0;
|
||||
int16 x, y, m, type = 0, i = 0;
|
||||
int type_id = 0;
|
||||
struct guild *g = NULL;
|
||||
struct party_data *p = NULL;
|
||||
struct clan *c = NULL;
|
||||
const char *str, *mapname;
|
||||
unsigned int index;
|
||||
|
||||
mapname = script_getstr(st, 2);
|
||||
str = script_getstr(st, 3);
|
||||
@ -13166,19 +13145,16 @@ BUILDIN_FUNC(mapwarp)
|
||||
y = script_getnum(st, 5);
|
||||
|
||||
if (script_hasdata(st, 7)){
|
||||
check_val = script_getnum(st, 6);
|
||||
check_ID = script_getnum(st, 7);
|
||||
type = script_getnum(st, 6);
|
||||
type_id = script_getnum(st, 7);
|
||||
}
|
||||
|
||||
if ((m = map_mapname2mapid(mapname)) < 0)
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
if (!(index = mapindex_name2id(str)))
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
switch (check_val) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
g = guild_search(check_ID);
|
||||
g = guild_search(type_id);
|
||||
if (g) {
|
||||
for (i = 0; i < g->max_member; i++) {
|
||||
if (g->member[i].sd && g->member[i].sd->bl.m == m)
|
||||
@ -13187,7 +13163,7 @@ BUILDIN_FUNC(mapwarp)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
p = party_search(check_ID);
|
||||
p = party_search(type_id);
|
||||
if (p) {
|
||||
for (i = 0; i < MAX_PARTY; i++) {
|
||||
if (p->data[i].sd && p->data[i].sd->bl.m == m)
|
||||
@ -13195,8 +13171,17 @@ BUILDIN_FUNC(mapwarp)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
c = clan_search(type_id);
|
||||
if (c) {
|
||||
for (i = 0; i < MAX_CLAN; i++) {
|
||||
if (c->members[i] && c->members[i]->bl.m == m)
|
||||
buildin_warp_sub(c->members[i], str, x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
map_foreachinmap(buildin_areawarp_sub, m, BL_PC, index, x, y, 0, 0, str);
|
||||
map_foreachinmap(buildin_areawarp_sub, m, BL_PC, mapindex_name2id(str), x, y, 0, 0, str);
|
||||
break;
|
||||
}
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
@ -13370,11 +13355,9 @@ BUILDIN_FUNC(getfatherid)
|
||||
*/
|
||||
BUILDIN_FUNC(warppartner)
|
||||
{
|
||||
int x,y;
|
||||
unsigned short mapindex;
|
||||
int16 x, y;
|
||||
const char *str;
|
||||
TBL_PC *sd;
|
||||
TBL_PC *p_sd;
|
||||
TBL_PC *sd, *p_sd;
|
||||
|
||||
if(!script_rid2sd(sd) || !pc_ismarried(sd) ||
|
||||
(p_sd=map_charid2sd(sd->status.partner_id)) == NULL) {
|
||||
@ -13386,16 +13369,12 @@ BUILDIN_FUNC(warppartner)
|
||||
x=script_getnum(st,3);
|
||||
y=script_getnum(st,4);
|
||||
|
||||
mapindex = mapindex_name2id(str);
|
||||
if (mapindex) {
|
||||
if (buildin_warp_sub(p_sd, str, x, y))
|
||||
script_pushint(st, 0);
|
||||
else {
|
||||
script_pushint(st, 1);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
if (buildin_warp_sub(p_sd, str, x, y) == SETPOS_OK) {
|
||||
script_pushint(st, true);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
} else
|
||||
script_pushint(st,0);
|
||||
script_pushint(st, false);
|
||||
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@ -7531,7 +7531,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
if( sd->state.autocast || ( (sd->skillitem == AL_TELEPORT || battle_config.skip_teleport_lv1_menu) && skill_lv == 1 ) || skill_lv == 3 )
|
||||
{
|
||||
if( skill_lv == 1 )
|
||||
pc_randomwarp(sd,CLR_TELEPORT);
|
||||
pc_setpos(sd, sd->bl.m, 0, 0, CLR_TELEPORT);
|
||||
else
|
||||
pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
|
||||
break;
|
||||
@ -12303,7 +12303,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
|
||||
//any kind of map change, so we need to restore it automatically
|
||||
//bugreport:8027
|
||||
if(strcmp(mapname,"Random") == 0)
|
||||
pc_randomwarp(sd,CLR_TELEPORT);
|
||||
pc_setpos(sd, sd->bl.m, 0, 0, CLR_TELEPORT);
|
||||
else if (sd->menuskill_val > 1 || skill_id == ALL_ODINS_RECALL) //Need lv2 to be able to warp here.
|
||||
pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
|
||||
|
||||
@ -13925,7 +13925,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
|
||||
|
||||
case UNT_DIMENSIONDOOR:
|
||||
if( tsd && !map[bl->m].flag.noteleport )
|
||||
pc_randomwarp(tsd,CLR_TELEPORT);
|
||||
pc_setpos(tsd, tsd->bl.m, 0, 0, CLR_TELEPORT);
|
||||
else if( bl->type == BL_MOB && battle_config.mob_warp&8 )
|
||||
unit_warp(bl,-1,-1,-1,CLR_TELEPORT);
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user