/***************************************************************************
* 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.diku' as well the Merc *
* license in 'license.merc'. 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. *
***************************************************************************/
/*
MurkMUD++ - A Windows compatible, C++ compatible Merc 2.2 Mud.
\author Jon A. Lambert
\date 08/30/2006
\version 1.4
\remarks
This source code copyright (C) 2005, 2006 by Jon A. Lambert
All rights reserved.
Use governed by the MurkMUD++ public license found in license.murk++
*/
#include "os.hpp"
#include "config.hpp"
#include "globals.hpp"
#include "utils.hpp"
#include "io.hpp"
#include "area.hpp"
#include "reset.hpp"
#include "objproto.hpp"
#include "mobproto.hpp"
#include "exit.hpp"
#include "object.hpp"
#include "room.hpp"
int Area::top_area = 0;
Area::Area() :
age(15), nplayer(0) {
top_area++;
}
/*
* Reset one area.
*/
void Area::reset_area (void)
{
Reset *pReset;
Character *mob;
bool last;
int level;
mob = NULL;
last = true;
level = 0;
std::list<Reset*>::iterator rst;
for (rst = reset_list.begin(); rst != reset_list.end(); rst++) {
pReset = *rst;
Room *pRoomIndex;
MobPrototype *pMobIndex;
ObjectPrototype *pObjIndex;
ObjectPrototype *pObjToIndex;
Exit *pexit;
Object *obj;
Object *obj_to;
switch (pReset->command) {
default:
bug_printf ("Reset_area: bad command %c.", pReset->command);
break;
case 'M':
if ((pMobIndex = get_mob_index (pReset->arg1)) == NULL) {
bug_printf ("Reset_area: 'M': bad vnum %d.", pReset->arg1);
continue;
}
if ((pRoomIndex = get_room_index (pReset->arg3)) == NULL) {
bug_printf ("Reset_area: 'R': bad vnum %d.", pReset->arg3);
continue;
}
level = URANGE (0, pMobIndex->level - 2, LEVEL_HERO);
if (pMobIndex->count >= pReset->arg2) {
last = false;
break;
}
mob = pMobIndex->create_mobile ();
/*
* Check for pet shop.
*/
{
Room *pRoomIndexPrev;
pRoomIndexPrev = get_room_index (pRoomIndex->vnum - 1);
if (pRoomIndexPrev != NULL
&& IS_SET (pRoomIndexPrev->room_flags, ROOM_PET_SHOP))
SET_BIT (mob->actflags, ACT_PET);
}
if (pRoomIndex->is_dark())
SET_BIT (mob->affected_by, AFF_INFRARED);
mob->char_to_room(pRoomIndex);
level = URANGE (0, mob->level - 2, LEVEL_HERO);
last = true;
break;
case 'O':
if ((pObjIndex = get_obj_index (pReset->arg1)) == NULL) {
bug_printf ("Reset_area: 'O': bad vnum %d.", pReset->arg1);
continue;
}
if ((pRoomIndex = get_room_index (pReset->arg3)) == NULL) {
bug_printf ("Reset_area: 'R': bad vnum %d.", pReset->arg3);
continue;
}
if (nplayer > 0
|| pObjIndex->count_obj_list (pRoomIndex->contents) > 0) {
last = false;
break;
}
obj = pObjIndex->create_object(number_fuzzy (level));
obj->cost = 0;
obj->obj_to_room (pRoomIndex);
last = true;
break;
case 'P':
if ((pObjIndex = get_obj_index (pReset->arg1)) == NULL) {
bug_printf ("Reset_area: 'P': bad vnum %d.", pReset->arg1);
continue;
}
if ((pObjToIndex = get_obj_index (pReset->arg3)) == NULL) {
bug_printf ("Reset_area: 'P': bad vnum %d.", pReset->arg3);
continue;
}
if (nplayer > 0
|| (obj_to = pObjToIndex->get_obj_type()) == NULL
|| pObjIndex->count_obj_list (obj_to->contains) > 0) {
last = false;
break;
}
obj = pObjIndex->create_object (number_fuzzy (obj_to->level));
obj->obj_to_obj (obj_to);
last = true;
break;
case 'G':
case 'E':
if ((pObjIndex = get_obj_index (pReset->arg1)) == NULL) {
bug_printf ("Reset_area: 'E' or 'G': bad vnum %d.", pReset->arg1);
continue;
}
if (!last)
break;
if (mob == NULL) {
bug_printf ("Reset_area: 'E' or 'G': null mob for vnum %d.", pReset->arg1);
last = false;
break;
}
if (mob->pIndexData->pShop != NULL) {
int olevel;
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:
olevel = number_range (5, 15);
break;
}
obj = pObjIndex->create_object (olevel);
SET_BIT (obj->extra_flags, ITEM_INVENTORY);
} else {
obj = pObjIndex->create_object (number_fuzzy (level));
}
obj->obj_to_char (mob);
if (pReset->command == 'E')
mob->equip_char (obj, pReset->arg3);
last = true;
break;
case 'D':
if ((pRoomIndex = get_room_index (pReset->arg1)) == NULL) {
bug_printf ("Reset_area: 'D': bad vnum %d.", pReset->arg1);
continue;
}
if ((pexit = pRoomIndex->exit[pReset->arg2]) == NULL)
break;
switch (pReset->arg3) {
case 0:
REMOVE_BIT (pexit->exit_info, EX_CLOSED);
REMOVE_BIT (pexit->exit_info, EX_LOCKED);
break;
case 1:
SET_BIT (pexit->exit_info, EX_CLOSED);
REMOVE_BIT (pexit->exit_info, EX_LOCKED);
break;
case 2:
SET_BIT (pexit->exit_info, EX_CLOSED);
SET_BIT (pexit->exit_info, EX_LOCKED);
break;
}
last = true;
break;
case 'R':
if ((pRoomIndex = get_room_index (pReset->arg1)) == NULL) {
bug_printf ("Reset_area: 'R': bad vnum %d.", pReset->arg1);
continue;
}
{
int d0;
int d1;
for (d0 = 0; d0 < pReset->arg2 - 1; d0++) {
d1 = number_range (d0, pReset->arg2 - 1);
pexit = pRoomIndex->exit[d0];
pRoomIndex->exit[d0] = pRoomIndex->exit[d1];
pRoomIndex->exit[d1] = pexit;
}
}
break;
}
}
return;
}