Added Zone Flags, Zone Levels Restrictions, and zlock, zunlock and areas commands

This commit is contained in:
JamDog 2009-03-13 21:49:38 +00:00
parent 44f59ceff2
commit 40d89ca26b
20 changed files with 1037 additions and 389 deletions

View file

@ -37,6 +37,11 @@ Xlist (mlist, olist, rlist, zlist, slist, tlist, qlist)
tbaMUD 3.59
[Mar 13 2009] - Jamdog
Bug-Fix: Character deletion (remove_player, players.c), where the wrong player was potentially being deleted.
Added Zone Flags, including zedit sub-menu
Added Zone level restrictions, including zedit sub-menu
Added zlock and zunlock commands
Added areas command
Set GRID flag on zones 0, 12 and 30
[Mar 08 2009] - Jamdog
Fixed a possible crash bug in delete_object (genobj.c) (Thanks Slicer)
CAP function now recognises both preceeding color codes and ANSI codes (Thanks Slicer)

View file

@ -1,14 +1,14 @@
#0
Rumble~
The Builder Academy Zone~
0 99 10 2
0 99 10 2 d 0 0 0 -1 -1
M 0 1 1 1 (Puff)
D 0 89 4 2 (The Prison Cell Corridor)
M 0 31 1 89 (the Commissar)
G 1 68 99 -1 (the Commissar's key)
M 0 18 1 2 (Friedrich Nietzsche)
R 0 88 1228 -1 (a advertising bulletin board)
O 0 1228 99 88 (a advertising bulletin board)
M 0 1 1 1 (Puff)
R 0 90 86 -1 (a pair of shackles)
R 0 90 84 -1 (the shower drain)
O 0 84 1 90 (the shower drain)

View file

@ -1,7 +1,7 @@
#30
DikuMUD~
Northern Midgaard~
3000 3099 15 2
3000 3099 15 2 d 0 0 0 -1 -1
R 0 3000 3099 -1 (a bulletin board)
O 0 3099 99 3000 (a bulletin board)
M 0 3045 1 3022 (the waiter)

View file

@ -1,7 +1,7 @@
#31
DikuMUD~
Southern Midgaard~
3100 3199 30 2
3100 3199 30 2 d 0 0 0 -1 -1
M 0 3060 20 3111 (the cityguard)
E 1 3022 100 16 (a long sword)
G 1 3105 2 -1 (an iron key)

View file

@ -82,6 +82,7 @@ ACMD(do_look);
#define SCMD_LOOK 0
#define SCMD_READ 1
/* functions without subcommands */
ACMD(do_areas);
ACMD(do_consider);
ACMD(do_diagnose);
ACMD(do_equipment);
@ -339,7 +340,9 @@ ACMD(do_wizlock);
ACMD(do_wiznet);
ACMD(do_wizupdate);
ACMD(do_zcheck);
ACMD(do_zlock);
ACMD(do_zpurge);
ACMD(do_zreset);
ACMD(do_zunlock);
#endif /* _ACT_H_ */

View file

@ -2400,3 +2400,110 @@ ACMD(do_whois)
if (got_from_file)
free_char (victim);
}
bool get_zone_levels(zone_rnum znum, char *buf)
{
/* Create a string for the level restrictions for this zone. */
if ((zone_table[znum].min_level == -1) && (zone_table[znum].max_level == -1)) {
sprintf(buf, "<Not Set!>");
return FALSE;
}
if (zone_table[znum].min_level == -1) {
sprintf(buf, "Up to level %d", zone_table[znum].max_level);
return TRUE;
}
if (zone_table[znum].max_level == -1) {
sprintf(buf, "Above level %d", zone_table[znum].min_level);
return TRUE;
}
sprintf(buf, "Levels %d to %d", zone_table[znum].min_level, zone_table[znum].max_level);
return TRUE;
}
ACMD(do_areas)
{
int i, hilev=-1, lolev=-1, zcount=0, lev_set;
char arg[MAX_INPUT_LENGTH], *second, lev_str[MAX_INPUT_LENGTH];
bool show_zone = FALSE, overlap = FALSE, overlap_shown = FALSE;
one_argument(argument, arg);
if (*arg) {
/* There was an arg typed - check for level range */
second = strchr(arg, '-');
if (second) {
/* Check for 1st value */
if (second == arg)
lolev = 0;
else
lolev = atoi(arg);
/* Check for 2nd value */
if (*(second+1) == '\0' || !isdigit(*(second+1)) )
hilev = 100;
else
hilev = atoi(second+1);
} else {
/* No range - single number */
lolev = atoi(arg);
hilev = -1; /* No high level - indicates single level */
}
}
if (hilev != -1 && lolev > hilev) {
/* Swap hi and lo lev if needed */
i = lolev;
lolev = hilev;
hilev = i;
}
if (hilev != -1)
send_to_char(ch, "Checking range: %s%d to %d%s\r\n", QYEL, lolev, hilev, QNRM);
else if (lolev != -1)
send_to_char(ch, "Checking level: %s%d%s\r\n", QYEL, lolev, QNRM);
else
send_to_char(ch, "Checking all areas.\r\n");
for (i = 0; i <= top_of_zone_table; i++) { /* Go through the whole zone table */
show_zone = FALSE;
overlap = FALSE;
if (ZONE_FLAGGED(i, ZONE_GRID)) { /* Is this zone 'on the grid' ? */
if (lolev == -1) {
/* No range supplied, show all zones */
show_zone = TRUE;
} else if ((hilev == -1) && (lolev >= ZONE_MINLVL(i)) && (lolev <= ZONE_MAXLVL(i))) {
/* Single number supplied, it's in this zone's range */
show_zone = TRUE;
} else if ((hilev != -1) && (lolev >= ZONE_MINLVL(i)) && (hilev <= ZONE_MAXLVL(i))) {
/* Range supplied, it's completely within this zone's range (no overlap) */
show_zone = TRUE;
} else if ((hilev != -1) && ((lolev >= ZONE_MINLVL(i) && lolev <= ZONE_MAXLVL(i)) || (hilev <= ZONE_MAXLVL(i) && hilev >= ZONE_MINLVL(i)))) {
/* Range supplied, it overlaps this zone's range */
show_zone = TRUE;
overlap = TRUE;
} else if (ZONE_MAXLVL(i) < 0 && (lolev >= ZONE_MINLVL(i))) {
/* Max level not set for this zone, but specified min in range */
show_zone = TRUE;
} else if (ZONE_MAXLVL(i) < 0 && (hilev >= ZONE_MINLVL(i))) {
/* Max level not set for this zone, so just display it as red */
show_zone = TRUE;
overlap = TRUE;
}
}
if (show_zone) {
if (overlap) overlap_shown = TRUE;
lev_set = get_zone_levels(i, lev_str);
send_to_char(ch, "@n(%3d) %s%-*s@n %s%s@n\r\n", ++zcount, overlap ? QRED : QCYN,
count_color_chars(zone_table[i].name)+30, zone_table[i].name,
lev_set ? "@c" : "@n", lev_set ? lev_str : "All Levels");
}
}
send_to_char(ch, "%s%d%s area%s found.\r\n", QYEL, zcount, QNRM, zcount == 1 ? "" : "s");
if (overlap_shown)
send_to_char(ch, "Areas shown in @rred@n may have some creatures outside the specified range.\r\n");
}

