Browse Source

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
Cydh Ramdh 8 years ago
parent
commit
d84d6ba1e5

+ 27 - 0
db/import-tmpl/job_noenter_map.txt

@@ -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 - 0
db/pre-re/job_noenter_map.txt

@@ -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 - 0
db/re/job_noenter_map.txt

@@ -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.

+ 11 - 0
doc/script_commands.txt

@@ -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

+ 1 - 1
src/common/mmo.h

@@ -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;

+ 1 - 1
src/map/atcommand.c

@@ -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;
 	}
 	}

+ 61 - 1
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

+ 6 - 0
src/map/pc.h

@@ -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

+ 58 - 7
src/map/script.c

@@ -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)
-				pc_setpos(pl_sd,mapindex_name2id(str),x,y,CLR_TELEPORT);
+			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);
 		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"
 
 

+ 6 - 3
src/map/skill.c

@@ -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,7 +13143,8 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, un
 
 
 					sg->val1 = (count<<16)|working;
 					sg->val1 = (count<<16)|working;
 
 
-					pc_setpos(sd,m,x,y,CLR_TELEPORT);
+					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);
 				}
 				}
 			} else if(bl->type == BL_MOB && battle_config.mob_warp&2) {
 			} else if(bl->type == BL_MOB && battle_config.mob_warp&2) {
 				int16 m = map_mapindex2mapid(sg->val3);
 				int16 m = map_mapindex2mapid(sg->val3);
@@ -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);

+ 1 - 0
vcproj-10/map-server.vcxproj

@@ -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')" />

+ 1 - 0
vcproj-12/map-server.vcxproj

@@ -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')" />

+ 1 - 0
vcproj-13/map-server.vcxproj

@@ -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')" />

+ 1 - 0
vcproj-14/map-server.vcxproj

@@ -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')" />