Initial release: Map X Job restriction (#1526)
* Listed job with matched map zone is restricted to enter the map. * Added db file `job_noenter_map.txt` with format: `JobID,FlagZone,GroupLevelBypass`. * Reserved usage for WOE:TE implementation. * Typo correction, thanks @aleos89 @Lemongrass3110
This commit is contained in:
parent
b3b2bab7c5
commit
d84d6ba1e5
27
db/import-tmpl/job_noenter_map.txt
Normal file
27
db/import-tmpl/job_noenter_map.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Defines Job(s) that are restricted to enter map (by flag/zones)
|
||||||
|
//
|
||||||
|
// Structure of Database:
|
||||||
|
// JobID,FlagZone,GroupLevelBypass
|
||||||
|
//
|
||||||
|
// JobID: See JOB_* constants or use job number
|
||||||
|
//
|
||||||
|
// Legend for 'Flag' field (bitmask):
|
||||||
|
// 1 - restricted in normal maps
|
||||||
|
// 2 - restricted in PVP
|
||||||
|
// 4 - restricted in GVG
|
||||||
|
// 8 - restricted in Battlegrounds
|
||||||
|
// Restricted zones - configured by 'restricted <number>' mapflag
|
||||||
|
// 32 - restricted in zone 1
|
||||||
|
// 64 - restricted in zone 2
|
||||||
|
// 128 - restricted in zone 3
|
||||||
|
// 256 - restricted in zone 4
|
||||||
|
// 512 - restricted in zone 5
|
||||||
|
// 1024 - restricted in zone 6
|
||||||
|
// 2048 - restricted in zone 7
|
||||||
|
// 4096 - restricted in zone 8
|
||||||
|
//
|
||||||
|
// GroupLevelBypass: Group Level (groups.conf) to ignore the restriction
|
||||||
|
//
|
||||||
|
// NOTES:
|
||||||
|
// - Restriction will be overwritten for multiple defines with the same Job ID
|
||||||
|
// - The flag is used by 'jobcanentermap' script.
|
27
db/pre-re/job_noenter_map.txt
Normal file
27
db/pre-re/job_noenter_map.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Defines Job(s) that are restricted to enter map (by flag/zones)
|
||||||
|
//
|
||||||
|
// Structure of Database:
|
||||||
|
// JobID,FlagZone,GroupLevelBypass
|
||||||
|
//
|
||||||
|
// JobID: See JOB_* constants or use job number
|
||||||
|
//
|
||||||
|
// Legend for 'Flag' field (bitmask):
|
||||||
|
// 1 - restricted in normal maps
|
||||||
|
// 2 - restricted in PVP
|
||||||
|
// 4 - restricted in GVG
|
||||||
|
// 8 - restricted in Battlegrounds
|
||||||
|
// Restricted zones - configured by 'restricted <number>' mapflag
|
||||||
|
// 32 - restricted in zone 1
|
||||||
|
// 64 - restricted in zone 2
|
||||||
|
// 128 - restricted in zone 3
|
||||||
|
// 256 - restricted in zone 4
|
||||||
|
// 512 - restricted in zone 5
|
||||||
|
// 1024 - restricted in zone 6
|
||||||
|
// 2048 - restricted in zone 7
|
||||||
|
// 4096 - restricted in zone 8
|
||||||
|
//
|
||||||
|
// GroupLevelBypass: Group Level (groups.conf) to ignore the restriction
|
||||||
|
//
|
||||||
|
// NOTES:
|
||||||
|
// - Restriction will be overwritten for multiple defines with the same Job ID
|
||||||
|
// - The flag is used by 'jobcanentermap' script.
|
27
db/re/job_noenter_map.txt
Normal file
27
db/re/job_noenter_map.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Defines Job(s) that are restricted to enter map (by flag/zones)
|
||||||
|
//
|
||||||
|
// Structure of Database:
|
||||||
|
// JobID,FlagZone,GroupLevelBypass
|
||||||
|
//
|
||||||
|
// JobID: See JOB_* constants or use job number
|
||||||
|
//
|
||||||
|
// Legend for 'Flag' field (bitmask):
|
||||||
|
// 1 - restricted in normal maps
|
||||||
|
// 2 - restricted in PVP
|
||||||
|
// 4 - restricted in GVG
|
||||||
|
// 8 - restricted in Battlegrounds
|
||||||
|
// Restricted zones - configured by 'restricted <number>' mapflag
|
||||||
|
// 32 - restricted in zone 1
|
||||||
|
// 64 - restricted in zone 2
|
||||||
|
// 128 - restricted in zone 3
|
||||||
|
// 256 - restricted in zone 4
|
||||||
|
// 512 - restricted in zone 5
|
||||||
|
// 1024 - restricted in zone 6
|
||||||
|
// 2048 - restricted in zone 7
|
||||||
|
// 4096 - restricted in zone 8
|
||||||
|
//
|
||||||
|
// GroupLevelBypass: Group Level (groups.conf) to ignore the restriction
|
||||||
|
//
|
||||||
|
// NOTES:
|
||||||
|
// - Restriction will be overwritten for multiple defines with the same Job ID
|
||||||
|
// - The flag is used by 'jobcanentermap' script.
|
@ -4302,6 +4302,17 @@ raise the specified stat from (current value - <val>) to current value.
|
|||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
*jobcanentermap("<mapname>"{,<JobID>});
|
||||||
|
|
||||||
|
Return true if player (decided by job) can enter the map, false otherwise.
|
||||||
|
|
||||||
|
For optional 'JobID', see constant of Job_*, or use player's Class, BaseJob,
|
||||||
|
and BaseClass. If no player is attached, this param must have a value.
|
||||||
|
|
||||||
|
See also db/[pre-]re/job_noenter_map.txt
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
*get_revision()
|
*get_revision()
|
||||||
|
|
||||||
This command will return the SVN revision number that the server is currently
|
This command will return the SVN revision number that the server is currently
|
||||||
|
@ -402,7 +402,7 @@ struct mmo_charstatus {
|
|||||||
unsigned int base_exp,job_exp;
|
unsigned int base_exp,job_exp;
|
||||||
int zeny;
|
int zeny;
|
||||||
|
|
||||||
short class_;
|
short class_; ///< Player's JobID
|
||||||
unsigned int status_point,skill_point;
|
unsigned int status_point,skill_point;
|
||||||
int hp,max_hp,sp,max_sp;
|
int hp,max_hp,sp,max_sp;
|
||||||
unsigned int option;
|
unsigned int option;
|
||||||
|
@ -475,7 +475,7 @@ ACMD_FUNC(mapmove)
|
|||||||
if (!map_search_freecell(NULL, m, &x, &y, 10, 10, 1))
|
if (!map_search_freecell(NULL, m, &x, &y, 10, 10, 1))
|
||||||
x = y = 0; //Invalid cell, use random spot.
|
x = y = 0; //Invalid cell, use random spot.
|
||||||
}
|
}
|
||||||
if (map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
|
if ((map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) || !pc_job_can_entermap((enum e_job)sd->status.class_, m, sd->group_level)) {
|
||||||
clif_displaymessage(fd, msg_txt(sd,247));
|
clif_displaymessage(fd, msg_txt(sd,247));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
62
src/map/pc.c
62
src/map/pc.c
@ -113,7 +113,7 @@ struct item_cd {
|
|||||||
* Converts a class to its array index for CLASS_COUNT defined arrays.
|
* Converts a class to its array index for CLASS_COUNT defined arrays.
|
||||||
* Note that it does not do a validity check for speed purposes, where parsing
|
* Note that it does not do a validity check for speed purposes, where parsing
|
||||||
* player input make sure to use a pcdb_checkid first!
|
* player input make sure to use a pcdb_checkid first!
|
||||||
* @param class_
|
* @param class_ Job ID see enum e_job
|
||||||
* @return Class Index
|
* @return Class Index
|
||||||
*/
|
*/
|
||||||
int pc_class2idx(int class_) {
|
int pc_class2idx(int class_) {
|
||||||
@ -11117,6 +11117,31 @@ static bool pc_readdb_job_param(char* fields[], int columns, int current)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read job_noenter_map.txt
|
||||||
|
**/
|
||||||
|
static bool pc_readdb_job_noenter_map(char *str[], int columns, int current) {
|
||||||
|
int idx, class_ = -1;
|
||||||
|
|
||||||
|
if (ISDIGIT(str[0][0])) {
|
||||||
|
class_ = atoi(str[0]);
|
||||||
|
} else {
|
||||||
|
if (!script_get_constant(str[0], &class_)) {
|
||||||
|
ShowError("pc_readdb_job_noenter_map: Invalid job %s specified.\n", str[0]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pcdb_checkid(class_) || (idx = pc_class2idx(class_)) < 0) {
|
||||||
|
ShowError("pc_readdb_job_noenter_map: Invalid job %d specified.\n", str[0]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
job_info[idx].noenter_map.zone = atoi(str[1]);
|
||||||
|
job_info[idx].noenter_map.group_lv = atoi(str[2]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int pc_read_statsdb(const char *basedir, int last_s, bool silent){
|
static int pc_read_statsdb(const char *basedir, int last_s, bool silent){
|
||||||
int i=1;
|
int i=1;
|
||||||
char line[24000]; //FIXME this seem too big
|
char line[24000]; //FIXME this seem too big
|
||||||
@ -11220,6 +11245,7 @@ void pc_readdb(void) {
|
|||||||
sv_readdb(dbsubpath2, "job_basehpsp_db.txt", ',', 4, 4+500, CLASS_COUNT*2, &pc_readdb_job_basehpsp, i); //Make it support until lvl 500!
|
sv_readdb(dbsubpath2, "job_basehpsp_db.txt", ',', 4, 4+500, CLASS_COUNT*2, &pc_readdb_job_basehpsp, i); //Make it support until lvl 500!
|
||||||
#endif
|
#endif
|
||||||
sv_readdb(dbsubpath2, "job_param_db.txt", ',', 2, PARAM_MAX+1, CLASS_COUNT, &pc_readdb_job_param, i);
|
sv_readdb(dbsubpath2, "job_param_db.txt", ',', 2, PARAM_MAX+1, CLASS_COUNT, &pc_readdb_job_param, i);
|
||||||
|
sv_readdb(dbsubpath2, "job_noenter_map.txt", ',', 3, 3, CLASS_COUNT, &pc_readdb_job_noenter_map, i);
|
||||||
aFree(dbsubpath1);
|
aFree(dbsubpath1);
|
||||||
aFree(dbsubpath2);
|
aFree(dbsubpath2);
|
||||||
}
|
}
|
||||||
@ -12177,6 +12203,40 @@ void pc_show_questinfo_reinit(struct map_session_data *sd) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a job is allowed to enter the map
|
||||||
|
* @param jobid Job ID see enum e_job or sd->status.class_
|
||||||
|
* @param m ID -an index- for direct indexing map[] array
|
||||||
|
* @return 1 if job is allowed, 0 otherwise
|
||||||
|
**/
|
||||||
|
bool pc_job_can_entermap(enum e_job jobid, int m, int group_lv) {
|
||||||
|
uint16 idx = 0;
|
||||||
|
|
||||||
|
// Map is other map server.
|
||||||
|
// !FIXME: Currently, a map-server doesn't recognized map's attributes on other server, so we assume it's fine to warp.
|
||||||
|
if (m < 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (m >= MAX_MAP_PER_SERVER || !map[m].cell)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!pcdb_checkid(jobid))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
idx = pc_class2idx(jobid);
|
||||||
|
if (!job_info[idx].noenter_map.zone || group_lv > job_info[idx].noenter_map.group_lv)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ((!map_flag_vs(m) && job_info[idx].noenter_map.zone&1) || // Normal
|
||||||
|
(map[m].flag.pvp && job_info[idx].noenter_map.zone&2) || // PVP
|
||||||
|
(map_flag_gvg2(m) && job_info[idx].noenter_map.zone&4) || // GVG
|
||||||
|
(map[m].flag.battleground && job_info[idx].noenter_map.zone&8) || // Battleground
|
||||||
|
(map[m].flag.restricted && job_info[idx].noenter_map.zone&(8*map[m].zone)) // Zone restriction
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* pc Init/Terminate
|
* pc Init/Terminate
|
||||||
|
@ -796,6 +796,10 @@ struct {
|
|||||||
struct s_params {
|
struct s_params {
|
||||||
uint16 str, agi, vit, int_, dex, luk;
|
uint16 str, agi, vit, int_, dex, luk;
|
||||||
} max_param;
|
} max_param;
|
||||||
|
struct s_job_noenter_map {
|
||||||
|
uint32 zone;
|
||||||
|
uint8 group_lv;
|
||||||
|
} noenter_map;
|
||||||
} job_info[CLASS_COUNT];
|
} job_info[CLASS_COUNT];
|
||||||
|
|
||||||
#define EQP_WEAPON EQP_HAND_R
|
#define EQP_WEAPON EQP_HAND_R
|
||||||
@ -1262,6 +1266,8 @@ void pc_validate_skill(struct map_session_data *sd);
|
|||||||
void pc_show_questinfo(struct map_session_data *sd);
|
void pc_show_questinfo(struct map_session_data *sd);
|
||||||
void pc_show_questinfo_reinit(struct map_session_data *sd);
|
void pc_show_questinfo_reinit(struct map_session_data *sd);
|
||||||
|
|
||||||
|
bool pc_job_can_entermap(enum e_job jobid, int m, int group_lv);
|
||||||
|
|
||||||
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
|
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
|
||||||
int pc_level_penalty_mod(int level_diff, uint32 mob_class, enum e_mode mode, int type);
|
int pc_level_penalty_mod(int level_diff, uint32 mob_class, enum e_mode mode, int type);
|
||||||
#endif
|
#endif
|
||||||
|
@ -5633,7 +5633,7 @@ BUILDIN_FUNC(warpparty)
|
|||||||
TBL_PC *pl_sd;
|
TBL_PC *pl_sd;
|
||||||
struct party_data* p;
|
struct party_data* p;
|
||||||
int type;
|
int type;
|
||||||
int mapindex;
|
int mapindex = 0, m = -1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
const char* str = script_getstr(st,2);
|
const char* str = script_getstr(st,2);
|
||||||
@ -5662,18 +5662,21 @@ BUILDIN_FUNC(warpparty)
|
|||||||
return SCRIPT_CMD_FAILURE;
|
return SCRIPT_CMD_FAILURE;
|
||||||
pl_sd = p->data[i].sd;
|
pl_sd = p->data[i].sd;
|
||||||
mapindex = pl_sd->mapindex;
|
mapindex = pl_sd->mapindex;
|
||||||
|
m = map_mapindex2mapid(mapindex);
|
||||||
x = pl_sd->bl.x;
|
x = pl_sd->bl.x;
|
||||||
y = pl_sd->bl.y;
|
y = pl_sd->bl.y;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
mapindex = mapindex_name2id(str);
|
mapindex = mapindex_name2id(str);
|
||||||
|
if (!mapindex) {// Invalid map
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
m = map_mapindex2mapid(mapindex);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
//"SavePoint" uses save point of the currently attached player
|
//"SavePoint" uses save point of the currently attached player
|
||||||
if (( sd = script_rid2sd(st) ) == NULL )
|
if (( sd = script_rid2sd(st) ) == NULL )
|
||||||
return SCRIPT_CMD_SUCCESS;
|
return SCRIPT_CMD_SUCCESS;
|
||||||
default:
|
|
||||||
mapindex = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5704,7 +5707,7 @@ BUILDIN_FUNC(warpparty)
|
|||||||
break;
|
break;
|
||||||
case 3: // Leader
|
case 3: // Leader
|
||||||
case 4: // m,x,y
|
case 4: // m,x,y
|
||||||
if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp)
|
if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)pl_sd->status.class_, m, pl_sd->group_level))
|
||||||
pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
|
pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5723,7 +5726,7 @@ BUILDIN_FUNC(warpguild)
|
|||||||
TBL_PC *pl_sd;
|
TBL_PC *pl_sd;
|
||||||
struct guild* g;
|
struct guild* g;
|
||||||
struct s_mapiterator* iter;
|
struct s_mapiterator* iter;
|
||||||
int type;
|
int type, mapindex = 0, m = -1;
|
||||||
|
|
||||||
const char* str = script_getstr(st,2);
|
const char* str = script_getstr(st,2);
|
||||||
int x = script_getnum(st,3);
|
int x = script_getnum(st,3);
|
||||||
@ -5744,6 +5747,15 @@ BUILDIN_FUNC(warpguild)
|
|||||||
return SCRIPT_CMD_SUCCESS;
|
return SCRIPT_CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 3:
|
||||||
|
mapindex = mapindex_name2id(str);
|
||||||
|
if (!mapindex)
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
m = map_mapindex2mapid(mapindex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
iter = mapit_getallusers();
|
iter = mapit_getallusers();
|
||||||
for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
|
for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
|
||||||
{
|
{
|
||||||
@ -5765,8 +5777,8 @@ BUILDIN_FUNC(warpguild)
|
|||||||
pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
|
pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
|
||||||
break;
|
break;
|
||||||
case 3: // m,x,y
|
case 3: // m,x,y
|
||||||
if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp)
|
if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)pl_sd->status.class_, m, pl_sd->group_level))
|
||||||
pc_setpos(pl_sd,mapindex_name2id(str),x,y,CLR_TELEPORT);
|
pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21681,6 +21693,44 @@ BUILDIN_FUNC(needed_status_point) {
|
|||||||
script_pushint(st, pc_need_status_point(sd, type, val));
|
script_pushint(st, pc_need_status_point(sd, type, val));
|
||||||
return SCRIPT_CMD_SUCCESS;
|
return SCRIPT_CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jobcanentermap("<mapname>"{,<JobID>});
|
||||||
|
* Check if (player with) JobID can enter the map.
|
||||||
|
* @param mapname Map name
|
||||||
|
* @param JobID Player's JobID (optional)
|
||||||
|
**/
|
||||||
|
BUILDIN_FUNC(jobcanentermap) {
|
||||||
|
const char *mapname = script_getstr(st, 2);
|
||||||
|
int mapidx = mapindex_name2id(mapname), m = -1;
|
||||||
|
int jobid = 0;
|
||||||
|
TBL_PC *sd = NULL;
|
||||||
|
|
||||||
|
if (!mapidx) {// Invalid map
|
||||||
|
script_pushint(st, false);
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
m = map_mapindex2mapid(mapidx);
|
||||||
|
if (m == -1) { // Map is on different map server
|
||||||
|
ShowError("buildin_jobcanentermap: Map '%s' is not found in this server.\n", mapname);
|
||||||
|
script_pushint(st, false);
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (script_hasdata(st, 3)) {
|
||||||
|
jobid = script_getnum(st, 3);
|
||||||
|
} else {
|
||||||
|
if (!(sd = script_rid2sd(st))) {
|
||||||
|
script_pushint(st, false);
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
jobid = sd->status.class_;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_pushint(st, pc_job_can_entermap((enum e_job)jobid, m, sd ? sd->group_level : 0));
|
||||||
|
return SCRIPT_CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#include "../custom/script.inc"
|
#include "../custom/script.inc"
|
||||||
|
|
||||||
// declarations that were supposed to be exported from npc_chat.c
|
// declarations that were supposed to be exported from npc_chat.c
|
||||||
@ -22264,6 +22314,7 @@ struct script_function buildin_func[] = {
|
|||||||
BUILDIN_DEF(getequiprandomoption, "iii?"),
|
BUILDIN_DEF(getequiprandomoption, "iii?"),
|
||||||
BUILDIN_DEF(setrandomoption,"iiiii?"),
|
BUILDIN_DEF(setrandomoption,"iiiii?"),
|
||||||
BUILDIN_DEF(needed_status_point,"ii?"),
|
BUILDIN_DEF(needed_status_point,"ii?"),
|
||||||
|
BUILDIN_DEF(jobcanentermap,"s?"),
|
||||||
|
|
||||||
#include "../custom/script_def.inc"
|
#include "../custom/script_def.inc"
|
||||||
|
|
||||||
|
@ -8603,6 +8603,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|||||||
if ((dstsd = g->member[i].sd) != NULL && sd != dstsd && !dstsd->state.autotrade && !pc_isdead(dstsd)) {
|
if ((dstsd = g->member[i].sd) != NULL && sd != dstsd && !dstsd->state.autotrade && !pc_isdead(dstsd)) {
|
||||||
if (map[dstsd->bl.m].flag.nowarp && !map_flag_gvg2(dstsd->bl.m))
|
if (map[dstsd->bl.m].flag.nowarp && !map_flag_gvg2(dstsd->bl.m))
|
||||||
continue;
|
continue;
|
||||||
|
if (!pc_job_can_entermap((enum e_job)dstsd->status.class_, src->m, dstsd->group_level))
|
||||||
|
continue;
|
||||||
if(map_getcell(src->m,src->x+dx[j],src->y+dy[j],CELL_CHKNOREACH))
|
if(map_getcell(src->m,src->x+dx[j],src->y+dy[j],CELL_CHKNOREACH))
|
||||||
dx[j] = dy[j] = 0;
|
dx[j] = dy[j] = 0;
|
||||||
if (!pc_setpos(dstsd, map_id2index(src->m), src->x+dx[j], src->y+dy[j], CLR_RESPAWN))
|
if (!pc_setpos(dstsd, map_id2index(src->m), src->x+dx[j], src->y+dy[j], CLR_RESPAWN))
|
||||||
@ -13141,6 +13143,7 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, un
|
|||||||
|
|
||||||
sg->val1 = (count<<16)|working;
|
sg->val1 = (count<<16)|working;
|
||||||
|
|
||||||
|
if (pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(m), sd->group_level))
|
||||||
pc_setpos(sd,m,x,y,CLR_TELEPORT);
|
pc_setpos(sd,m,x,y,CLR_TELEPORT);
|
||||||
}
|
}
|
||||||
} else if(bl->type == BL_MOB && battle_config.mob_warp&2) {
|
} else if(bl->type == BL_MOB && battle_config.mob_warp&2) {
|
||||||
@ -18122,13 +18125,13 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap)
|
|||||||
if(group->val1) {
|
if(group->val1) {
|
||||||
sd = map_charid2sd(group->val1);
|
sd = map_charid2sd(group->val1);
|
||||||
group->val1 = 0;
|
group->val1 = 0;
|
||||||
if (sd && !map[sd->bl.m].flag.nowarp)
|
if (sd && !map[sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)sd->status.class_, unit->bl.m, sd->group_level))
|
||||||
pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
|
pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
|
||||||
}
|
}
|
||||||
if(group->val2) {
|
if(group->val2) {
|
||||||
sd = map_charid2sd(group->val2);
|
sd = map_charid2sd(group->val2);
|
||||||
group->val2 = 0;
|
group->val2 = 0;
|
||||||
if (sd && !map[sd->bl.m].flag.nowarp)
|
if (sd && !map[sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)sd->status.class_, unit->bl.m, sd->group_level))
|
||||||
pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
|
pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
|
||||||
}
|
}
|
||||||
skill_delunit(unit);
|
skill_delunit(unit);
|
||||||
|
@ -325,6 +325,7 @@
|
|||||||
<Copy SourceFiles="..\db\import-tmpl\job_db2.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_db2.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_db2.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_db2.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\job_exp.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_exp.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_exp.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_exp.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\job_param_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_param_db.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_param_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_param_db.txt')" />
|
||||||
|
<Copy SourceFiles="..\db\import-tmpl\job_noenter_map.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_noenter_map.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\level_penalty.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\level_penalty.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\level_penalty.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\level_penalty.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\magicmushroom_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\magicmushroom_db.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\magicmushroom_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\magicmushroom_db.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\map_cache.dat" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\map_cache.dat')" />
|
<Copy SourceFiles="..\db\import-tmpl\map_cache.dat" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\map_cache.dat')" />
|
||||||
|
@ -329,6 +329,7 @@
|
|||||||
<Copy SourceFiles="..\db\import-tmpl\job_db2.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_db2.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_db2.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_db2.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\job_exp.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_exp.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_exp.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_exp.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\job_param_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_param_db.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_param_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_param_db.txt')" />
|
||||||
|
<Copy SourceFiles="..\db\import-tmpl\job_noenter_map.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_noenter_map.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\level_penalty.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\level_penalty.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\level_penalty.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\level_penalty.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\magicmushroom_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\magicmushroom_db.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\magicmushroom_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\magicmushroom_db.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\map_cache.dat" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\map_cache.dat')" />
|
<Copy SourceFiles="..\db\import-tmpl\map_cache.dat" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\map_cache.dat')" />
|
||||||
|
@ -329,6 +329,7 @@
|
|||||||
<Copy SourceFiles="..\db\import-tmpl\job_db2.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_db2.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_db2.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_db2.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\job_exp.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_exp.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_exp.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_exp.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\job_param_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_param_db.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_param_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_param_db.txt')" />
|
||||||
|
<Copy SourceFiles="..\db\import-tmpl\job_noenter_map.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_noenter_map.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\level_penalty.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\level_penalty.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\level_penalty.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\level_penalty.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\magicmushroom_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\magicmushroom_db.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\magicmushroom_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\magicmushroom_db.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\map_cache.dat" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\map_cache.dat')" />
|
<Copy SourceFiles="..\db\import-tmpl\map_cache.dat" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\map_cache.dat')" />
|
||||||
|
@ -327,6 +327,7 @@
|
|||||||
<Copy SourceFiles="..\db\import-tmpl\job_db2.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_db2.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_db2.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_db2.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\job_exp.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_exp.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_exp.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_exp.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\job_param_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_param_db.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\job_param_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_param_db.txt')" />
|
||||||
|
<Copy SourceFiles="..\db\import-tmpl\job_noenter_map.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\job_noenter_map.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\level_penalty.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\level_penalty.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\level_penalty.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\level_penalty.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\magicmushroom_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\magicmushroom_db.txt')" />
|
<Copy SourceFiles="..\db\import-tmpl\magicmushroom_db.txt" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\magicmushroom_db.txt')" />
|
||||||
<Copy SourceFiles="..\db\import-tmpl\map_cache.dat" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\map_cache.dat')" />
|
<Copy SourceFiles="..\db\import-tmpl\map_cache.dat" DestinationFolder="..\db\import\" ContinueOnError="true" Condition="!Exists('..\db\import\map_cache.dat')" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user