View file

@ -213,6 +213,26 @@ int do_simple_move(struct char_data *ch, int dir, int need_specials_check)
}
}
/* Check zone level restrictions */
if ((ZONE_MINLVL(GET_ROOM_ZONE(going_to)) != -1) && ZONE_MINLVL(GET_ROOM_ZONE(going_to)) > GET_LEVEL(ch)) {
send_to_char(ch, "You are not ready to enter that area.\r\n");
return (0);
}
if ((ZONE_MAXLVL(GET_ROOM_ZONE(going_to)) != -1) && ZONE_MAXLVL(GET_ROOM_ZONE(going_to)) < GET_LEVEL(ch)) {
send_to_char(ch, "You are too powerful for that area.\r\n");
return (0);
}
/* Check zone flag restrictions */
if (ZONE_FLAGGED(GET_ROOM_ZONE(going_to), ZONE_CLOSED)) {
send_to_char(ch, "A mysterious barrier forces you back! That area is off-limits.\r\n");
return (0);
}
if (ZONE_FLAGGED(GET_ROOM_ZONE(going_to), ZONE_NOIMMORT) && (GET_LEVEL(ch) >= LVL_IMMORT) && (GET_LEVEL(ch) < LVL_GRGOD)) {
send_to_char(ch, "A mysterious barrier forces you back! That area is off-limits.\r\n");
return (0);
}
/* Room Size Capacity: Is the room full of people already? */
if (ROOM_FLAGGED(going_to, ROOM_TUNNEL) &&
num_pc_in_room(&(world[going_to])) >= CONFIG_TUNNEL_SIZE)

View file

