Zone Flags [by Ming]
Snippet Posted Sunday, July 29th @ 04:20:55 PM, by Brandon Brown in the Zones dept.
Ming from Wintermute writes, "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 in the next post. Enjoy!"
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 in the next post. 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;
      }

<< Multiplayer Limiting [by Boxboy] | Reply | Flattened | Arena Combat [by Taerin] >>

 


Related Links
  Ming from Wintermute
Related Articles
More by bbrown
 
 

Quick Links
 
The CircleMUD FAQ
The CircleMUD home page
Alex's Snippets
Wintermute Snippets
CircleMUD Bug Reporting or Help
CircleMUD List Archives
CircleMUD Resources
Death Gate's Scripts
(Author of C conversion)
Sammy's code site
Erwin S. Andreasen's page
(Author of mudFTP and other goodies)
Death's Gate Scripting site
Help for CircleMUD in Windows
The OasisOLC Maintenance Effort
George's Random Stuff
Imaginary Realities
MUD Dictionary