circlemud_squared_0.5.153/cnf/
circlemud_squared_0.5.153/etc/
circlemud_squared_0.5.153/etc/etc/
circlemud_squared_0.5.153/etc/house/
circlemud_squared_0.5.153/etc/misc/
circlemud_squared_0.5.153/etc/plralias/A-E/
circlemud_squared_0.5.153/etc/plralias/F-J/
circlemud_squared_0.5.153/etc/plralias/K-O/
circlemud_squared_0.5.153/etc/plralias/P-T/
circlemud_squared_0.5.153/etc/plralias/U-Z/
circlemud_squared_0.5.153/etc/plralias/ZZZ/
circlemud_squared_0.5.153/etc/plrobjs/
circlemud_squared_0.5.153/etc/plrobjs/A-E/
circlemud_squared_0.5.153/etc/plrobjs/F-J/
circlemud_squared_0.5.153/etc/plrobjs/K-O/
circlemud_squared_0.5.153/etc/plrobjs/P-T/
circlemud_squared_0.5.153/etc/plrobjs/U-Z/
circlemud_squared_0.5.153/etc/plrobjs/ZZZ/
circlemud_squared_0.5.153/etc/text/
circlemud_squared_0.5.153/etc/text/help/
circlemud_squared_0.5.153/src/util/
circlemud_squared_0.5.153/src/util/worldconv/
/**
 * @file zone.c
 * @ingroup zone
 *
 * Zone based code
 *
 * @author Geoff Davis <geoff@circlemudsquared.org>
 * @author Greg Buxton <greg@circlemudsquared.org>
 *
 * @par Copyright:
 *   Copyright (C) 2006 Geoff Davis <geoff@circlemudsquared.org><br>
 *                      Greg Buxton <greg@circlemudsquared.org>
 *
 * @par
 *   Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University<br>
 *   CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.
 *
 * @par
 *   All rights reserved.  See license.doc for complete information.
 *
 * @package cs
 * @version 1.0
 */

#define __ZONE_C__

#include "sysdep.h"
#include "structs.h"
#include "interpreter.h"
#include "main.h"
#include "utils.h"
#include "dao.h"
#include "db.h"
#include "spells.h"
#include "room.h"
#include "extraDesc.h"
#include "item.h"
#include "mobile.h"
#include "shop.h"

/*
 * This is here for now
 */

const char *reset_types[] = {
  /* 00 */ "none",
  /* 01 */ "loadMobile",
  /* 02 */ "loadItem",
  /* 03 */ "giveItemToMobile",
  /* 04 */ "doorState",
  /* 05 */ "purgeItem",
  /* 06 */ "purgeMobile", /* new? */
  /* 07 */ "equipMobile",
  /* 08 */ "putItemInContainer",
             "\n"
};

const char *equip_slots[] = {
  "light",
  "rightFinger",
  "leftFinger",
  "firstNeck",
  "secondNeck",
  "onBody",
  "head",
  "legs",
  "feet",
  "hands",
  "arms",
  "shield",
  "aboutBody",
  "waist",
  "rightWrist",
  "leftWrist",
  "wielded",
  "held",
  "\n"
};

#define ZCMD_NONE	(0)
#define ZCMD_LOADMOB	(1)
#define ZCMD_LOADITEM	(2)
#define ZCMD_GIVEITEM	(3)
#define ZCMD_SETDOOR	(4)
#define ZCMD_PURGEITEM	(5)
#define ZCMD_PURGEMOB	(6)
#define ZCMD_EQUIPMOB	(7)
#define ZCMD_PUTITEM	(8)

/*
 * External variables.
 */
extern const char *zone_reset_types[];
extern struct shop_data *shop_index;
extern int top_shop;

/*
 * Local function prototypes.
 */
bool zoneData_saveFile(zoneData_t *zone);
void zoneData_resetCommandToDao(daoData_t *dao, int n, resetCommand_t *cmd);