@ -236,6 +236,11 @@ ACMD(do_goto)
if ((location = find_target_room(ch, argument)) == NOWHERE)
return;
if (ZONE_FLAGGED(GET_ROOM_ZONE(location), ZONE_NOIMMORT) && (GET_LEVEL(ch) >= LVL_IMMORT) && (GET_LEVEL(ch) < LVL_GRGOD)) {
send_to_char(ch, "Sorry, that zone is off-limits for immortals!");
return;
}
snprintf(buf, sizeof(buf), "$n %s", POOFOUT(ch) ? POOFOUT(ch) : "disappears in a puff of smoke.");
act(buf, TRUE, ch, 0, 0, TO_ROOM);
@ -4533,3 +4538,206 @@ bool change_player_name(struct char_data *ch, struct char_data *vict, char *new_
return TRUE;
}
ACMD(do_zlock)
{
zone_vnum znvnum;
zone_rnum zn;
char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
int counter = 0;
bool fail = FALSE;
two_arguments(argument, arg, arg2);
if (!*arg) {
send_to_char(ch, "Usage: %szlock <zone number>%s\r\n", QYEL, QNRM);
send_to_char(ch, "%s zlock list%s\r\n\r\n", QYEL, QNRM);
send_to_char(ch, "Locks a zone so that building or editing is not possible.\r\n");
send_to_char(ch, "The 'list' shows all currently locked zones.\r\n");
send_to_char(ch, "'zlock all' will lock every zone with the GRID flag set.\r\n");
send_to_char(ch, "'zlock all all' will lock every zone in the MUD.\r\n");
return;
}
if (is_abbrev(arg, "all")) {
if (GET_LEVEL(ch) < LVL_GRGOD) {
send_to_char(ch, "You do not have sufficient access to lock all zones.\r\n");
return;
}
if (!*arg2) {
for (zn = 0; zn <= top_of_zone_table; zn++) {
if (!ZONE_FLAGGED(zn, ZONE_NOBUILD) && ZONE_FLAGGED(zn, ZONE_GRID)) {
counter++;
SET_BIT_AR(ZONE_FLAGS(zn), ZONE_NOBUILD);
if (save_zone(zn)) {
log("(GC) %s has locked zone %d", GET_NAME(ch), zone_table[zn].number);
} else {
fail = TRUE;
}
}
}
} else if (is_abbrev(arg2, "all")) {
for (zn = 0; zn <= top_of_zone_table; zn++) {
if (!ZONE_FLAGGED(zn, ZONE_NOBUILD)) {
counter++;
SET_BIT_AR(ZONE_FLAGS(zn), ZONE_NOBUILD);
if (save_zone(zn)) {
log("(GC) %s has locked zone %d", GET_NAME(ch), zone_table[zn].number);
} else {
fail = TRUE;
}
}
}
}
if (counter == 0) {
send_to_char(ch, "There are no unlocked zones to lock!\r\n");
return;
}
if (fail) {
send_to_char(ch, "Unable to save zone changes. Check syslog!\r\n");
return;
}
send_to_char(ch, "%d zones have now been locked.\r\n", counter);
mudlog(BRF, LVL_GOD, TRUE, "(GC) %s has locked ALL zones!", GET_NAME(ch));
return;
}
if (is_abbrev(arg, "list")) {
/* Show all locked zones */
for (zn = 0; zn <= top_of_zone_table; zn++) {
if (ZONE_FLAGGED(zn, ZONE_NOBUILD)) {
if (!counter) send_to_char(ch, "Locked Zones\r\n");
send_to_char(ch, "[%s%3d%s] %s%-*s %s%-1s%s\r\n",
QGRN, zone_table[zn].number, QNRM, QCYN, count_color_chars(zone_table[zn].name)+30, zone_table[zn].name,
QYEL, zone_table[zn].builders ? zone_table[zn].builders : "None.", QNRM);
counter++;
}
}
if (counter == 0) {
send_to_char(ch, "There are currently no locked zones!\r\n");
}
return;
}
else if ((znvnum = atoi(arg)) == 0) {
send_to_char(ch, "Usage: %szlock <zone number>%s\r\n", QYEL, QNRM);
return;
}
if ((zn = real_zone(znvnum)) == NOWHERE) {
send_to_char(ch, "That zone does not exist!\r\n");
return;
}
/* Check the builder list */
if (GET_LEVEL(ch) < LVL_GRGOD && !is_name(GET_NAME(ch), zone_table[zn].builders) && GET_OLC_ZONE(ch) != znvnum) {
send_to_char(ch, "You do not have sufficient access to lock that zone!\r\n");
return;
}
/* If we get here, player has typed 'zlock <num>' */
if (ZONE_FLAGGED(zn, ZONE_NOBUILD)) {
send_to_char(ch, "Zone %d is already locked!\r\n", znvnum);
return;
}
SET_BIT_AR(ZONE_FLAGS(zn), ZONE_NOBUILD);
if (save_zone(zn)) {
mudlog(NRM, LVL_GRGOD, TRUE, "(GC) %s has locked zone %d", GET_NAME(ch), znvnum);
}
else
{
send_to_char(ch, "Unable to save zone changes. Check syslog!\r\n");
}
}
ACMD(do_zunlock)
{
zone_vnum znvnum;
zone_rnum zn;
char arg[MAX_INPUT_LENGTH];
int counter = 0;
bool fail = FALSE;
one_argument(argument, arg);
if (!*arg) {
send_to_char(ch, "Usage: %szunlock <zone number>%s\r\n", QYEL, QNRM);
send_to_char(ch, "%s zunlock list%s\r\n\r\n", QYEL, QNRM);
send_to_char(ch, "Unlocks a 'locked' zone to allow building or editing.\r\n");
send_to_char(ch, "The 'list' shows all currently unlocked zones.\r\n");
send_to_char(ch, "'zunlock all' will unlock every zone in the MUD.\r\n");
return;
}
if (is_abbrev(arg, "all")) {
if (GET_LEVEL(ch) < LVL_GRGOD) {
send_to_char(ch, "You do not have sufficient access to lock zones.\r\n");
return;
}
for (zn = 0; zn <= top_of_zone_table; zn++) {
if (ZONE_FLAGGED(zn, ZONE_NOBUILD)) {
counter++;
REMOVE_BIT_AR(ZONE_FLAGS(zn), ZONE_NOBUILD);
if (save_zone(zn)) {
log("(GC) %s has unlocked zone %d", GET_NAME(ch), zone_table[zn].number);
} else {
fail = TRUE;
}
}
}
if (counter == 0) {
send_to_char(ch, "There are no locked zones to unlock!\r\n");
return;
}
if (fail) {
send_to_char(ch, "Unable to save zone changes. Check syslog!\r\n");
return;
}
send_to_char(ch, "%d zones have now been unlocked.\r\n", counter);
mudlog(BRF, LVL_GOD, TRUE, "(GC) %s has unlocked ALL zones!", GET_NAME(ch));
return;
}
if (is_abbrev(arg, "list")) {
/* Show all unlocked zones */
for (zn = 0; zn <= top_of_zone_table; zn++) {
if (!ZONE_FLAGGED(zn, ZONE_NOBUILD)) {
if (!counter) send_to_char(ch, "Unlocked Zones\r\n");
send_to_char(ch, "[%s%3d%s] %s%-*s %s%-1s%s\r\n",
QGRN, zone_table[zn].number, QNRM, QCYN, count_color_chars(zone_table[zn].name)+30, zone_table[zn].name,
QYEL, zone_table[zn].builders ? zone_table[zn].builders : "None.", QNRM);
counter++;
}
}
if (counter == 0) {
send_to_char(ch, "There are currently no unlocked zones!\r\n");
}
return;
}
else if ((znvnum = atoi(arg)) == 0) {
send_to_char(ch, "Usage: %szunlock <zone number>%s\r\n", QYEL, QNRM);
return;
}
if ((zn = real_zone(znvnum)) == NOWHERE) {
send_to_char(ch, "That zone does not exist!\r\n");
return;
}
/* Check the builder list */
if (GET_LEVEL(ch) < LVL_GRGOD && !is_name(GET_NAME(ch), zone_table[zn].builders) && GET_OLC_ZONE(ch) != znvnum) {
send_to_char(ch, "You do not have sufficient access to unlock that zone!\r\n");
return;
}
/* If we get here, player has typed 'zunlock <num>' */
if (!ZONE_FLAGGED(zn, ZONE_NOBUILD)) {
send_to_char(ch, "Zone %d is already unlocked!\r\n", znvnum);
return;
}
REMOVE_BIT_AR(ZONE_FLAGS(zn), ZONE_NOBUILD);
if (save_zone(zn)) {
mudlog(NRM, LVL_GRGOD, TRUE, "(GC) %s has unlocked zone %d", GET_NAME(ch), znvnum);
}
else
{
send_to_char(ch, "Unable to save zone changes. Check syslog!\r\n");
}
}

