/* $Id: olc_room.c,v 1.666 2004/09/20 10:50:30 shrike Exp $ */
/************************************************************************************
* Copyright 2004 Astrum Metaphora consortium *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
************************************************************************************/
/************************************************************************************
* ANATOLIA 2.1 is copyright 1996-1997 Serdar BULUT, Ibrahim CANPUNAR *
* ANATOLIA has been brought to you by ANATOLIA consortium *
* Serdar BULUT {Chronos} bulut@rorqual.cc.metu.edu.tr *
* Ibrahim Canpunar {Asena} canpunar@rorqual.cc.metu.edu.tr *
* Murat BICER {KIO} mbicer@rorqual.cc.metu.edu.tr *
* D.Baris ACAR {Powerman} dbacar@rorqual.cc.metu.edu.tr *
* By using this code, you have agreed to follow the terms of the *
* ANATOLIA license, in the file Anatolia/anatolia.licence *
***********************************************************************************/
/************************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
************************************************************************************/
/************************************************************************************
* ROM 2.4 is copyright 1993-1995 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@pacinfo.com) *
* Gabrielle Taylor (gtaylor@pacinfo.com) *
* Brian Moore (rom@rom.efn.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
*************************************************************************************/
/************************************************************************************
* Copyright (c) 1998 fjoe <fjoe@iclub.nsu.ru> *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND *
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE *
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *
* SUCH DAMAGE. *
************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "olc.h"
#include "db/db.h"
#define EDIT_ROOM(ch, room) (room = (ROOM_INDEX_DATA*) ch->desc->pEdit)
/*
* Room Editor Prototypes
*/
DECLARE_OLC_FUN(roomed_create );
DECLARE_OLC_FUN(roomed_edit );
DECLARE_OLC_FUN(roomed_touch );
DECLARE_OLC_FUN(roomed_show );
DECLARE_OLC_FUN(roomed_list );
DECLARE_OLC_FUN(roomed_name );
DECLARE_OLC_FUN(roomed_desc );
DECLARE_OLC_FUN(roomed_exd );
DECLARE_OLC_FUN(roomed_north );
DECLARE_OLC_FUN(roomed_south );
DECLARE_OLC_FUN(roomed_east );
DECLARE_OLC_FUN(roomed_west );
DECLARE_OLC_FUN(roomed_up );
DECLARE_OLC_FUN(roomed_down );
DECLARE_OLC_FUN(roomed_mreset );
DECLARE_OLC_FUN(roomed_oreset );
DECLARE_OLC_FUN(roomed_heal );
DECLARE_OLC_FUN(roomed_mana );
DECLARE_OLC_FUN(roomed_clan );
DECLARE_OLC_FUN(roomed_space );
DECLARE_OLC_FUN(roomed_owner );
DECLARE_OLC_FUN(roomed_room );
DECLARE_OLC_FUN(roomed_sector );
DECLARE_OLC_FUN(roomed_reset );
DECLARE_OLC_FUN(roomed_clone );
DECLARE_OLC_FUN(roomed_trigadd );
DECLARE_OLC_FUN(roomed_trigdel );
olc_cmd_t olc_cmds_room[] =
{
/* { command function }, */
{ "create", roomed_create, 5},
{ "edit", roomed_edit, 0},
{ "touch", roomed_touch, 0},
{ "show", roomed_show, 0},
{ "list", roomed_list, 0},
{ "desc", roomed_desc, 0},
{ "exd", roomed_exd, 0},
{ "name", roomed_name, 0},
{ "heal", roomed_heal, 5},
{ "mana", roomed_mana, 5},
{ "clan", roomed_clan, 5},
{ "clone", roomed_clone, 5},
{ "space", roomed_space, 5},
{ "north", roomed_north, 0},
{ "south", roomed_south, 0},
{ "east", roomed_east, 0},
{ "west", roomed_west, 0},
{ "up", roomed_up, 0},
{ "down", roomed_down, 0},
{ "trigadd",roomed_trigadd, 5},
{ "trigDEL",roomed_trigdel, 5},
/* New reset commands. */
{ "mreset", roomed_mreset, 5},
{ "oreset", roomed_oreset, 5},
{ "owner", roomed_owner, 5},
{ "room", roomed_room, 5, room_flags },
{ "sector", roomed_sector, 5, sector_types },
{ "reset", roomed_reset, 0},
{ "commands", show_commands, 0},
{ "version", show_version, 0},
{ NULL}
};
static bool olced_exit(CHAR_DATA *ch, const char *argument,
olc_cmd_t *cmd, int door);
static void add_reset(ROOM_INDEX_DATA *room, RESET_DATA *pReset, int index);
OLC_FUN(roomed_create)
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
int value;
int iHash;
char arg[MAX_STRING_LENGTH];
one_argument(argument, arg, sizeof(arg));
value = atoi(arg);
if (!value)
{
do_help(ch, "'OLC CREATE'");
return FALSE;
}
pArea = area_vnum_lookup(value);
if (!pArea)
{
char_puts("RoomEd: Vnum is not assigned an area.\n", ch);
return FALSE;
}
if (!IS_BUILDER(ch, pArea))
{
char_puts("RoomEd: Insufficient security.\n", ch);
return FALSE;
}
if (get_room_index(value))
{
char_puts("RoomEd: Vnum already exists.\n", ch);
return FALSE;
}
pRoom = new_room_index();
pRoom->area = pArea;
pRoom->vnum = value;
if (value > top_vnum_room)
top_vnum_room = value;
iHash = value % MAX_KEY_HASH;
pRoom->next = room_index_hash[iHash];
room_index_hash[iHash] = pRoom;
ch->desc->pEdit = (void *)pRoom;
OLCED(ch) = olced_lookup(ED_ROOM);
touch_area(pArea);
char_puts("RoomEd: Room created.\n", ch);
return FALSE;
}
OLC_FUN(roomed_edit)
{
char arg[MAX_STRING_LENGTH];
ROOM_INDEX_DATA *pRoom;
one_argument(argument, arg, sizeof(arg));
if (arg[0] == '\0')
pRoom = ch->in_room;
else if (!is_number(arg))
{
do_help(ch, "'OLC EDIT'");
return FALSE;
}
else if ((pRoom = get_room_index(atoi(arg))) == NULL)
{
char_puts("RoomEd: Vnum does not exist.\n", ch);
return FALSE;
}
roomed_edit_room(ch, pRoom, FALSE);
return FALSE;
}
OLC_FUN(roomed_touch)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
return touch_vnum(pRoom->vnum);
}
OLC_FUN(roomed_show)
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_STRING_LENGTH];
ROOM_INDEX_DATA *pRoom;
MPTRIG *rptrig;
BUFFER * output;
OBJ_DATA *obj;
CHAR_DATA *rch;
int door;
bool fcnt;
clan_t *clan;
one_argument(argument, arg, sizeof(arg));
if (arg[0] == '\0')
{
if (IS_EDIT(ch, ED_ROOM))
EDIT_ROOM(ch, pRoom);
else
pRoom = ch->in_room;
}
else if (!is_number(arg))
{
do_help(ch, OLCED(ch) ? "'OLC EDIT'" : "'OLC ASHOW'");
return FALSE;
}
else if ((pRoom = get_room_index(atoi(arg))) == NULL)
{
char_puts("RoomEd: Vnum does not exist.\n", ch);
return FALSE;
}
if (!IS_BUILDER(ch, pRoom->area))
{
char_puts("RoomEd: Insufficient security.\n", ch);
return FALSE;
}
output = buf_new(-1);
buf_add(output, "Description:\n");
mlstr_dump(output, str_empty, pRoom->description);
mlstr_dump(output, "Name: ", pRoom->name);
buf_printf(output, "Area: [%5d] %s\n",
pRoom->area->vnum, pRoom->area->name);
buf_printf(output, "Vnum: [%5d]\nSector: [%s]\nSpace: [%d]\n",
pRoom->vnum, flag_string(sector_types, pRoom->sector_type),
pRoom->space);
if (pRoom->clan && (clan = clan_lookup(pRoom->clan)))
buf_printf(output, "Clan : [%s]\n", clan->name);
buf_printf(output, "Room flags: [%s]\n",
flag_string(room_flags, pRoom->room_flags));
if (pRoom->heal_rate != 100 || pRoom->mana_rate != 100)
buf_printf(output, "Health rec: [%d]\nMana rec : [%d]\n",
pRoom->heal_rate, pRoom->mana_rate);
if (!IS_NULLSTR(pRoom->owner))
buf_printf(output, "Owner : [%s]\n", pRoom->owner);
if (pRoom->ed)
{
ED_DATA *ed;
buf_add(output, "Desc Kwds: [");
for (ed = pRoom->ed; ed != NULL; ed = ed->next)
{
buf_add(output, ed->keyword);
if (ed->next != NULL)
buf_add(output, " ");
}
buf_add(output, "]\n");
}
buf_add(output, "Characters: [");
fcnt = FALSE;
for (rch = pRoom->people; rch != NULL; rch = rch->next_in_room)
{
one_argument(rch->name, buf, sizeof(buf));
buf_add(output, buf);
if (rch->next_in_room != NULL)
buf_add(output, " ");
fcnt = TRUE;
}
if (fcnt)
buf_add(output, "]\n");
else
buf_add(output, "none]\n");
buf_add(output, "Objects: [");
fcnt = FALSE;
for (obj = pRoom->contents; obj != NULL; obj = obj->next_content)
{
one_argument(obj->name, buf, sizeof(buf));
buf_add(output, buf);
if (obj->next_content != NULL)
buf_add(output, " ");
fcnt = TRUE;
}
if (fcnt)
buf_add(output, "]\n");
else
buf_add(output, "none]\n");
for (door = 0; door < MAX_DIR; door++)
{
EXIT_DATA *pexit;
if ((pexit = pRoom->exit[door]) != NULL)
{
char word[MAX_INPUT_LENGTH];
char reset_state[MAX_STRING_LENGTH];
const char *state;
int i, length;
buf_printf(output, "-%-5s to [%5d] Key: [%5d] Size: [%d]",
capitalize(dir_name[door]),
pexit->to_room.r ?
pexit->to_room.r->vnum : 0,
pexit->key, pexit->size);
/*
* Format up the exit info.
* Capitalize all flags that are not part of the reset info.
*/
strnzcpy(reset_state, sizeof(reset_state),
flag_string(exit_flags, pexit->rs_flags));
state = flag_string(exit_flags, pexit->exit_info);
buf_add(output, " Exit flags: [");
for (; ;)
{
state = one_argument(state, word, sizeof(word));
if (word[0] == '\0')
{
buf_add(output, "]\n");
break;
}
if (str_infix(word, reset_state))
{
length = strlen(word);
for (i = 0; i < length; i++)
word[i] = UPPER(word[i]);
}
buf_add(output, word);
buf_add(output, " ");
}
if (!IS_NULLSTR(pexit->keyword))
buf_printf(output, "Kwds: [%s]\n",
pexit->keyword);
mlstr_dump(output, str_empty, pexit->description);
}
}
if (pRoom->rprogs)
{
int cnt = 0;
buf_printf(output, "\nROMPrograms for [%5d]:\n", pRoom->vnum);
for (rptrig = pRoom->rprogs; rptrig; rptrig = rptrig->next)
{
if (cnt ==0)
{
buf_add(output, " Number Vnum Trigger Phrase [Flags]\n");
buf_add(output, " ------ ---- ------- ----------------------------------------------------------\n");
}
buf_printf(output, "[%5d] %4d %7s %s [%s]\n", cnt,
rptrig->vnum, flag_string(rprog_flags, rptrig->type),
rptrig->phrase,
flag_string(rprog_flags, rptrig->flags));
cnt++;
}
}
char_puts(buf_string(output), ch);
buf_free(output);
return FALSE;
}
OLC_FUN(roomed_list)
{
ROOM_INDEX_DATA *pRoomIndex;
AREA_DATA *pArea;
BUFFER *buffer;
bool found;
int vnum;
int col = 0;
if ((pArea = get_edited_area(ch)) == NULL)
pArea = ch->in_room->area;
buffer = buf_new(-1);
found = FALSE;
for (vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++)
{
if ((pRoomIndex = get_room_index(vnum)))
{
found = TRUE;
buf_printf(buffer, "{x[%5d] %s {x",
vnum,
fmt_color_str(mlstr_cval(pRoomIndex->name, ch), 16));
if (++col % 3 == 0)
buf_add(buffer, "\n");
}
}
if (!found)
char_puts("RoomEd: No rooms in this area.\n", ch);
else
{
if (col % 3 != 0)
buf_add(buffer, "\n");
page_to_char(buf_string(buffer), ch);
}
buf_free(buffer);
return FALSE;
}
OLC_FUN(roomed_north)
{
return olced_exit(ch, argument, cmd, DIR_NORTH);
}
OLC_FUN(roomed_south)
{
return olced_exit(ch, argument, cmd, DIR_SOUTH);
}
OLC_FUN(roomed_east)
{
return olced_exit(ch, argument, cmd, DIR_EAST);
}
OLC_FUN(roomed_west)
{
return olced_exit(ch, argument, cmd, DIR_WEST);
}
OLC_FUN(roomed_up)
{
return olced_exit(ch, argument, cmd, DIR_UP);
}
OLC_FUN(roomed_down)
{
return olced_exit(ch, argument, cmd, DIR_DOWN);
}
OLC_FUN(roomed_exd)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
return olced_exd(ch, argument, cmd, &pRoom->ed);
}
OLC_FUN(roomed_name)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
return olced_mlstr(ch, argument, cmd, &pRoom->name);
}
OLC_FUN(roomed_desc)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
return olced_mlstr_text(ch, argument, cmd, &pRoom->description);
}
OLC_FUN(roomed_heal)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
return olced_number(ch, argument, cmd, &pRoom->heal_rate);
}
OLC_FUN(roomed_mana)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
return olced_number(ch, argument, cmd, &pRoom->mana_rate);
}
OLC_FUN(roomed_clan)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
return olced_clan(ch, argument, cmd, &pRoom->clan);
}
#define MAX_MOB 1 /* Default maximum number for resetting mobs */
OLC_FUN(roomed_mreset)
{
ROOM_INDEX_DATA *pRoom;
MOB_INDEX_DATA *pMobIndex;
AREA_DATA *pArea;
CHAR_DATA *newmob;
char arg [ MAX_INPUT_LENGTH ];
char arg2 [ MAX_INPUT_LENGTH ];
RESET_DATA *pReset;
EDIT_ROOM(ch, pRoom);
argument = one_argument(argument, arg, sizeof(arg));
argument = one_argument(argument, arg2, sizeof(arg2));
if (arg[0] == '\0' || !is_number(arg))
{
char_puts ("Syntax: mreset <vnum> <max #x> <min #x>\n", ch);
return FALSE;
}
if (!(pMobIndex = get_mob_index(atoi(arg))))
{
char_puts("RoomEd: No mobile has that vnum.\n", ch);
return FALSE;
}
pArea = area_vnum_lookup(pMobIndex->vnum);
if (pArea != pRoom->area)
{
char_puts("RoomEd: No such mobile in this area.\n", ch);
return FALSE;
}
/*
* Create the mobile reset.
*/
pReset = new_reset_data();
pReset->command = 'M';
pReset->arg1 = pMobIndex->vnum;
pReset->arg2 = is_number(arg2) ? atoi(arg2) : MAX_MOB;
pReset->arg3 = pRoom->vnum;
pReset->arg4 = is_number(argument) ? atoi (argument) : 1;
add_reset(pRoom, pReset, 0/* Last slot*/);
/*
* Create the mobile.
*/
newmob = create_mob(pMobIndex);
char_printf(ch, "%s (%d) has been loaded and added to resets.\n"
"There will be a maximum of %d loaded to this room.\n",
mlstr_mval(pMobIndex->short_descr),
pMobIndex->vnum,
pReset->arg2);
act("$n has created $N!", ch, NULL, newmob, TO_ROOM);
char_to_room(newmob, pRoom);
return TRUE;
}
struct wear_type
{
int wear_loc;
int wear_bit;
};
const struct wear_type wear_table[] =
{
{ WEAR_NONE, ITEM_TAKE},
{ WEAR_LIGHT, ITEM_LIGHT},
{ WEAR_FINGER_L, ITEM_WEAR_FINGER},
{ WEAR_FINGER_R, ITEM_WEAR_FINGER},
{ WEAR_NECK_1, ITEM_WEAR_NECK},
{ WEAR_EAR, ITEM_WEAR_EAR},
{ WEAR_BODY, ITEM_WEAR_BODY},
{ WEAR_HEAD, ITEM_WEAR_HEAD},
{ WEAR_LEGS, ITEM_WEAR_LEGS},
{ WEAR_FEET, ITEM_WEAR_FEET},
{ WEAR_HANDS, ITEM_WEAR_HANDS},
{ WEAR_ARMS, ITEM_WEAR_ARMS},
{ WEAR_SHIELD, ITEM_WEAR_SHIELD},
{ WEAR_ABOUT, ITEM_WEAR_ABOUT},
{ WEAR_WAIST, ITEM_WEAR_WAIST},
{ WEAR_WRIST_L, ITEM_WEAR_WRIST},
{ WEAR_WRIST_R, ITEM_WEAR_WRIST},
{ WEAR_WIELD, ITEM_WIELD},
{ WEAR_HOLD, ITEM_HOLD},
{ WEAR_FLOAT, ITEM_WEAR_FLOAT},
{ WEAR_TATTOO, ITEM_WEAR_TATTOO},
{ WEAR_SECOND_WIELD, ITEM_WIELD},
{ WEAR_STUCK_IN, ITEM_WIELD},
{ WEAR_CLANMARK, ITEM_WEAR_CLANMARK},
{ WEAR_PLUG_IN, ITEM_WEAR_PLUG_IN},
{ WEAR_TAIL, ITEM_WEAR_TAIL},
{ WEAR_FACE, ITEM_WEAR_FACE},
{ MAX_WEAR}
};
/*****************************************************************************
Name: wear_loc
Purpose: Returns the location of the bit that matches the count.
1 = first match, 2 = second match etc.
Called by: objed_reset(olc_act.c).
****************************************************************************/
int wear_loc(int bits, int count)
{
int flag;
for (flag = 0; wear_table[flag].wear_loc != MAX_WEAR; flag++)
{
if (IS_SET(bits, wear_table[flag].wear_bit) && --count < 1)
return wear_table[flag].wear_loc;
}
return -1;
}
/*****************************************************************************
Name: wear_bit
Purpose: Converts a wear_loc into a bit.
Called by: roomed_oreset(olc_act.c).
****************************************************************************/
int wear_bit(int loc)
{
int flag;
for (flag = 0; wear_table[flag].wear_loc != MAX_WEAR; flag++)
{
if (loc == wear_table[flag].wear_loc)
return wear_table[flag].wear_bit;
}
return 0;
}
OLC_FUN(roomed_oreset)
{
ROOM_INDEX_DATA *pRoom;
OBJ_INDEX_DATA *pObjIndex;
AREA_DATA *pArea;
OBJ_DATA *newobj;
OBJ_DATA *to_obj;
CHAR_DATA *to_mob;
char arg1 [ MAX_INPUT_LENGTH ];
char arg2 [ MAX_INPUT_LENGTH ];
int olevel = 0;
RESET_DATA *pReset;
EDIT_ROOM(ch, pRoom);
argument = one_argument(argument, arg1, sizeof(arg1));
argument = one_argument(argument, arg2, sizeof(arg2));
if (arg1[0] == '\0' || !is_number(arg1))
{
char_puts ("Syntax: oreset <vnum> <args>\n", ch);
char_puts (" -no_args = into room\n", ch);
char_puts (" -<obj_name> = into obj\n", ch);
char_puts (" -<mob_name> <wear_loc> = into mob\n", ch);
return FALSE;
}
if (!(pObjIndex = get_obj_index(atoi(arg1))))
{
char_puts("RoomEd: No object has that vnum.\n", ch);
return FALSE;
}
pArea = area_vnum_lookup(pObjIndex->vnum);
if (pArea != pRoom->area)
{
char_puts("RoomEd: No such object in this area.\n", ch);
return FALSE;
}
if (pObjIndex->limit != -1 && ch->pcdata->security < SEC_LOAD_LIMIT)
{
char_puts("RoomEd: Insufficient security.\n", ch);
return FALSE;
}
/*
* Load into room.
*/
if (arg2[0] == '\0')
{
pReset = new_reset_data();
pReset->command = 'O';
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = 0;
pReset->arg3 = pRoom->vnum;
pReset->arg4 = 0;
add_reset(pRoom, pReset, 0/* Last slot*/);
newobj = create_obj(pObjIndex, number_fuzzy(olevel));
obj_to_room(newobj, pRoom);
char_printf(ch, "%s (%d) has been loaded and added to resets.\n",
mlstr_mval(pObjIndex->short_descr),
pObjIndex->vnum);
}
else
/*
* Load into object's inventory.
*/
if (argument[0] == '\0'
&& ((to_obj = get_obj_list(ch, arg2, pRoom->contents)) != NULL))
{
pReset = new_reset_data();
pReset->command = 'P';
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = 0;
pReset->arg3 = to_obj->pIndexData->vnum;
pReset->arg4 = 1;
add_reset(pRoom, pReset, 0/* Last slot*/);
newobj = create_obj(pObjIndex, number_fuzzy(olevel));
newobj->cost = 0;
obj_to_obj(newobj, to_obj);
char_printf(ch, "%s (%d) has been loaded into "
"%s (%d) and added to resets.\n",
mlstr_mval(newobj->short_descr),
newobj->pIndexData->vnum,
mlstr_mval(to_obj->short_descr),
to_obj->pIndexData->vnum);
}
else
/*
* Load into mobile's inventory.
*/
if ((to_mob = get_char_room(ch, arg2)) != NULL)
{
int wear_loc;
if (!str_cmp(argument, "?"))
{
show_flags(ch, wear_loc_flags);
return FALSE;
}
wear_loc = flag_value(wear_loc_flags, argument);
/*
* Disallow loading a sword(WEAR_WIELD) into WEAR_HEAD.
*/
if (!IS_SET(pObjIndex->wear_flags, wear_bit(wear_loc)))
{
char_printf(ch, "%s (%d) has wear flags: [%s]\n",
mlstr_mval(pObjIndex->short_descr),
pObjIndex->vnum,
flag_string(wear_flags,
pObjIndex->wear_flags));
return FALSE;
}
/*
* Can't load into same position.
*/
if (get_eq_char(to_mob, wear_loc))
{
char_puts("RoomEd: Object already equipped.\n", ch);
return FALSE;
}
pReset = new_reset_data();
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = wear_loc;
if (pReset->arg2 == WEAR_NONE)
pReset->command = 'G';
else
pReset->command = 'E';
pReset->arg3 = wear_loc;
add_reset(pRoom, pReset, 0/* Last slot*/);
olevel = URANGE(0, to_mob->level - 2, LEVEL_HERO);
newobj = create_obj(pObjIndex, number_fuzzy(olevel));
if (to_mob->pIndexData->pShop)
{ /* Shop-keeper? */
switch (pObjIndex->item_type)
{
default: olevel = 0; break;
case ITEM_PILL: olevel = number_range( 0, 10); break;
case ITEM_POTION:olevel = number_range( 0, 10); break;
case ITEM_SCROLL:olevel = number_range( 5, 15); break;
case ITEM_WAND: olevel = number_range(10, 20); break;
case ITEM_STAFF:olevel = number_range(15, 25); break;
case ITEM_ARMOR:olevel = number_range( 5, 15); break;
case ITEM_WEAPON: if (pReset->command == 'G')
olevel = number_range(5, 15);
else
olevel = number_fuzzy(olevel);
break;
}
newobj = create_obj(pObjIndex, olevel);
if (pReset->arg2 == WEAR_NONE)
SET_BIT(newobj->extra_flags, ITEM_INVENTORY);
}
else
newobj = create_obj(pObjIndex, number_fuzzy(olevel));
obj_to_char(newobj, to_mob);
if (pReset->command == 'E')
equip_char(to_mob, newobj, pReset->arg3);
char_printf(ch, "%s (%d) has been loaded "
"%s of %s (%d) and added to resets.\n",
mlstr_mval(pObjIndex->short_descr),
pObjIndex->vnum,
flag_string(wear_loc_strings, pReset->arg3),
mlstr_mval(to_mob->short_descr),
to_mob->pIndexData->vnum);
}
else /* Display Syntax */
{
char_puts("RoomEd: That mobile isn't here.\n", ch);
return FALSE;
}
act("$n has created $p!", ch, newobj, NULL, TO_ROOM);
wiznet("$N loads $p.", ch, newobj, WIZ_LOAD, WIZ_SECURE, ch->level);
log_printf("Log %s: OLoad: obj: %d",
ch->name, newobj->pIndexData->vnum);
return TRUE;
}
OLC_FUN(roomed_room)
{
ROOM_INDEX_DATA *room;
EDIT_ROOM(ch, room);
return olced_flag64(ch, argument, cmd, &room->room_flags);
}
OLC_FUN(roomed_sector)
{
ROOM_INDEX_DATA *room;
EDIT_ROOM(ch, room);
return olced_flag64(ch, argument, cmd, &room->sector_type);
}
OLC_FUN(roomed_owner)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
if (argument[0] == '\0')
{
char_puts("Syntax: owner [owner]\n", ch);
char_puts(" owner none\n", ch);
return FALSE;
}
free_string(pRoom->owner);
if (!str_cmp(argument, "none"))
pRoom->owner = str_dup(str_empty);
else
pRoom->owner = str_dup(argument);
char_puts("Owner set.\n", ch);
return TRUE;
}
OLC_FUN(roomed_reset)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
reset_room(pRoom);
char_puts("RoomEd: Room reset.\n", ch);
return FALSE;
}
OLC_FUN(roomed_clone)
{
ROOM_INDEX_DATA *room;
ROOM_INDEX_DATA *proto;
char arg[MAX_INPUT_LENGTH];
int i;
bool fAll = FALSE;
argument = one_argument(argument, arg, sizeof(arg));
if (!str_cmp(arg, "all"))
{
fAll = TRUE;
argument = one_argument(argument, arg, sizeof(arg));
}
if (!is_number(arg))
{
do_help(ch, "'OLC ROOM CLONE'");
return FALSE;
}
i = atoi(arg);
if ((proto = get_room_index(i)) == NULL)
{
char_printf(ch, "RoomEd: %d: Vnum does not exist.\n", i);
return FALSE;
}
if (!IS_BUILDER(ch, proto->area))
{
char_puts("RoomEd: Insufficient security.\n", ch);
return FALSE;
}
EDIT_ROOM(ch, room);
if (room == proto)
{
char_puts("RoomEd: Huh, cloning from self?\n", ch);
return FALSE;
}
mlstr_free(room->name);
room->name = mlstr_dup(proto->name);
mlstr_free(room->description);
room->description = mlstr_dup(proto->description);
if (fAll)
{
ed_free(room->ed);
room->ed = ed_dup(proto->ed);
free_string(room->owner);
room->owner = str_dup(proto->owner);
room->room_flags = proto->room_flags;
room->sector_type = proto->sector_type;
room->heal_rate = proto->heal_rate;
room->mana_rate = proto->mana_rate;
room->clan = proto->clan;
}
return TRUE;
}
void roomed_edit_room(CHAR_DATA *ch, ROOM_INDEX_DATA *pRoom, bool drop_out)
{
AREA_DATA *pArea = area_vnum_lookup(pRoom->vnum);
if (!IS_BUILDER(ch, pArea))
{
char_puts("RoomEd: Insufficient security.\n", ch);
if (drop_out)
edit_done(ch->desc);
return;
}
ch->desc->pEdit = (void*) pRoom;
OLCED(ch) = olced_lookup(ED_ROOM);
}
static bool olced_exit(CHAR_DATA *ch, const char *argument, olc_cmd_t *cmd, int door)
{
ROOM_INDEX_DATA *pRoom;
char command[MAX_INPUT_LENGTH];
char arg[MAX_INPUT_LENGTH];
int value;
AREA_DATA *eArea;
EDIT_ROOM(ch, pRoom);
/*
* Set the exit flags, needs full argument.
* ----------------------------------------
*/
if ((value = flag_value(exit_flags, argument)) != 0)
{
ROOM_INDEX_DATA *pToRoom;
int rev; /* ROM OLC */
if (!pRoom->exit[door])
{
char_puts("Exit does not exist.\n",ch);
return FALSE;
}
/* pRoom->exit[door] = new_exit(); */
/*
* This room.
*/
TOGGLE_BIT(pRoom->exit[door]->rs_flags, value);
/*
* Don't toggle exit_info because it can be
* changed by players.
*/
pRoom->exit[door]->exit_info = pRoom->exit[door]->rs_flags;
/*
* Connected room.
*/
rev = rev_dir[door];
pToRoom = pRoom->exit[door]->to_room.r; /* ROM OLC */
if (pToRoom && pToRoom->exit[rev] != NULL)
{
TOGGLE_BIT(pToRoom->exit[rev]->rs_flags, value);
TOGGLE_BIT(pToRoom->exit[rev]->exit_info, value);
}
char_puts("Exit flag toggled.\n", ch);
return TRUE;
}
/*
* Now parse the arguments.
*/
argument = one_argument(argument, command, sizeof(command));
argument = one_argument(argument, arg, sizeof(arg));
if (command[0] == '\0' && argument[0] == '\0')
{ /* Move command. */
move_char(ch, door, TRUE); /* ROM OLC */
return FALSE;
}
if (command[0] == '?')
{
BUFFER *output;
output = buf_new(-1);
help_show(ch, output, "'OLC EXITS'");
buf_printf(output, "Valid exit flags are:\n");
show_flags_buf(output, exit_flags);
page_to_char(buf_string(output), ch);
buf_free(output);
return FALSE;
}
if (!str_cmp(command, "delete"))
{
ROOM_INDEX_DATA *pToRoom;
int rev; /* ROM OLC */
if (!pRoom->exit[door])
{
char_puts("RoomEd: Cannot delete a null exit.\n", ch);
return FALSE;
}
/*
* Remove ToRoom Exit.
*/
rev = rev_dir[door];
pToRoom = pRoom->exit[door]->to_room.r; /* ROM OLC */
if (pToRoom && pToRoom->exit[rev])
{
free_exit(pToRoom->exit[rev]);
pToRoom->exit[rev] = NULL;
}
/*
* Remove this exit.
*/
free_exit(pRoom->exit[door]);
pRoom->exit[door] = NULL;
char_puts("Exit unlinked.\n", ch);
/*
* Check toggled exit on another area
*/
eArea = area_vnum_lookup(pRoom->vnum);
if (pToRoom->vnum < eArea->min_vnum || pToRoom->vnum > eArea->max_vnum)
{
eArea = area_vnum_lookup(pToRoom->vnum);
SET_BIT(eArea->flags, AREA_CHANGED);
char_printf(ch, "Toggled changed flag for area %s.\n",eArea->name );
}
return TRUE;
}
if (!str_cmp(command, "link"))
{
EXIT_DATA *pExit;
ROOM_INDEX_DATA *pToRoom;
if (arg[0] == '\0' || !is_number(arg))
{
do_help(ch, "'OLC EXITS'");
return FALSE;
}
value = atoi(arg);
if ((pToRoom = get_room_index(value)) == NULL)
{
char_puts("RoomEd: Cannot link to non-existant room.\n", ch);
return FALSE;
}
if (!IS_BUILDER(ch, pToRoom->area))
{
char_puts("RoomEd: Cannot link to that area.\n", ch);
return FALSE;
}
if (pToRoom->exit[rev_dir[door]])
{
char_puts("RoomEd: Remote side's exit already exists.\n", ch);
return FALSE;
}
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
pRoom->exit[door]->to_room.r = pToRoom;
pRoom->exit[door]->orig_door = door;
door = rev_dir[door];
pExit = new_exit();
pExit->to_room.r = pRoom;
pExit->orig_door = door;
pToRoom->exit[door] = pExit;
char_puts("Two-way link established.\n", ch);
/*
* Check toggled exit on another area
*/
eArea = area_vnum_lookup(pRoom->vnum);
if (pToRoom->vnum < eArea->min_vnum || pToRoom->vnum > eArea->max_vnum)
{
eArea = area_vnum_lookup(pToRoom->vnum);
SET_BIT(eArea->flags, AREA_CHANGED);
char_printf(ch, "Toggled changed flag for area %s.\n",eArea->name );
}
return TRUE;
}
if (!str_cmp(command, "dig"))
{
char buf[MAX_STRING_LENGTH];
if (arg[0] == '\0' || !is_number(arg))
{
char_printf(ch, "Syntax: %s dig <vnum>\n",
cmd->name);
return FALSE;
}
roomed_create(ch, arg, cmd);
ch->desc->pEdit = pRoom;
snprintf(buf, sizeof(buf), "link %s", arg);
olced_exit(ch, buf, cmd, door);
return TRUE;
}
if (!str_cmp(command, "size"))
{
if (arg[0] == '\0' || !is_number(arg))
{
char_printf(ch, "Syntax: %s size <number>\n",
cmd->name);
return FALSE;
}
if (!pRoom->exit[door])
{
char_puts("RoomEd: Exit does not exist.\n",ch);
return FALSE;
}
value = atoi(arg);
if (value < SIZE_TINY_MIN || value > SIZE_GARGANTUAN_MAX)
{
char_puts("RoomEd: Incorrect exit size.\n", ch);
return FALSE;
}
pRoom->exit[door]->size = value;
char_puts("Exit size set.\n", ch);
return TRUE;
}
if (!str_cmp(command, "room"))
{
ROOM_INDEX_DATA *pToRoom;
if (arg[0] == '\0' || !is_number(arg))
{
char_printf(ch, "Syntax: %s room [vnum]\n", cmd->name);
return FALSE;
}
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
value = atoi(arg);
if (!(pToRoom = get_room_index(value)))
{
char_puts("RoomEd: Cannot link to non-existant room.\n", ch);
return FALSE;
}
if (!IS_BUILDER(ch, pToRoom->area))
{
char_puts("RoomEd: Cannot link to that area.\n", ch);
return FALSE;
}
pRoom->exit[door]->to_room.r = pToRoom;
pRoom->exit[door]->orig_door = door;
char_puts("One-way link established.\n", ch);
/*
* Check toggled exit on another area
*/
eArea = area_vnum_lookup(pRoom->vnum);
if (pToRoom->vnum < eArea->min_vnum || pToRoom->vnum > eArea->max_vnum)
{
eArea = area_vnum_lookup(pToRoom->vnum);
SET_BIT(eArea->flags, AREA_CHANGED);
char_printf(ch, "Toggled changed flag for area %s.\n",eArea->name );
}
return TRUE;
}
if (!str_cmp(command, "key"))
{
OBJ_INDEX_DATA *key;
if (arg[0] == '\0' || !is_number(arg))
{
char_printf(ch, "Syntax: %s key [vnum]\n",
cmd->name);
return FALSE;
}
if (!pRoom->exit[door])
{
char_puts("RoomEd: Exit does not exist.\n",ch);
return FALSE;
}
value = atoi(arg);
if ((key = get_obj_index(value)) == NULL)
{
char_puts("RoomEd: Obj doesn't exist.\n", ch);
return FALSE;
}
if (key->item_type != ITEM_KEY)
{
char_puts("RoomEd: That obj is not key.\n", ch);
return FALSE;
}
pRoom->exit[door]->key = value;
char_puts("Exit key set.\n", ch);
return TRUE;
}
if (!str_cmp(command, "name"))
{
if (arg[0] == '\0')
{
char_printf(ch, "Syntax: %s name [string]\n"
" %s name none\n",
cmd->name, cmd->name);
return FALSE;
}
if (!pRoom->exit[door])
{
char_puts("RoomEd: Exit does not exist.\n",ch);
return FALSE;
}
free_string(pRoom->exit[door]->keyword);
if (!str_cmp(arg, "none"))
pRoom->exit[door]->keyword = str_dup(str_empty);
else
pRoom->exit[door]->keyword = str_dup(arg);
char_puts("Exit name set.\n", ch);
return TRUE;
}
if (!str_prefix(command, "description"))
{
if (!pRoom->exit[door])
{
char_puts("RoomEd: Exit does not exist.\n",ch);
return FALSE;
}
if (!mlstr_append(ch, &pRoom->exit[door]->description, arg))
{
char_printf(ch, "Syntax: %s desc lang\n", cmd->name);
return FALSE;
}
return TRUE;
}
return FALSE;
}
void display_resets(CHAR_DATA *ch)
{
ROOM_INDEX_DATA *pRoom = ch->in_room;
RESET_DATA *pReset;
MOB_INDEX_DATA *pMob = NULL;
BUFFER * buf;
int iReset = 0;
buf = buf_new(-1);
buf_add(buf,
"{x No. Loads Description Location Vnum Mx Mn Description"
"\n"
"==== ======== ============= =================== ======== ===== ==========="
"\n");
for (pReset = pRoom->reset_first; pReset; pReset = pReset->next)
{
OBJ_INDEX_DATA *pObj;
MOB_INDEX_DATA *pMobIndex;
OBJ_INDEX_DATA *pObjIndex;
OBJ_INDEX_DATA *pObjToIndex;
ROOM_INDEX_DATA *pRoomIndex;
char *start = buf_string(buf);
buf_printf(buf, "[%2d] ", ++iReset);
switch (pReset->command)
{
default:
buf_printf(buf, "Bad reset command: %c.", pReset->command);
break;
case 'M':
if (!(pMobIndex = get_mob_index(pReset->arg1)))
{
buf_printf(buf, "Load Mobile - Bad Mob %d\n", pReset->arg1);
continue;
}
if (!(pRoomIndex = get_room_index(pReset->arg3)))
{
buf_printf(buf, "Load Mobile - Bad Room %d\n", pReset->arg3);
continue;
}
pMob = pMobIndex;
buf_printf(buf, "M[%5d] %s {xin room R[%5d] %2d-%2d %s{x\n",
pReset->arg1, fmt_color_str(mlstr_mval(pMob->short_descr), 13),
pReset->arg3, pReset->arg2, pReset->arg4,
fmt_color_str(mlstr_cval(pRoomIndex->name, ch), 15));
/*
* Check for pet shop.
* -------------------
*/
{
ROOM_INDEX_DATA *pRoomIndexPrev;
pRoomIndexPrev = get_room_index(pRoomIndex->vnum - 1);
if (pRoomIndexPrev
&& IS_SET(pRoomIndexPrev->room_flags, ROOM_PET_SHOP))
start[5] = 'P';
}
break;
case 'O':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
buf_printf(buf, "Load Object - Bad Object %d\n",
pReset->arg1);
continue;
}
pObj = pObjIndex;
if (!(pRoomIndex = get_room_index(pReset->arg3)))
{
buf_printf(buf, "Load Object - Bad Room %d\n", pReset->arg3);
continue;
}
buf_printf(buf, "O[%5d] %s {xin room "
"R[%5d] %s{x\n",
pReset->arg1, fmt_color_str(mlstr_mval(pObj->short_descr), 13),
pReset->arg3, fmt_color_str(mlstr_mval(pRoomIndex->name), 15));
break;
case 'P':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
buf_printf(buf, "Put Object - Bad Object %d\n",
pReset->arg1);
continue;
}
pObj = pObjIndex;
if (!(pObjToIndex = get_obj_index(pReset->arg3)))
{
buf_printf(buf, "Put Object - Bad To Object %d\n",
pReset->arg3);
continue;
}
buf_printf(buf,
"O[%5d] %s {xinside O[%5d] %2d-%2d %s{x\n",
pReset->arg1,
fmt_color_str(mlstr_mval(pObj->short_descr), 13),
pReset->arg3,
pReset->arg2,
pReset->arg4,
fmt_color_str(mlstr_mval(pObjToIndex->short_descr), 15));
break;
case 'G':
case 'E':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
buf_printf(buf, "Give/Equip Object - Bad Object %d\n",
pReset->arg1);
continue;
}
pObj = pObjIndex;
if (!pMob)
{
buf_printf(buf, "Give/Equip Object - No Previous Mobile\n");
break;
}
if (pMob->pShop)
{
buf_printf(buf,
"O[%5d] %s {xin the inventory of S[%5d] %s{x\n",
pReset->arg1,
fmt_color_str(mlstr_mval(pObj->short_descr), 13),
pMob->vnum,
fmt_color_str(mlstr_mval(pMob->short_descr), 15));
}
else
buf_printf(buf,
"O[%5d] %s{x %-19.19s M[%5d] %s{x\n",
pReset->arg1,
fmt_color_str(mlstr_mval(pObj->short_descr), 13),
(pReset->command == 'G') ?
flag_string(wear_loc_strings, WEAR_NONE)
: flag_string(wear_loc_strings, pReset->arg3),
pMob->vnum,
fmt_color_str(mlstr_mval(pMob->short_descr), 15));
break;
/*
* Doors are set in rs_flags don't need to be displayed.
* If you want to display them then uncomment the new_reset
* line in the case 'D' in load_resets in db.c and here.
*/
case 'D':
pRoomIndex = get_room_index(pReset->arg1);
buf_printf(buf, "R[%5d] %s {xdoor of %s{x reset to %s\n",
pReset->arg1,
capitalize(dir_name[pReset->arg2]),
fmt_color_str(mlstr_cval(pRoomIndex->name, ch), 19),
flag_string(door_resets, pReset->arg3));
break;
/*
* End Doors Comment.
*/
case 'R':
if (!(pRoomIndex = get_room_index(pReset->arg1)))
{
buf_printf(buf, "Randomize Exits - Bad Room %d\n",
pReset->arg1);
continue;
}
buf_printf(buf, "R[%5d] Exits are randomized in %s{x\n",
pReset->arg1, mlstr_cval(pRoomIndex->name, ch));
break;
}
}
char_puts(buf_string(buf), ch);
buf_free(buf);
}
DO_FUN(do_resets)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char arg4[MAX_INPUT_LENGTH];
char arg5[MAX_INPUT_LENGTH];
char arg6[MAX_INPUT_LENGTH];
char arg7[MAX_INPUT_LENGTH];
RESET_DATA *pReset = NULL;
ROOM_INDEX_DATA *pRoom = ch->in_room;
argument = one_argument(argument, arg1, sizeof(arg1));
argument = one_argument(argument, arg2, sizeof(arg2));
argument = one_argument(argument, arg3, sizeof(arg3));
argument = one_argument(argument, arg4, sizeof(arg4));
argument = one_argument(argument, arg5, sizeof(arg5));
argument = one_argument(argument, arg6, sizeof(arg6));
argument = one_argument(argument, arg7, sizeof(arg7));
if (!IS_BUILDER(ch, pRoom->area))
{
char_puts("Resets: Invalid security for editing this area.\n",
ch);
return;
}
/*
* Display resets in current room.
* -------------------------------
*/
if (arg1[0] == '\0')
{
if (pRoom->reset_first)
{
char_puts(
"Resets: M = mobile, R = room, O = object, "
"P = pet, S = shopkeeper\n", ch);
display_resets(ch);
}
else
char_puts("No resets in this room.\n", ch);
}
/*
* Take index number and search for commands.
* ------------------------------------------
*/
if (is_number(arg1))
{
/*
* Delete a reset.
* ---------------
*/
if (!str_cmp(arg2, "delete"))
{
int insert_loc = atoi(arg1);
if (!pRoom->reset_first)
{
char_puts("No resets in this area.\n", ch);
return;
}
if (insert_loc-1 <= 0)
{
pReset = pRoom->reset_first;
pRoom->reset_first = pRoom->reset_first->next;
if (!pRoom->reset_first)
pRoom->reset_last = NULL;
}
else
{
int iReset = 0;
RESET_DATA *prev = NULL;
for (pReset = pRoom->reset_first; pReset; pReset = pReset->next)
{
if (++iReset == insert_loc)
break;
prev = pReset;
}
if (!pReset)
{
char_puts("Reset not found.\n", ch);
return;
}
if (prev)
prev->next = prev->next->next;
else
pRoom->reset_first = pRoom->reset_first->next;
for (pRoom->reset_last = pRoom->reset_first;
pRoom->reset_last->next;
pRoom->reset_last = pRoom->reset_last->next);
}
free_reset_data(pReset);
touch_area(pRoom->area);
char_puts("Reset deleted.\n", ch);
}
else
/*
* Add a reset.
* ------------
*/
if ((!str_cmp(arg2, "mob") && is_number(arg3))
|| (!str_cmp(arg2, "obj") && is_number(arg3)))
{
/*
* Check for Mobile reset.
* -----------------------
*/
if (!str_cmp(arg2, "mob"))
{
if (get_mob_index(is_number(arg3) ? atoi(arg3) : 1) == NULL)
{
char_puts("Mob doesn't exists.\n",ch);
return;
}
pReset = new_reset_data();
pReset->command = 'M';
pReset->arg1 = atoi(arg3);
pReset->arg2 = is_number(arg4) ? atoi(arg4) : 1; /* Max # */
pReset->arg3 = pRoom->vnum;
pReset->arg4 = is_number(arg5) ? atoi(arg5) : 1; /* Min # */
}
else
/*
* Check for Object reset.
* -----------------------
*/
if (!str_cmp(arg2, "obj"))
{
OBJ_INDEX_DATA *reset_obj;
if ((reset_obj = get_obj_index(atoi(arg3))) == NULL)
{
char_puts("Vnum doesn't exists.\n",ch);
return;
}
if (reset_obj->limit != -1 && ch->pcdata->security < SEC_LOAD_LIMIT)
{
char_puts("Reset: Insufficient security.\n", ch);
return;
}
pReset = new_reset_data();
pReset->arg1 = atoi(arg3);
/*
* Inside another object.
* ----------------------
*/
if (!str_prefix(arg4, "inside"))
{
OBJ_INDEX_DATA *temp;
temp = get_obj_index(is_number(arg5) ? atoi(arg5) : 1);
if ((temp->item_type != ITEM_CONTAINER) &&
(temp->item_type != ITEM_CORPSE_NPC))
{
char_puts("Object 2 is not a container.\n", ch);
return;
}
pReset->command = 'P';
pReset->arg2 = is_number(arg6) ? atoi(arg6) : 1;
pReset->arg3 = is_number(arg5) ? atoi(arg5) : 1;
pReset->arg4 = is_number(arg7) ? atoi(arg7) : 1;
}
else
/*
* Inside the room.
* ----------------
*/
if (!str_cmp(arg4, "room"))
{
if (get_obj_index(atoi(arg3)) == NULL)
{
char_puts("Vnum doesn't exists.\n",ch);
return;
}
pReset->command = 'O';
pReset->arg2 = 0;
pReset->arg3 = pRoom->vnum;
pReset->arg4 = 0;
}
else
{
/*
* Into a Mobile's inventory.
* --------------------------
*/
int loc = WEAR_NONE;
int vnum;
if (str_prefix(arg4, "none")
&& str_prefix(arg4, "inventory")
&& (loc = flag_value(wear_loc_flags, arg4)) < 0)
{
show_flags(ch, wear_loc_flags);
return;
}
if (get_obj_index(vnum = atoi(arg3)) == NULL)
{
char_puts("Vnum doesn't exists.\n",ch);
return;
}
pReset->arg1 = vnum;
pReset->arg3 = loc;
if (pReset->arg3 == WEAR_NONE)
pReset->command = 'G';
else
pReset->command = 'E';
}
}
add_reset(pRoom, pReset, atoi(arg1));
touch_area(pRoom->area);
char_puts("Reset added.\n", ch);
log_printf("Log %s: Reset: room: %d, obj: %s",
ch->name, pRoom->vnum, arg3);
}
else
if (!str_cmp(arg2, "random") && is_number(arg3))
{
if (atoi(arg3) < 1 || atoi(arg3) > 6)
{
char_puts("Invalid argument.\n", ch);
return;
}
pReset = new_reset_data ();
pReset->command = 'R';
pReset->arg1 = pRoom->vnum;
pReset->arg2 = atoi(arg3);
add_reset(pRoom, pReset, atoi(arg1));
touch_area(pRoom->area);
char_puts("Random exits reset added.\n", ch);
}
else
{
char_puts("Syntax: RESET <number> OBJ <vnum> <wear_loc>\n", ch);
char_puts(" RESET <number> OBJ <vnum> inside <vnum> [limit] [count]\n", ch);
char_puts(" RESET <number> OBJ <vnum> room\n", ch);
char_puts(" RESET <number> MOB <vnum> [max #x area] [max #x room]\n", ch);
char_puts(" RESET <number> DELETE\n", ch);
char_puts(" RESET <number> RANDOM [#x exits]\n", ch);
}
}
}
/* Static functions */
/*****************************************************************************
Name: add_reset
Purpose: Inserts a new reset in the given index slot.
Called by: do_resets(olc.c).
****************************************************************************/
static void add_reset(ROOM_INDEX_DATA *room, RESET_DATA *pReset, int index)
{
RESET_DATA *reset;
int iReset = 0;
if (!room->reset_first)
{
room->reset_first = pReset;
room->reset_last = pReset;
pReset->next = NULL;
return;
}
index--;
if (index == 0) /* First slot (1) selected. */
{
pReset->next = room->reset_first;
room->reset_first = pReset;
return;
}
/*
* If negative slot(<= 0 selected) then this will find the last.
*/
for (reset = room->reset_first; reset->next; reset = reset->next)
{
if (++iReset == index)
break;
}
pReset->next = reset->next;
reset->next = pReset;
if (!pReset->next)
room->reset_last = pReset;
return;
}
OLC_FUN(roomed_space)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
return olced_number(ch, argument, cmd, &pRoom->space);
}
OLC_FUN(roomed_trigadd)
{
int value;
ROOM_INDEX_DATA *pRoom;
MPTRIG *rptrig;
MPCODE *rpcode;
char trigger[MAX_STRING_LENGTH];
char num[MAX_STRING_LENGTH];
EDIT_ROOM(ch, pRoom);
argument = one_argument(argument, num, sizeof(num));
argument = one_argument(argument, trigger, sizeof(trigger));
if (!str_cmp(num, "?"))
{
show_flags(ch, rprog_flags);
return FALSE;
}
if (!is_number(num) || trigger[0] =='\0' || argument[0] =='\0')
{
char_puts("Syntax: trigadd [vnum] [trigger] [phrase]\n",ch);
return FALSE;
}
if ((value = flag_value(rprog_flags, trigger)) < 0)
{
char_puts("Invalid trigger type.\n"
"Use 'trigadd ?' for list of triggers.\n", ch);
return FALSE;
}
if ((rpcode = rpcode_lookup(atoi(num))) == NULL)
{
char_puts("No such ROOMProgram.\n", ch);
return FALSE;
}
rptrig = rptrig_new(value, argument, atoi(num));
rptrig_add(pRoom, rptrig);
char_puts("Trigger added.\n",ch);
return TRUE;
}
OLC_FUN(roomed_trigdel)
{
ROOM_INDEX_DATA *pRoom;
MPTRIG *rptrig;
MPTRIG *rptrig_next;
char rprog[MAX_STRING_LENGTH];
int value;
int cnt = 0;
EDIT_ROOM(ch, pRoom);
one_argument(argument, rprog, sizeof(rprog));
if (!is_number(rprog) || rprog[0] == '\0')
{
char_puts("Syntax: trigdel [#rprog]\n",ch);
return FALSE;
}
value = atoi (rprog);
if (value < 0)
{
char_puts("Only non-negative rprog-numbers allowed.\n",ch);
return FALSE;
}
if (!(rptrig = pRoom->rprogs))
{
char_puts("RoomEd: Nonexistent trigger.\n",ch);
return FALSE;
}
if (value == 0)
{
REMOVE_BIT(pRoom->rprog_flags, pRoom->rprogs->type);
rptrig = pRoom->rprogs;
pRoom->rprogs = rptrig->next;
rptrig_free(rptrig);
}
else {
while ((rptrig_next = rptrig->next) && (++cnt < value))
rptrig = rptrig_next;
if (rptrig_next)
{
REMOVE_BIT(pRoom->rprog_flags, rptrig_next->type);
rptrig->next = rptrig_next->next;
rptrig_free(rptrig_next);
}
else
{
char_puts("No such trigger.\n",ch);
return FALSE;
}
}
rptrig_fix(pRoom);
char_puts("Trigger removed.\n", ch);
return TRUE;
}