void keyword_zones(void) {
  char keywords[120] = { '\0' };
  int i = 0;

  for (i = 0; i <= top_of_zone_table; i++) {
    /* Ask for the keyword for the zone, new data */
    log("\r\n:: Zone: %s", zone_table[i].name);
    printf("Specify keyword for zone: ");
    scanf("%s", keywords);
    zone_table[i].keyword = strdup(keywords);
  }
}

void world_toDao(void) {
  zoneRnum_t rzone = NOWHERE;

  /* Declare an iterator variable. */
  register int i = 0;

  log("Saving zones:\r\n");

  /* Iterate each zone in the zone table. */
  for (i = 0; i <= top_of_zone_table; i++) {
    if (!zoneData_saveFile(&(zone_table[i]))) {
      log("...Unable to save zone #%d.\r\n", zone_table[rzone].number);
    }
  }
  log("...Done.\r\n");
}

/**
 * Save a zone to disk in DAO format
 * @param zone Zone to save
 * @returns TRUE or FALSE
 */
bool zoneData_saveFile(zoneData_t *zone) {
  bool retcode = FALSE;
  /* Declare a variable to contain the filename. */
  char filename[PATH_MAX] = { '\0' };

  if (zone == NULL) {
    log("zoneData_saveFile(): invalid 'zone' zoneData_t.");
  } else if (!get_filename(filename, sizeof(filename), ZONE_FILE, zone->keyword)) {
    log("zoneData_saveFile(): couldn't get filename for zone %s.", zone->keyword);
  } else {
    /* Declare an iterator variable. */
    register int i = 0;

    /* Declare some temporary DAO pointers. */
    daoData_t *rootDao = NULL, *subContainerDao = NULL, *zoneDao = NULL;

    rootDao = dao_newDocument();
    zoneDao = dao_newChild(rootDao, "zone");
    dao_newScalar(zoneDao, "name", "%s", zone->name);
    dao_newScalar(zoneDao, "keyword", "%s", zone->keyword);
    dao_newScalar(zoneDao, "lifespan", "%d", zone->lifespan);

    if (zone->cmd && zone->cmd->command != 'S') {
      /* Construct the 'resetList' container DAO. */
      subContainerDao = dao_newChild(zoneDao, "resets");

      /* Iterate over the zone's reset command list. */
      for (i = 0; zone->cmd[i].command != 'S'; i++) {
        /* Convert each zone command to its DAO representation. */
        zoneData_resetCommandToDao(subContainerDao, i, &(zone->cmd[i]));
      }
    }

    /* Set the subcontainer DAO back to NULL. */
    subContainerDao = NULL;

    /* Iterate over the rooms in the world table. */
    for (i = 0; i <= top_of_world; i++) {
      /* Skip rooms not contained by the specified zone. */
      if (zone_table[world[i].zone].number != zone->number) {
        continue;
      }
      /* Allocate the 'roomList' container DAO, if necessary. */
      if (subContainerDao == NULL) {
        subContainerDao = dao_newChild(zoneDao, "rooms");
      }
      /* Convert each room to its DAO representation. */
      roomData_toDao(subContainerDao, &(world[i]));
    }

    /* Set the subcontainer DAO back to NULL. */
    subContainerDao = NULL;

    /* Iterate over the items in the obj_proto table */
    for (i = 0; i <= top_of_objt; i++) {
      /* Skip objects not in the specified zone. */
      if (GET_OBJ_VNUM(&(obj_proto[i])) > zone->top ||
          GET_OBJ_VNUM(&(obj_proto[i])) < zone->bot) {
        continue;
      }
      /* Allocate the 'objectList' container DAO, if necessary. */
      if (subContainerDao == NULL) {
        subContainerDao = dao_newChild(zoneDao, "itemPrototypes");
      }
      /* Convert each item to it's DAO representation. */
      itemData_toDao(subContainerDao, &(obj_proto[i]));
    }

    /* Set the subcontainer DAO back to NULL. */
    subContainerDao = NULL;

    /* Iterate over the mobiles in the mob_proto table */
    for (i = 0; i <= top_of_mobt; i++) {
      /* Skip mobiles not in the specified zone. */
      if (GET_MOB_VNUM(&(mob_proto[i])) > zone->top ||
          GET_MOB_VNUM(&(mob_proto[i])) < zone->bot) {
        continue;
      }
      /* Allocate the 'mobileList' container DAO, if necessary. */
      if (subContainerDao == NULL) {
        subContainerDao = dao_newChild(zoneDao, "mobilePrototypes");
      }
      /* Convert each mobile to it's DAO representation. */
      mobile_toDao(subContainerDao, &(mob_proto[i]));
    }

    /* Set the subcontainer DAO back to NULL. */
    subContainerDao = NULL;

    /* Iterate over the shops in the shop_index table */
    for (i = 0; i <= top_shop; i++) {
      if (shop_index[i].vnum > zone->top ||
          shop_index[i].vnum < zone->bot) {
        continue;
      }
      /* Allocate the 'mobileList' container DAO, if necessary. */
      if (subContainerDao == NULL) {
        subContainerDao = dao_newChild(zoneDao, "shops");
      }
      /* Convert each shop to it's DAO representation. */
      shopData_toDao(subContainerDao, &(shop_index[i]));
    }

    /* Save the DAO out to disk. */
    retcode = dao_saveFile(rootDao, filename);

    /* Free the top-level DAO container. */
    dao_free(rootDao);
  }
  return (retcode);
}

