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