View file

@ -67,6 +67,19 @@ const char *room_bits[] = {
"\n"
};
/** Room flag descriptions. (ZONE_x)
* @pre Must be in the same order as the defines in structs.h.
* Must end array with a single newline. */
const char *zone_bits[] = {
"CLOSED",
"NO_IMMORT",
"QUEST",
"GRID",
"NOBUILD",
"!ASTRAL",
"\n"
};
/** Exit bits for doors.
* @pre Must be in the same order as the defines.
* Must end array with a single newline. */

View file

@ -15,6 +15,7 @@
extern const char *tbamud_version;
extern const char *dirs[];
extern const char *room_bits[];
extern const char *zone_bits[];
extern const char *exit_bits[];
extern const char *sector_types[];
extern const char *genders[];

View file

@ -1980,10 +1980,12 @@ char *parse_object(FILE *obj_f, int nr)
static void load_zones(FILE *fl, char *zonename)
{
static zone_rnum zone = 0;
int cmd_no, num_of_cmds = 0, line_num = 0, tmp, error;
int i, cmd_no, num_of_cmds = 0, line_num = 0, tmp, error;
char *ptr, buf[READ_SIZE], zname[READ_SIZE], buf2[MAX_STRING_LENGTH];
int zone_fix = FALSE;
char t1[80], t2[80];
char zbuf1[MAX_STRING_LENGTH], zbuf2[MAX_STRING_LENGTH];
char zbuf3[MAX_STRING_LENGTH], zbuf4[MAX_STRING_LENGTH];
strlcpy(zname, zonename, sizeof(zname));
@ -2024,7 +2026,15 @@ static void load_zones(FILE *fl, char *zonename)
*ptr = '\0';
Z.name = strdup(buf);
/* Clear all the zone flags */
for (i=0; i<ZN_ARRAY_MAX; i++)
Z.zone_flags[i] = 0;
line_num += get_line(fl, buf);
/* Look for 10 items first (new tbaMUD), if not found, try 4 (old tbaMUD) */
if (sscanf(buf, " %hd %hd %d %d %s %s %s %s %d %d", &Z.bot, &Z.top, &Z.lifespan,
&Z.reset_mode, zbuf1, zbuf2, zbuf3, zbuf4, &Z.min_level, &Z.max_level) != 10)
{
if (sscanf(buf, " %hd %hd %d %d ", &Z.bot, &Z.top, &Z.lifespan, &Z.reset_mode) != 4) {
/* This may be due to the fact that the zone has no builder. So, we just
* attempt to fix this by copying the previous 2 last reads into this
@ -2041,6 +2051,18 @@ static void load_zones(FILE *fl, char *zonename)
zone_fix = TRUE;
}
}
/* We only found 4 values, so set 'defaults' for the ones not found */
Z.min_level = -1;
Z.max_level = -1;
}
else
{
/* We found 12 values, so deal with the strings */
Z.zone_flags[0] = asciiflag_conv(zbuf1);
Z.zone_flags[1] = asciiflag_conv(zbuf2);
Z.zone_flags[2] = asciiflag_conv(zbuf3);
Z.zone_flags[3] = asciiflag_conv(zbuf4);
}
if (Z.bot > Z.top) {
log("SYSERR: Zone %d bottom (%d) > top (%d).", Z.number, Z.bot, Z.top);
exit(1);

View file

@ -181,6 +181,10 @@ struct zone_data {
room_vnum bot; /* starting room number for this zone */
room_vnum top; /* upper limit for rooms in this zone */
int zone_flags[ZN_ARRAY_MAX]; /* Zone Flags bitvector */
int min_level; /* Minimum level a player must be to enter this zone */
int max_level; /* Maximum level a player must be to enter this zone */
int reset_mode; /* conditions for reset (see below) */
zone_vnum number; /* virtual number of this zone */
struct reset_com *cmd; /* command table for reset */

View file

@ -194,6 +194,11 @@ rznum = i;
zone->lifespan = 30;
zone->age = 0;
zone->reset_mode = 2;
zone->min_level = -1;
zone->max_level = -1;
for (i=0; i<ZN_ARRAY_MAX; i++) zone->zone_flags[i] = 0;
/* No zone commands, just terminate it with an 'S' */
CREATE(zone->cmd, struct reset_com, 1);
zone->cmd[0].command = 'S';
@ -315,10 +320,12 @@ void remove_room_zone_commands(zone_rnum zone, room_rnum room_num)
* field is also there. */
int save_zone(zone_rnum zone_num)
{
int subcmd, arg1 = -1, arg2 = -1, arg3 = -1;
int subcmd, arg1 = -1, arg2 = -1, arg3 = -1, flag_tot=0, i;
char fname[128], oldname[128];
const char *comment = NULL;
FILE *zfile;
char zbuf1[MAX_STRING_LENGTH], zbuf2[MAX_STRING_LENGTH];
char zbuf3[MAX_STRING_LENGTH], zbuf4[MAX_STRING_LENGTH];
#if CIRCLE_UNSIGNED_INDEX
if (zone_num == NOWHERE || zone_num > top_of_zone_table) {
@ -335,6 +342,12 @@ int save_zone(zone_rnum zone_num)
return FALSE;
}
for (i=0; i<ZN_ARRAY_MAX; i++)
flag_tot += zone_table[zone_num].zone_flags[(i)];
/* If zone flags or levels aren't set, there is no reason to save them! */
if (flag_tot == 0 && zone_table[zone_num].min_level == -1 && zone_table[zone_num].max_level == -1)
{
/* Print zone header to file. */
fprintf(zfile, "#%d\n"
"%s~\n"
@ -350,6 +363,31 @@ int save_zone(zone_rnum zone_num)
zone_table[zone_num].lifespan,
zone_table[zone_num].reset_mode
);
} else {
sprintascii(zbuf1, zone_table[zone_num].zone_flags[0]);
sprintascii(zbuf2, zone_table[zone_num].zone_flags[1]);
sprintascii(zbuf3, zone_table[zone_num].zone_flags[2]);
sprintascii(zbuf4, zone_table[zone_num].zone_flags[3]);
/* Print zone header to file. */
fprintf(zfile, "#%d\n"
"%s~\n"
"%s~\n"
"%d %d %d %d %s %s %s %s %d %d\n", /* New tbaMUD data line */
zone_table[zone_num].number,
(zone_table[zone_num].builders && *zone_table[zone_num].builders)
? zone_table[zone_num].builders : "None.",
(zone_table[zone_num].name && *zone_table[zone_num].name)
? zone_table[zone_num].name : "undefined",
genolc_zone_bottom(zone_num),
zone_table[zone_num].top,
zone_table[zone_num].lifespan,
zone_table[zone_num].reset_mode,
zbuf1, zbuf2, zbuf3, zbuf4,
zone_table[zone_num].min_level,
zone_table[zone_num].max_level
);
}
/* Handy Quick Reference Chart for Zone Values.
*

View file

@ -75,6 +75,7 @@ cpp_extern const struct command_info cmd_info[] = {
{ "aedit" , "aed" , POS_DEAD , do_oasis_aedit, LVL_GOD, 0 },
{ "alias" , "ali" , POS_DEAD , do_alias , 0, 0 },
{ "afk" , "afk" , POS_DEAD , do_gen_tog , 0, SCMD_AFK },
{ "areas" , "are" , POS_DEAD , do_areas , 0, 0 },
{ "assist" , "as" , POS_FIGHTING, do_assist , 1, 0 },
{ "ask" , "ask" , POS_RESTING , do_spec_comm, 0, SCMD_ASK },
{ "astat" , "ast" , POS_DEAD , do_astat , 0, 0 },
@ -330,6 +331,8 @@ cpp_extern const struct command_info cmd_info[] = {
{ "zreset" , "zreset" , POS_DEAD , do_zreset , LVL_BUILDER, 0 },
{ "zedit" , "zedit" , POS_DEAD , do_oasis_zedit, LVL_BUILDER, 0 },
{ "zlist" , "zlist" , POS_DEAD , do_oasis_list, LVL_BUILDER, SCMD_OASIS_ZLIST },
{ "zlock" , "zlock" , POS_DEAD , do_zlock , LVL_BUILDER, 0 },
{ "zunlock" , "zunlock" , POS_DEAD , do_zunlock , LVL_BUILDER, 0 },
{ "zcheck" , "zcheck" , POS_DEAD , do_zcheck , LVL_GOD, 0 },
{ "zpurge" , "zpurge" , POS_DEAD , do_zpurge , LVL_BUILDER, 0 },

View file

@ -252,6 +252,10 @@ int can_edit_zone(struct char_data *ch, zone_rnum rnum)
if (!ch->desc || IS_NPC(ch) || rnum == NOWHERE)
return FALSE;
/* If zone is flagged NOBUILD, then No-one can edit it (use zunlock to open it) */
if (rnum != HEDIT_PERMISSION && rnum != AEDIT_PERMISSION && ZONE_FLAGGED(rnum, ZONE_NOBUILD) )
return FALSE;
if (GET_OLC_ZONE(ch) == ALL_PERMISSION)
return TRUE;

View file

@ -228,6 +228,11 @@ extern const char *nrm, *grn, *cyn, *yel;
#define ZEDIT_ZONE_BUILDERS 15
#define ZEDIT_SARG1 20
#define ZEDIT_SARG2 21
#define ZEDIT_ZONE_FLAGS 22
#define ZEDIT_LEVELS 23
#define ZEDIT_LEV_MIN 24
#define ZEDIT_LEV_MAX 25
#define ZEDIT_ZONE_CLAIM 26
/* Submodes of MEDIT connectedness. */
#define MEDIT_MAIN_MENU 0

View file

@ -59,6 +59,11 @@ ASPELL(spell_recall)
if (victim == NULL || IS_NPC(victim))
return;
if (ZONE_FLAGGED(GET_ROOM_ZONE(IN_ROOM(victim)), ZONE_NOASTRAL)) {
send_to_char(ch, "A bright flash prevents your spell from working!");
return;
}
act("$n disappears.", TRUE, victim, 0, 0, TO_ROOM);
char_from_room(victim);
char_to_room(victim, r_mortal_start_room);
@ -76,9 +81,16 @@ ASPELL(spell_teleport)
if (victim == NULL || IS_NPC(victim))
return;
if (ZONE_FLAGGED(GET_ROOM_ZONE(IN_ROOM(victim)), ZONE_NOASTRAL)) {
send_to_char(ch, "A bright flash prevents your spell from working!");
return;
}
do {
to_room = rand_number(0, top_of_world);
} while (ROOM_FLAGGED(to_room, ROOM_PRIVATE) || ROOM_FLAGGED(to_room, ROOM_DEATH) || ROOM_FLAGGED(to_room, ROOM_GODROOM));
} while (ROOM_FLAGGED(to_room, ROOM_PRIVATE) || ROOM_FLAGGED(to_room, ROOM_DEATH) ||
ROOM_FLAGGED(to_room, ROOM_GODROOM) || ZONE_FLAGGED(GET_ROOM_ZONE(to_room), ZONE_CLOSED) ||
ZONE_FLAGGED(GET_ROOM_ZONE(to_room), ZONE_NOASTRAL));
act("$n slowly fades out of existence and is gone.",
FALSE, victim, 0, 0, TO_ROOM);
@ -102,6 +114,12 @@ ASPELL(spell_summon)
return;
}
if (ZONE_FLAGGED(GET_ROOM_ZONE(IN_ROOM(victim)), ZONE_NOASTRAL) ||
ZONE_FLAGGED(GET_ROOM_ZONE(IN_ROOM(ch)), ZONE_NOASTRAL)) {
send_to_char(ch, "A bright flash prevents your spell from working!");
return;
}
if (!CONFIG_PK_ALLOWED) {
if (MOB_FLAGGED(victim, MOB_AGGRESSIVE)) {
act("As the words escape your lips and $N travels\r\n"

View file

@ -91,6 +91,16 @@
/** The total number of Room Flags */
#define NUM_ROOM_FLAGS 17
/* Zone info: Used in zone_data.zone_flags */
#define ZONE_CLOSED 0 /**< Zone is closed - players cannot enter */
#define ZONE_NOIMMORT 1 /**< Immortals (below LVL_GRGOD) cannot enter this zone */
#define ZONE_QUEST 2 /**< This zone is a quest zone (not implemented) */
#define ZONE_GRID 3 /**< Zone is 'on the grid', connected, show on 'areas' */
#define ZONE_NOBUILD 4 /**< Building is not allowed in the zone */
#define ZONE_NOASTRAL 5 /**< No teleportation magic will work to or from this zone */
/** The total number of Zone Flags */
#define NUM_ZONE_FLAGS 6
/* Exit info: used in room_data.dir_option.exit_info */
#define EX_ISDOOR (1 << 0) /**< Exit is a door */
#define EX_CLOSED (1 << 1) /**< The door is closed */
@ -489,6 +499,7 @@
#define AF_ARRAY_MAX 4 /**< # Bytes in Bit vector - Affect flags */
#define TW_ARRAY_MAX 4 /**< # Bytes in Bit vector - Obj Wear Locations */
#define EF_ARRAY_MAX 4 /**< # Bytes in Bit vector - Obj Extra Flags */
#define ZN_ARRAY_MAX 4 /**< # Bytes in Bit vector - Zone Flags */
/* other #defined constants */
/* **DO**NOT** blindly change the number of levels in your MUD merely by

View file

@ -295,6 +295,15 @@ void char_from_furniture(struct char_data *ch);
/** Room flags.
* @param loc The real room number. */
#define ROOM_FLAGS(loc) (world[(loc)].room_flags)
/** Zone flags.
* @param rnum The real zone number. */
#define ZONE_FLAGS(rnum) (zone_table[(rnum)].zone_flags)
/** Zone minimum level restriction.
* @param rnum The real zone number. */
#define ZONE_MINLVL(rnum) (zone_table[(rnum)].min_level)
/** Zone maximum level restriction.
* @param rnum The real zone number. */
#define ZONE_MAXLVL(rnum) (zone_table[(rnum)].max_level)
/** References the routine element for a spell. Currently unused. */
#define SPELL_ROUTINES(spl) (spell_info[spl].routines)
@ -319,6 +328,8 @@ void char_from_furniture(struct char_data *ch);
#define PRF_FLAGGED(ch, flag) (IS_SET_AR(PRF_FLAGS(ch), (flag)))
/** 1 if flag is set in the room of loc, 0 if not. */
#define ROOM_FLAGGED(loc, flag) (IS_SET_AR(ROOM_FLAGS(loc), (flag)))
/** 1 if flag is set in the zone of rnum, 0 if not. */
#define ZONE_FLAGGED(rnum, flag) (IS_SET_AR(zone_table[(rnum)].zone_flags, (flag)))
/** 1 if flag is set in the exit, 0 if not. */
#define EXIT_FLAGGED(exit, flag) (IS_SET((exit)->exit_info, (flag)))
/** 1 if flag is set in the affects bitarray of obj, 0 if not. */
@ -351,6 +362,9 @@ void char_from_furniture(struct char_data *ch);
#define SECT(room) (VALID_ROOM_RNUM(room) ? \
world[(room)].sector_type : SECT_INSIDE)
/** Return the zone number for this room */
#define GET_ROOM_ZONE(room) (VALID_ROOM_RNUM(room) ? world[(room)].zone : NOWHERE)
/** TRUE if the room has no light, FALSE if not. */
#define IS_DARK(room) room_is_dark((room))
/** TRUE if the room has light, FALSE if not. */

View file

@ -191,7 +191,7 @@ ACMD(do_oasis_zedit)
static void zedit_setup(struct descriptor_data *d, int room_num)
{
struct zone_data *zone;
int subcmd = 0, count = 0, cmd_room = NOWHERE;
int subcmd = 0, count = 0, cmd_room = NOWHERE, i;
/* Allocate one scratch zone structure. */
CREATE(zone, struct zone_data, 1);
@ -208,6 +208,12 @@ static void zedit_setup(struct descriptor_data *d, int room_num)
zone->number = 0; /* Header information has changed. */
zone->age = 0; /* The commands have changed. */
for (i=0; i<ZN_ARRAY_MAX; i++)
zone->zone_flags[(i)] = zone_table[OLC_ZNUM(d)].zone_flags[(i)];
zone->min_level = zone_table[OLC_ZNUM(d)].min_level;
zone->max_level = zone_table[OLC_ZNUM(d)].max_level;
/* Start the reset command list with a terminator. */
CREATE(zone->cmd, struct reset_com, 1);
zone->cmd[0].command = 'S';
@ -284,7 +290,7 @@ static void zedit_save_internally(struct descriptor_data *d)
{
int mobloaded = FALSE,
objloaded = FALSE,
subcmd;
subcmd, i;
room_rnum room_num = real_room(OLC_NUM(d));
if (room_num == NOWHERE) {
@ -341,6 +347,10 @@ static void zedit_save_internally(struct descriptor_data *d)
zone_table[OLC_ZNUM(d)].top = OLC_ZONE(d)->top;
zone_table[OLC_ZNUM(d)].reset_mode = OLC_ZONE(d)->reset_mode;
zone_table[OLC_ZNUM(d)].lifespan = OLC_ZONE(d)->lifespan;
zone_table[OLC_ZNUM(d)].min_level = OLC_ZONE(d)->min_level;
zone_table[OLC_ZNUM(d)].max_level = OLC_ZONE(d)->max_level;
for (i=0; i<ZN_ARRAY_MAX; i++)
zone_table[OLC_ZNUM(d)].zone_flags[(i)] = OLC_ZONE(d)->zone_flags[(i)];
}
add_to_save_list(zone_table[OLC_ZNUM(d)].number, SL_ZON);
}
@ -361,16 +371,63 @@ static int start_change_command(struct descriptor_data *d, int pos)
return 1;
}
/*------------------------------------------------------------------*/
void zedit_disp_flag_menu(struct descriptor_data *d)
{
int counter, columns = 0;
char bits[MAX_STRING_LENGTH];
clear_screen(d);
for (counter = 0; counter < NUM_ZONE_FLAGS; counter++) {
write_to_output(d, "@g%2d@n) %-20.20s %s", counter + 1,
zone_bits[counter], !(++columns % 2) ? "\r\n" : "");
}
sprintbitarray(OLC_ZONE(d)->zone_flags, zone_bits, ZN_ARRAY_MAX, bits);
write_to_output(d, "\r\nZone flags: @c%s@n\r\n"
"Enter Zone flags, 0 to quit : ", bits);
OLC_MODE(d) = ZEDIT_ZONE_FLAGS;
}
/*------------------------------------------------------------------*/
bool zedit_get_levels(struct descriptor_data *d, char *buf)
{
/* Create a string for the recommended levels for this zone. */
if ((OLC_ZONE(d)->min_level == -1) && (OLC_ZONE(d)->max_level == -1)) {
sprintf(buf, "<Not Set!>");
return FALSE;
}
if (OLC_ZONE(d)->min_level == -1) {
sprintf(buf, "Up to level %d", OLC_ZONE(d)->max_level);
return TRUE;
}
if (OLC_ZONE(d)->max_level == -1) {
sprintf(buf, "Above level %d", OLC_ZONE(d)->min_level);
return TRUE;
}
sprintf(buf, "Levels %d to %d", OLC_ZONE(d)->min_level, OLC_ZONE(d)->max_level);
return TRUE;
}
/*------------------------------------------------------------------*/
/* Menu functions */
/* the main menu */
static void zedit_disp_menu(struct descriptor_data *d)
{
int subcmd = 0, room, counter = 0;
char buf1[MAX_STRING_LENGTH], lev_string[50];
bool levels_set = FALSE;
get_char_colors(d->character);
clear_screen(d);
room = real_room(OLC_NUM(d));
sprintbitarray(OLC_ZONE(d)->zone_flags, zone_bits, ZN_ARRAY_MAX, buf1);
levels_set = zedit_get_levels(d, lev_string);
/* Menu header */
send_to_char(d->character,
"Room number: %s%d%s Room zone: %s%d\r\n"
@ -379,7 +436,9 @@ static void zedit_disp_menu(struct descriptor_data *d)
"%sL%s) Lifespan : %s%d minutes\r\n"
"%sB%s) Bottom of zone : %s%d\r\n"
"%sT%s) Top of zone : %s%d\r\n"
"%sR%s) Reset Mode : %s%s%s\r\n"
"%sR%s) Reset Mode : %s%s\r\n"
"%sF%s) Zone Flags : %s%s\r\n"
"%sM%s) Level Range : %s%s%s\r\n"
"[Command list]\r\n",
cyn, OLC_NUM(d), nrm,
@ -389,9 +448,10 @@ static void zedit_disp_menu(struct descriptor_data *d)
grn, nrm, yel, OLC_ZONE(d)->lifespan,
grn, nrm, yel, OLC_ZONE(d)->bot,
grn, nrm, yel, OLC_ZONE(d)->top,
grn, nrm,
yel,
grn, nrm, yel,
OLC_ZONE(d)->reset_mode ? ((OLC_ZONE(d)->reset_mode == 1) ? "Reset when no players are in zone." : "Normal reset.") : "Never reset",
grn, nrm, cyn, buf1,
grn, nrm, levels_set ? cyn : yel, lev_string,
nrm
);
@ -643,10 +703,35 @@ static void zedit_disp_arg3(struct descriptor_data *d)
OLC_MODE(d) = ZEDIT_ARG3;
}
/*-------------------------------------------------------------------*/
/*
* Print the recommended levels menu and setup response catch.
*/
void zedit_disp_levels(struct descriptor_data *d)
{
char lev_string[50];
bool levels_set = FALSE;
levels_set = zedit_get_levels(d, lev_string);
clear_screen(d);
write_to_output(d,
"\r\n"
"@y1@n) Set minimum level\r\n"
"@y2@n) Set maximum level\r\n"
"@y3@n) Clear level restrictions\r\n\r\n"
"@y0@n) Quit to main menu\r\n"
"@gCurrent Setting: %s%s\r\n"
"\r\n"
"Enter choice (0 to quit): ", levels_set ? "@c" : "@y", lev_string
);
OLC_MODE(d) = ZEDIT_LEVELS;
}
/* The event handler */
void zedit_parse(struct descriptor_data *d, char *arg)
{
int pos, i = 0;
int pos, i = 0, number;
switch (OLC_MODE(d)) {
case ZEDIT_CONFIRM_SAVESTRING:
@ -760,6 +845,15 @@ void zedit_parse(struct descriptor_data *d, char *arg)
"Enter new zone reset type : ");
OLC_MODE(d) = ZEDIT_ZONE_RESET;
break;
case 'f':
case 'F':
zedit_disp_flag_menu(d);
break;
case 'm':
case 'M':
/*** Edit zone level restrictions (sub-menu) ***/
zedit_disp_levels(d);
break;
default:
zedit_disp_menu(d);
break;
@ -767,6 +861,49 @@ void zedit_parse(struct descriptor_data *d, char *arg)
break;
/* End of ZEDIT_MAIN_MENU */
/*-------------------------------------------------------------------*/
case ZEDIT_LEVELS:
switch (*arg) {
case '1': write_to_output(d, "Enter the min level for this zone (0-%d, -1 = none): ", (LVL_IMMORT-1));
OLC_MODE(d) = ZEDIT_LEV_MIN;
break;
case '2': write_to_output(d, "Enter the max level for this zone (0-%d, -1 = none): ", (LVL_IMMORT-1));
OLC_MODE(d) = ZEDIT_LEV_MAX;
break;
case '3': OLC_ZONE(d)->min_level = -1;
OLC_ZONE(d)->max_level = -1;
OLC_ZONE(d)->age = 1;
zedit_disp_levels(d);
break;
case '0':
zedit_disp_menu(d);
break;
default: write_to_output(d, "Invalid choice!\r\n");
break;
}
break;
/*-------------------------------------------------------------------*/
case ZEDIT_LEV_MIN:
pos = atoi(arg);
OLC_ZONE(d)->min_level = MIN(MAX(pos,-1), 100);
OLC_ZONE(d)->age = 1;
zedit_disp_levels(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_LEV_MAX:
pos = atoi(arg);
OLC_ZONE(d)->max_level = MIN(MAX(pos,-1), 100);
OLC_ZONE(d)->age = 1;
zedit_disp_levels(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_NEW_ENTRY:
/* Get the line number and insert the new line. */
pos = atoi(arg);
@ -779,6 +916,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
zedit_disp_menu(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_DELETE_ENTRY:
/* Get the line number and delete the line. */
pos = atoi(arg);
@ -789,6 +927,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
zedit_disp_menu(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_CHANGE_ENTRY:
/* Parse the input for which line to edit, and goto next quiz. Abort edit,
and return to main menu idea from Mark Garringer zizazat@hotmail.com */
@ -808,6 +947,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
zedit_disp_menu(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_COMMAND_TYPE:
/* Parse the input for which type of command this is, and goto next quiz. */
OLC_CMD(d).command = toupper(*arg);
@ -829,6 +969,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
}
break;
/*-------------------------------------------------------------------*/
case ZEDIT_IF_FLAG:
/* Parse the input for the if flag, and goto next quiz. */
switch (*arg) {
@ -847,6 +988,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
zedit_disp_arg1(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ARG1:
/* Parse the input for arg1, and goto next quiz. */
if (!isdigit(*arg)) {
@ -891,6 +1033,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
}
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ARG2:
/* Parse the input for arg2, and goto next quiz. */
if (!isdigit(*arg)) {
@ -953,6 +1096,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
}
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ARG3:
/* Parse the input for arg3, and go back to main menu. */
if (!isdigit(*arg)) {
@ -1004,6 +1148,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
}
break;
/*-------------------------------------------------------------------*/
case ZEDIT_SARG1:
if (strlen(arg)) {
OLC_CMD(d).sarg1 = strdup(arg);
@ -1013,6 +1158,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
write_to_output(d, "Must have some name to assign : ");
break;
/*-------------------------------------------------------------------*/
case ZEDIT_SARG2:
if (strlen(arg)) {
OLC_CMD(d).sarg2 = strdup(arg);
@ -1021,6 +1167,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
write_to_output(d, "Must have some value to set it to :");
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ZONE_NAME:
/* Add new name and return to main menu. */
if (genolc_checkstring(d, arg)) {
@ -1034,6 +1181,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
zedit_disp_menu(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ZONE_BUILDERS:
/* Add new builders list and return to main menu. */
if (genolc_checkstring(d, arg)) {
@ -1047,6 +1195,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
zedit_disp_menu(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ZONE_RESET:
/* Parse and add new reset_mode and return to main menu. */
pos = atoi(arg);
@ -1059,6 +1208,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
}
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ZONE_LIFE:
/* Parse and add new lifespan and return to main menu. */
pos = atoi(arg);
@ -1071,6 +1221,27 @@ void zedit_parse(struct descriptor_data *d, char *arg)
}
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ZONE_FLAGS:
number = atoi(arg);
if (number < 0 || number > NUM_ZONE_FLAGS) {
write_to_output(d, "That is not a valid choice!\r\n");
zedit_disp_flag_menu(d);
} else if (number == 0) {
zedit_disp_menu(d);
break;
}
else {
/*
* Toggle the bit.
*/
TOGGLE_BIT_AR(OLC_ZONE(d)->zone_flags, number - 1);
OLC_ZONE(d)->number = 1;
zedit_disp_flag_menu(d);
}
return;
/*-------------------------------------------------------------------*/
case ZEDIT_ZONE_BOT:
/* Parse and add new bottom room in zone and return to main menu. */
if (OLC_ZNUM(d) == 0)
@ -1081,6 +1252,7 @@ void zedit_parse(struct descriptor_data *d, char *arg)
zedit_disp_menu(d);
break;
/*-------------------------------------------------------------------*/
case ZEDIT_ZONE_TOP:
/* Parse and add new top room in zone and return to main menu. */
if (OLC_ZNUM(d) == top_of_zone_table)