This system permits lib staff to assign zone globals to areas. These zone flags supplement room flags, but can be assigned in one line zone file command (i.e. Z 0 1 0 0) in order to cover an entire zone. This reduces the amount of work needed in editing, and is provided as a prerequisite for the gladiatorial arena combat snippet. Enjoy! pkilling system defined by zone flags added to wintermute in august 1998 sarq's zone flag system implemented ----------------------------------------------------------------------------- killer toggle command in interpreter.c, define: ACMD(do_killer); in interpreter.c, master command list, add: { "killer" , POS_FIGHTING, do_killer , 0, 0 }, in interpreter.c, append: /* killer command for voluntary switching to the dark side, taerin 8/14/98 */ ACMD(do_killer) { char buf2[128]; if (IS_NPC(ch) || PLR_FLAGGED(ch, PLR_KILLER)) return; SET_BIT(PLR_FLAGS(ch), PLR_KILLER); send_to_char("Cry Havoc! And let slip the dogs of war!\r\n", ch); send_to_char("Your move to the dark side is only reversed by: death or pardon.\r\n", ch); sprintf(buf2, "%s elects to become a PLAYER KILLER.", GET_NAME(ch)); mudlog(buf2, BRF, LVL_IMMORT, TRUE); } in fight.c, void check_killer: send_to_char("Cry Havoc! And let slip the dogs of war!\r\n", ch); ----------------------------------------------------------------------------- ZONE_FLAGS utils.h: after line: /* basic bitvector utils ********************************/ Add: /* Sarq 8/21/98 - for New Z zone command */ #define IN_ZONE(ch) (world[(ch)->in_room].zone) /* zonenumb should be IN_ZONE(ch) */ #define ZONE_NOPKILL(zone) (zone_flags[zone].NOPKILL) #define ZONE_NOPORTAL(zone) (zone_flags[zone].NOPORTAL) in structs.h: Before line: (roughly line 737) /* char-related structures *********************/ Add: /* zone-related structs ************************************8/21/98 by Sarq */ struct zone_flag_struct { /* if these are set to 1 during game, you can NOT do them in that zone */ int NOPORTAL, NOPKILL; }; typedef struct zone_flag_struct zf_struct; zf_struct zone_flags[500]; /* If number of zones exceeds 500, this must increase */ in db.c, void reset_zone: after: for (cmd_no = 0; ZCMD.command != 'S'; cmd_no++) { add: if (ZCMD.command == 'Z') test_log("Z COMMAND FOUND"); /* 8/21/98 Sarq */ then at end: case 'Z': /* Added by Sarq on 8/21/98 * this case is for new additions to the zone commands. * Specifically, it handles the following commands: * NO_PORTAL | NO_PKILL * * modified by taerin 8/22/98 * format: Z * Xample: Z 0 1 0 0 * legend: NOPORTAL 1 no portal in or out of this zone * NOPKILL 2 no pkilling in this zone */ switch (ZCMD.arg1) { case 1: test_log("Zone Command Z - 1 NOPORTAL initiated"); zone_flags[zone].NOPORTAL = 1; /* NO_PORTAL */ break; case 2: test_log("Zone Command Z - 2 NOPKILL initiated"); zone_flags[zone].NOPKILL = 1; /* NO_PKILL */ break; default: ZONE_ERROR("Bad use of zone command Z in reset table; cmd disabled"); ZCMD.command = '*'; break; } /* switch (ZCMD.arg1) */ last_cmd = 1; test_log("Running ZONE command line with Z char"); /* sarq 8/21/98 */ break; ----------------------------------------------------------------------------- now implement the zone flags in the code: in spells.c (portal spell) : after line : assert((level >= 0) && (level <= LVL_IMPL)); (roughly line 491) ADD: /* Sarq 8/21/98 - Zone Flag !PORTAL additon */ /* ZONE_NOPORTAL(IN_ZONE(victim)) is the zone portal flag of the victim */ /* ZONE_NOPORTAL(IN_ZONE(ch)) is the zone portal flag of the character */ if (((ZONE_NOPORTAL(IN_ZONE(victim)) == 1) || (ZONE_NOPORTAL(IN_ZONE(ch)) == 1)) && (GET_LEVEL(ch) < LVL_IMPL)) { /* Can't portal bitch! Let's tell them that and end */ send_to_char("Your target is protected!\n\r", ch); return; } /* taerin gets annoyed at grand central */ if (IS_SET(rp->room_flags, ROOM_GODROOM)) { send_to_char("That room is private.\n\r", ch); extract_obj(tmp_obj); return; } add in roomflags too in act.informative.c, void look_at_room: char zf_buf[128]; *zf_buf = '\0'; if (ZONE_NOPORTAL(IN_ZONE(ch)) == 1) strcat(zf_buf, " [ !PORTAL ]"); if (ZONE_NOPKILL(IN_ZONE(ch)) == 1) strcat(zf_buf, " [ !PKILL ]"); sprintf(buf2, "[%5d] %s [ %s] [ %s ]%s", world[ch->in_room].number, world[ch->in_room].name, buf, buf1, zf_buf); ----------------------------------------------------------------------------- now implement the pkill flags in the code: !pk_allowed = 0 will permit pkilling in designated zones !pk_allowed = 1 will turn off pkilling globally NOPKILL = 0 will allow pkill in the zone NOPKILL = 1 will prevent pkill in zone remove murder command account for KILLER flag ok to kill if: 1. !pk_allowed = 0, global pk protection is false; and 2. ZONE_NOPKILL(IN_ZONE(ch)) = 0, zone allows pkill leave this check out until folks request it, being flagged is enough (with guards) 3. PLR_FLAGGED(victim, PLR_KILLER) = 1, victim is a KILLER later on we can add that pkillers have NO protection at all in NOPKILL zones therefore, block pkill if: 1. !pk_allowed = 1, global pk protection is true; or 2. ZONE_NOPKILL(IN_ZONE(ch)) = 1, zone doesn't allows pkill so, replace all: if (!pk_allowed) { with if ( (!pk_allowed) || (ZONE_NOPKILL(IN_ZONE(ch)) == 1) ) { ---- in act.offensive.c, ACMD(do_assist): /* think about this do we want to assist also? */ else if ((!pk_allowed || (ZONE_NOPKILL(IN_ZONE(ch)) == 1)) && !IS_NPC(opponent)) /* prevent accidental pkill */ in act.offensive.c, ACMD(do_hit): if (!pk_allowed || (ZONE_NOPKILL(IN_ZONE(ch)) == 1)) { in act.offensive.c, ACMD(do_backstab): if ((!pk_allowed || (ZONE_NOPKILL(IN_ZONE(ch)) == 1)) && !IS_NPC(vict)) { in act.offensive.c, ACMD(do_bash): if ((!pk_allowed || (ZONE_NOPKILL(IN_ZONE(ch)) == 1)) && !IS_NPC(vict)) { in act.offensive.c, ACMD(do_rescue): if ((!pk_allowed || (ZONE_NOPKILL(IN_ZONE(ch)) == 1)) && !IS_NPC(vict)) { in act.offensive.c, ACMD(do_kick): if ((!pk_allowed || (ZONE_NOPKILL(IN_ZONE(ch)) == 1)) && !IS_NPC(vict)) { in act.wizard.c, do_status: /* cosmetic fix */ sprintf(buf, "%s[ SYS: %s disallows PKilling ]%s\r\n", CCRED(ch, C_NRM), GET_NAME(ch), CCNRM(ch, C_NRM)); sprintf(buf, "%s[ SYS: %s allows PKilling ]%s\r\n", CCRED(ch, C_NRM), GET_NAME(ch), CCRED(ch, C_NRM)); in fight.c, void set_fighting, check_killer regardless: /* if (!pk_allowed) */ in fight.c, void damage, check_killer regardless: /* if (!pk_allowed) */ { in fight.c, void fire_missile: if ((!pk_allowed || (ZONE_NOPKILL(IN_ZONE(ch)) == 1)) && !IS_NPC(vict)) { in spell_parser.c, ACMD(do_cast): if (!IS_NPC(tch) && (!pk_allowed || (ZONE_NOPKILL(IN_ZONE(ch)) == 1)) && SINFO.violent) { send_to_char("I don't think so ...\r\n", ch); the following used to present a problem with area affect weapons: in spell_parser.c: extern int roomaffect_allowed; in spell_parser.c, void mag_objectmagic, case ITEM_STAFF where it checks through each ch in room (because staves are inherently area affect): /* fixes the staff of ra problem, taerin 8/22/98 */ if (!roomaffect_allowed && !IS_NPC(ch) && !IS_NPC(tch)) continue; in act.offensive.c, ACMD(do_hit): replace: if (!IS_NPC(vict) && !IS_NPC(ch)) { if (subcmd != SCMD_MURDER) { send_to_char("Go to a PKILL zone and fight!\r\n", ch); return; } else { check_killer(ch, vict); } } with: if (!IS_NPC(vict) && !IS_NPC(ch)) { /* disabled SCMD_MURDER */ send_to_char("Go to a PKILL zone and fight!\r\n", ch); return; }