room_rnum real_room(room_vnum vnum);

extern const char *dirs[];
extern const char *wear_bits[];

int zoneNum_forVnum(int vnum) {
  int zNum = 0;

  for (zNum = 0; zNum <= top_of_zone_table; zNum++) {
    if (zone_table[zNum].bot <= vnum && vnum <= zone_table[zNum].top)
      return zNum;
  }
  return -1;
}

/**
 * Convert a zone reset to its DAO representation.
 * @param parentDao the container DAO to contain the reset's DAO
 * @param n the index of the zone reset in the zone's reset list
 * @param cmd the zone reset to be converted
 * @return none
 */
void zoneData_resetCommandToDao(daoData_t *dao, int n, resetCommand_t *cmd) {
  if (dao == NULL) {
    log("zoneData_resetCommandToDao(): invalid 'dao' daoData_t.");
  } else if (cmd == NULL) {
    log("zoneData_resetCommandToDao(): invalid 'cmd' resetCommand_t.");
  } else {
    /* Declare a DAO pointer. */
    daoData_t *resetDao = NULL;
    /* Declare a temp variable */
    int zResetType = 0;

    resetDao = dao_newChild(dao, "%d", n);

    /* Set the zone reset type. */
    switch(cmd->command) {
      case '*':	zResetType = ZCMD_NONE; break;
      case 'M': zResetType = ZCMD_LOADMOB; break;
      case 'O': zResetType = ZCMD_LOADITEM; break;
      case 'G': zResetType = ZCMD_GIVEITEM; break;
      case 'D': zResetType = ZCMD_SETDOOR; break;
      case 'R': zResetType = ZCMD_PURGEITEM; break;
      case 'K': zResetType = ZCMD_PURGEMOB; break;
      case 'E': zResetType = ZCMD_EQUIPMOB; break;
      case 'P': zResetType = ZCMD_PUTITEM; break;
    }

    if (cmd->if_flag != 0)
      dao_newScalar(resetDao, "then", "%s", YESNO(cmd->if_flag));

    dao_newScalar(resetDao, "command", "%s", reset_types[zResetType]);

    /*
     * This is where things will get ugly...
     *
     * To make the reset commands human readable, we're outputting different
     * tags based on the reset command.  This means more work in the saving
     * and loading, but a much better result for human editing.
     */
    switch(zResetType) {
      case ZCMD_NONE:
        break;
      case ZCMD_LOADMOB:
        if (cmd->arg1 != 0)
          dao_newScalar(resetDao, "mobile", "%s:%d", zone_table[(zoneNum_forVnum(cmd->arg1))].keyword, cmd->arg1);
        if (cmd->arg3 != 0)
          dao_newScalar(resetDao, "inRoom", "%s:%d", zone_table[(world[real_room(cmd->arg3)].zone)].keyword, cmd->arg3);
        if (cmd->arg2 != 0)
          dao_newScalar(resetDao, "maxNumber", "%d", cmd->arg2);
        break;
      case ZCMD_LOADITEM:
        if (cmd->arg1 != 0)
          dao_newScalar(resetDao, "item", "%s:%d", zone_table[(zoneNum_forVnum(cmd->arg1))].keyword, cmd->arg1);
        if (cmd->arg3 != 0)
          dao_newScalar(resetDao, "inRoom", "%s:%d", zone_table[(world[real_room(cmd->arg3)].zone)].keyword, cmd->arg3);
        if (cmd->arg2 != 0)
          dao_newScalar(resetDao, "maxNumber", "%d", cmd->arg2);
        break;
      case ZCMD_GIVEITEM:
        if (cmd->arg1 != 0)
          dao_newScalar(resetDao, "item", "%s:%d", zone_table[(zoneNum_forVnum(cmd->arg1))].keyword, cmd->arg1);
        if (cmd->arg2 != 0)
          dao_newScalar(resetDao, "maxNumber", "%d", cmd->arg2);
        /* No arg3 for these */
        break;
      case ZCMD_SETDOOR:
        if (cmd->arg2 >= 0 && cmd->arg2 <= NUM_OF_DIRS) {
          if (cmd->arg1 != 0)
            dao_newScalar(resetDao, "inRoom", "%s:%d", zone_table[(world[real_room(cmd->arg1)].zone)].keyword, cmd->arg1);

          dao_newScalar(resetDao, "direction", "%s", dirs[cmd->arg2]);

          switch(cmd->arg3) {
            case 0:
              dao_newScalar(resetDao, "state", "open");
              break;
            case 1:
              dao_newScalar(resetDao, "state", "closed");
              break;
            case 2:
              dao_newScalar(resetDao, "state", "locked");
              break;
          }
        }          
        break;
      case ZCMD_PURGEITEM:
        if (cmd->arg1 != 0)
          dao_newScalar(resetDao, "inRoom", "%s:%d", zone_table[(world[real_room(cmd->arg1)].zone)].keyword, cmd->arg1);
        if (cmd->arg2 != 0)
          dao_newScalar(resetDao, "item", "%s:%d", zone_table[(zoneNum_forVnum(cmd->arg2))].keyword, cmd->arg2);
        /* No arg3 for these */
        break;
      case ZCMD_PURGEMOB:
        if (cmd->arg1 != 0)
          dao_newScalar(resetDao, "inRoom", "%s:%d", zone_table[(world[real_room(cmd->arg1)].zone)].keyword, cmd->arg1);
        if (cmd->arg2 != 0)
          dao_newScalar(resetDao, "mobile", "%s:%d", zone_table[(zoneNum_forVnum(cmd->arg2))].keyword, cmd->arg2);
        /* No arg3 for these */
        break;
      case ZCMD_EQUIPMOB:
        if (cmd->arg3 >= 0 && cmd->arg3 < NUM_WEARS) {
          if (cmd->arg1 != 0)
            dao_newScalar(resetDao, "item", "%s:%d", zone_table[(zoneNum_forVnum(cmd->arg1))].keyword, cmd->arg1);

          dao_newScalar(resetDao, "wearLocation", "%s", equip_slots[cmd->arg3]);

          if (cmd->arg2 != 0)
            dao_newScalar(resetDao, "maxNumber", "%d", cmd->arg2);
        }
        break;
      case ZCMD_PUTITEM:
        if (cmd->arg1 != 0)
          dao_newScalar(resetDao, "item", "%s:%d", zone_table[(zoneNum_forVnum(cmd->arg1))].keyword, cmd->arg1);
        if (cmd->arg2 != 0)
          dao_newScalar(resetDao, "maxNumber", "%d", cmd->arg2);
        if (cmd->arg3 != 0)
          dao_newScalar(resetDao, "inItem", "%s:%d", zone_table[(zoneNum_forVnum(cmd->arg3))].keyword, cmd->arg3);
        break;
    }

  }
}