/************************************************************************ * OasisOLC - General / oasis.c v2.0 * * Original author: Levork * * Copyright 1996 by Harvey Gilpin * * Copyright 1997-2001 by George Greer (greerga@circlemud.org) * ************************************************************************/ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "interpreter.h" #include "comm.h" #include "db.h" #include "shop.h" #include "genolc.h" #include "genmob.h" #include "genshp.h" #include "genzon.h" #include "genwld.h" #include "genobj.h" #include "oasis.h" #include "screen.h" const char *nrm, *grn, *cyn, *yel; /* * External data structures. */ extern struct obj_data *obj_proto; extern struct char_data *mob_proto; extern struct room_data *world; extern zone_rnum top_of_zone_table; extern struct zone_data *zone_table; extern struct descriptor_data *descriptor_list; /* * Internal data structures. */ struct olc_scmd_info_t { const char *text; int con_type; } olc_scmd_info[] = { { "room", CON_REDIT }, { "object", CON_OEDIT }, { "zone", CON_ZEDIT }, { "mobile", CON_MEDIT }, { "shop", CON_SEDIT }, { "\n", -1 } }; /* -------------------------------------------------------------------------- */ /* * Only player characters should be using OLC anyway. */ void clear_screen(struct descriptor_data *d) { if (PRF_FLAGGED(d->character, PRF_CLS)) send_to_char("[H[J", d->character); } /* -------------------------------------------------------------------------- */ /* * Exported ACMD do_oasis function. * * This function is the OLC interface. It deals with all the * generic OLC stuff, then passes control to the sub-olc sections. */ ACMD(do_oasis) { int number = -1, save = 0, real_num; struct descriptor_data *d; char *buf3; /* * No screwing around as a mobile. */ if (IS_NPC(ch)) return; /* * The command to see what needs to be saved, typically 'olc'. */ if (subcmd == SCMD_OLC_SAVEINFO) { do_show_save_list(ch); return; } /* * Parse any arguments. */ buf3 = two_arguments(argument, buf1, buf2); if (!*buf1) { /* No argument given. */ switch (subcmd) { case SCMD_OASIS_ZEDIT: case SCMD_OASIS_REDIT: number = GET_ROOM_VNUM(IN_ROOM(ch)); break; case SCMD_OASIS_OEDIT: case SCMD_OASIS_MEDIT: case SCMD_OASIS_SEDIT: sprintf(buf, "Specify a %s VNUM to edit.\r\n", olc_scmd_info[subcmd].text); send_to_char(buf, ch); return; } } else if (!isdigit(*buf1)) { if (str_cmp("save", buf1) == 0) { save = TRUE; if (is_number(buf2)) number = atoi(buf2); else if (GET_OLC_ZONE(ch) >= 0) { zone_rnum zlok; if ((zlok = real_zone(GET_OLC_ZONE(ch))) == NOWHERE) number = -1; else number = genolc_zone_bottom(zlok); /* Or .top or in between. */ } if (number < 0) { send_to_char("Save which zone?\r\n", ch); return; } } else if (subcmd == SCMD_OASIS_ZEDIT && GET_LEVEL(ch) >= LVL_IMPL) { if (str_cmp("new", buf1) || !buf3 || !*buf3) send_to_char("Unknown command, perhaps 'new lower-room-number upper-room-number'?\r\n", ch); else { char sbot[MAX_INPUT_LENGTH], stop[MAX_INPUT_LENGTH]; room_vnum bottom, top; skip_spaces(&buf3); /* actually, atoi() doesn't care... */ two_arguments(buf3, sbot, stop); number = atoi(buf2); bottom = atoi(sbot); top = atoi(stop); zedit_new_zone(ch, number, bottom, top); } return; } else { send_to_char("Yikes! Stop that, someone will get hurt!\r\n", ch); return; } } /* * If a numeric argument was given (like a room number), get it. */ if (number == -1) number = atoi(buf1); /* * Check that whatever it is isn't already being edited. */ for (d = descriptor_list; d; d = d->next) if (STATE(d) == olc_scmd_info[subcmd].con_type) if (d->olc && OLC_NUM(d) == number) { sprintf(buf, "That %s is currently being edited by %s.\r\n", olc_scmd_info[subcmd].text, PERS(d->character, ch)); send_to_char(buf, ch); return; } d = ch->desc; /* * Give descriptor an OLC structure. */ if (d->olc) { mudlog("SYSERR: do_oasis: Player already had olc structure.", BRF, LVL_IMMORT, TRUE); free(d->olc); } CREATE(d->olc, struct oasis_olc_data, 1); /* * Find the zone. */ if ((OLC_ZNUM(d) = real_zone_by_thing(number)) == -1) { send_to_char("Sorry, there is no zone for that number!\r\n", ch); free(d->olc); d->olc = NULL; return; } /* * Everyone but IMPLs can only edit zones they have been assigned. */ if (zone_table[OLC_ZNUM(d)].number != GET_OLC_ZONE(ch) && GET_LEVEL(ch) < LVL_IMPL) { send_to_char("You do not have permission to edit this zone.\r\n", ch); free(d->olc); d->olc = NULL; return; } if (save) { const char *type = NULL; if (subcmd >= 0 && subcmd <= (int)(sizeof(olc_scmd_info) / sizeof(struct olc_scmd_info_t) - 1)) type = olc_scmd_info[subcmd].text; else { send_to_char("Oops, I forgot what you wanted to save.\r\n", ch); return; } sprintf(buf, "Saving all %ss in zone %d.\r\n", type, zone_table[OLC_ZNUM(d)].number); send_to_char(buf, ch); sprintf(buf, "OLC: %s saves %s info for zone %d.", GET_NAME(ch), type, zone_table[OLC_ZNUM(d)].number); mudlog(buf, CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(ch)), TRUE); switch (subcmd) { case SCMD_OASIS_REDIT: save_rooms(OLC_ZNUM(d)); break; case SCMD_OASIS_ZEDIT: save_zone(OLC_ZNUM(d)); break; case SCMD_OASIS_OEDIT: save_objects(OLC_ZNUM(d)); break; case SCMD_OASIS_MEDIT: save_mobiles(OLC_ZNUM(d)); break; case SCMD_OASIS_SEDIT: save_shops(OLC_ZNUM(d)); break; } free(d->olc); d->olc = NULL; return; } OLC_NUM(d) = number; /* * Steal player's descriptor and start up subcommands. */ switch (subcmd) { case SCMD_OASIS_REDIT: if ((real_num = real_room(number)) >= 0) redit_setup_existing(d, real_num); else redit_setup_new(d); STATE(d) = CON_REDIT; break; case SCMD_OASIS_ZEDIT: if ((real_num = real_room(number)) < 0) { send_to_char("That room does not exist.\r\n", ch); free(d->olc); d->olc = NULL; return; } zedit_setup(d, real_num); STATE(d) = CON_ZEDIT; break; case SCMD_OASIS_MEDIT: if ((real_num = real_mobile(number)) < 0) medit_setup_new(d); else medit_setup_existing(d, real_num); STATE(d) = CON_MEDIT; break; case SCMD_OASIS_OEDIT: if ((real_num = real_object(number)) >= 0) oedit_setup_existing(d, real_num); else oedit_setup_new(d); STATE(d) = CON_OEDIT; break; case SCMD_OASIS_SEDIT: if ((real_num = real_shop(number)) >= 0) sedit_setup_existing(d, real_num); else sedit_setup_new(d); STATE(d) = CON_SEDIT; break; } act("$n starts using OLC.", TRUE, d->character, 0, 0, TO_ROOM); SET_BIT(PLR_FLAGS(ch), PLR_WRITING); } /*------------------------------------------------------------*\ Exported utilities \*------------------------------------------------------------*/ /* * Set the colour string pointers for that which this char will * see at color level NRM. Changing the entries here will change * the colour scheme throughout the OLC. */ void get_char_colors(struct char_data *ch) { nrm = CCNRM(ch, C_NRM); grn = CCGRN(ch, C_NRM); cyn = CCCYN(ch, C_NRM); yel = CCYEL(ch, C_NRM); } /* * This procedure frees up the strings and/or the structures * attatched to a descriptor, sets all flags back to how they * should be. */ void cleanup_olc(struct descriptor_data *d, byte cleanup_type) { /* * Clean up WHAT? */ if (d->olc == NULL) return; /* * Check for a room. free_room doesn't perform * sanity checks, we must be careful here. */ if (OLC_ROOM(d)) { switch (cleanup_type) { case CLEANUP_ALL: free_room(OLC_ROOM(d)); break; case CLEANUP_STRUCTS: free(OLC_ROOM(d)); break; default: /* The caller has screwed up. */ log("SYSERR: cleanup_olc: Unknown type!"); break; } } /* * Check for an existing object in the OLC. The strings * aren't part of the prototype any longer. They get added * with str_dup(). */ if (OLC_OBJ(d)) { free_object_strings(OLC_OBJ(d)); free(OLC_OBJ(d)); } /* * Check for a mob. free_mobile() makes sure strings are not in * the prototype. */ if (OLC_MOB(d)) free_mobile(OLC_MOB(d)); /* * Check for a zone. cleanup_type is irrelevant here, free() everything. */ if (OLC_ZONE(d)) { free(OLC_ZONE(d)->name); free(OLC_ZONE(d)->cmd); free(OLC_ZONE(d)); } /* * Check for a shop. free_shop doesn't perform sanity checks, we must * be careful here. */ if (OLC_SHOP(d)) { switch (cleanup_type) { case CLEANUP_ALL: free_shop(OLC_SHOP(d)); break; case CLEANUP_STRUCTS: free(OLC_SHOP(d)); break; default: /* The caller has screwed up but we already griped above. */ break; } } /* * Restore descriptor playing status. */ if (d->character) { REMOVE_BIT(PLR_FLAGS(d->character), PLR_WRITING); STATE(d) = CON_PLAYING; act("$n stops using OLC.", TRUE, d->character, NULL, NULL, TO_ROOM); } free(d->olc); d->olc = NULL; }