/***************************************************************************
* 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. *
* *
* _/ _/_/_/ _/ _/ _/ ACK! MUD is modified *
* _/_/ _/ _/ _/ _/ Merc2.0/2.1/2.2 code *
* _/ _/ _/ _/_/ _/ (c)Stephen Dooley 1994 *
* _/_/_/_/ _/ _/ _/ "This mud has not been *
* _/ _/ _/_/_/ _/ _/ _/ tested on animals." *
* *
* *
* 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. *
***************************************************************************/
/*
* This program goes through each area. It checks all vnums to see if
* they are in the allowed range. If not it moves them, and updates all
* references.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "merc.h"
#include "hash.h"
void swap_global_hash(char Tp, void * Ptr, int old_vnum, int new_vnum)
{
ROOM_INDEX_DATA * pRoomIndex,* prevRoomIndex;
OBJ_INDEX_DATA * pObjIndex ,* prevObjIndex;
MOB_INDEX_DATA * pMobIndex ,* prevMobIndex;
extern ROOM_INDEX_DATA * room_index_hash[];
extern OBJ_INDEX_DATA * obj_index_hash[];
extern MOB_INDEX_DATA * mob_index_hash[];
int iHash;
switch (Tp)
{
case 'R':
/* Delete old hash table entry */
iHash = old_vnum % MAX_KEY_HASH;
prevRoomIndex = NULL;
for (pRoomIndex = room_index_hash[iHash]; pRoomIndex != NULL; pRoomIndex=pRoomIndex->next)
{
if (pRoomIndex == (ROOM_INDEX_DATA *) Ptr)
break;
prevRoomIndex = pRoomIndex;
}
if (pRoomIndex != NULL)
{
if (prevRoomIndex == NULL)
room_index_hash[iHash]=pRoomIndex->next;
else
prevRoomIndex->next=pRoomIndex->next;
}
/* Add another */
iHash = new_vnum % MAX_KEY_HASH;
pRoomIndex->next = room_index_hash[iHash];
room_index_hash[iHash] = pRoomIndex;
break;
case 'M':
/* Delete old hash table entry */
iHash = old_vnum % MAX_KEY_HASH;
prevMobIndex = NULL;
for (pMobIndex = mob_index_hash[iHash]; pMobIndex != NULL; pMobIndex=pMobIndex->next)
{
if (pMobIndex == (MOB_INDEX_DATA *) Ptr)
break;
prevMobIndex = pMobIndex;
}
if (pMobIndex != NULL)
{
if (prevMobIndex == NULL)
mob_index_hash[iHash]=pMobIndex->next;
else
prevMobIndex->next=pMobIndex->next;
}
/* Add another */
iHash = new_vnum % MAX_KEY_HASH;
pMobIndex->next = mob_index_hash[iHash];
mob_index_hash[iHash] = pMobIndex;
break;
case 'O':
/* Delete old hash table entry */
iHash = old_vnum % MAX_KEY_HASH;
prevObjIndex = NULL;
for (pObjIndex = obj_index_hash[iHash]; pObjIndex != NULL; pObjIndex=pObjIndex->next)
{
if (pObjIndex == (OBJ_INDEX_DATA *) Ptr)
break;
prevObjIndex = pObjIndex;
}
if (pObjIndex != NULL)
{
if (prevObjIndex == NULL)
obj_index_hash[iHash]=pObjIndex->next;
else
prevObjIndex->next=pObjIndex->next;
}
/* Add another */
iHash = new_vnum % MAX_KEY_HASH;
pObjIndex->next = obj_index_hash[iHash];
obj_index_hash[iHash] = pObjIndex;
break;
}
return;
}
void do_check_areas(CHAR_DATA * ch, char * argument)
{
hash_table * room_hash;
hash_table * obj_hash;
hash_table * mob_hash;
int min_vnum,max_vnum;
int new_vnum,old_vnum;
char buffer[MAX_INPUT_LENGTH];
FILE * out_file;
int a;
RESET_DATA * pReset;
AREA_DATA * CurArea;
BUILD_DATA_LIST * pList;
ROOM_INDEX_DATA * pRoomIndex;
OBJ_INDEX_DATA * pObjIndex;
MOB_INDEX_DATA * pMobIndex;
/* Create hash tables for rooms, mobiles, objects */
room_hash=create_hash_table(MAX_KEY_HASH);
obj_hash=create_hash_table(MAX_KEY_HASH);
mob_hash=create_hash_table(MAX_KEY_HASH);
out_file=fopen("area_changes.txt","a");
for (CurArea=first_area; CurArea != NULL; CurArea=CurArea->next)
{
min_vnum=CurArea->min_vnum;
max_vnum=CurArea->max_vnum;
fprintf(out_file,"%s:\n",CurArea->name);
/* Go through rooms */
for (pList=CurArea->first_area_room; pList != NULL; pList=pList->next)
{
pRoomIndex=pList->data;
if (pRoomIndex->vnum < min_vnum || pRoomIndex->vnum > max_vnum)
{
old_vnum=pRoomIndex->vnum;
/* Find a free slot */
for (new_vnum=min_vnum; new_vnum <= max_vnum; new_vnum++)
if (get_room_index(new_vnum)==NULL)
break;
if (new_vnum > max_vnum)
{
sprintf(buffer,"Not enough vnums in area %s\n\r",CurArea->name);
send_to_char(buffer,ch);
}
else
{
fprintf(out_file,"Room: [%5i] -> [%5i] %s\n",old_vnum,new_vnum,pRoomIndex->name);
/* Delete from room hashing table, and put new vnum in. */
add_hash_entry(room_hash,old_vnum,(void *) new_vnum);
swap_global_hash('R',pRoomIndex,old_vnum,new_vnum);
pRoomIndex->vnum=new_vnum;
area_modified(CurArea);
}
}
}
/* Go through objs */
for (pList=CurArea->first_area_object; pList != NULL; pList=pList->next)
{
pObjIndex=pList->data;
if (pObjIndex->vnum < min_vnum || pObjIndex->vnum > max_vnum)
{
old_vnum=pObjIndex->vnum;
/* Find a free slot */
for (new_vnum=min_vnum; new_vnum <= max_vnum; new_vnum++)
if (get_obj_index(new_vnum)==NULL)
break;
if (new_vnum > max_vnum)
{
sprintf(buffer,"Not enough vnums in area %s\n\r",CurArea->name);
send_to_char(buffer,ch);
}
else
{
fprintf(out_file,"Obj: [%5i] -> [%5i] %s\n",old_vnum,new_vnum,pObjIndex->short_descr);
/* Delete from obj hashing table, and put new vnum in. */
add_hash_entry(obj_hash,old_vnum,(void *) new_vnum);
swap_global_hash('O',pObjIndex,old_vnum,new_vnum);
pObjIndex->vnum=new_vnum;
area_modified(CurArea);
}
}
}
/* Go through mobs */
for (pList=CurArea->first_area_mobile; pList != NULL; pList=pList->next)
{
pMobIndex=pList->data;
if (pMobIndex->vnum < min_vnum || pMobIndex->vnum > max_vnum)
{
old_vnum=pMobIndex->vnum;
/* Find a free slot */
for (new_vnum=min_vnum; new_vnum <= max_vnum; new_vnum++)
if (get_mob_index(new_vnum)==NULL)
break;
if (new_vnum > max_vnum)
{
sprintf(buffer,"Not enough vnums in area %s\n\r",CurArea->name);
send_to_char(buffer,ch);
}
else
{
fprintf(out_file,"Mob: [%5i] -> [%5i] %s\n",old_vnum,new_vnum,pMobIndex->short_descr);
/* Delete from mob hashing table, and put new vnum in. */
add_hash_entry(mob_hash,old_vnum,(void *) new_vnum);
swap_global_hash('M',pMobIndex,old_vnum,new_vnum);
pMobIndex->vnum=new_vnum;
area_modified(CurArea);
/* Check for shops */
if (pMobIndex->pShop != NULL)
pMobIndex->pShop->keeper=new_vnum;
}
}
}
}
fclose(out_file);
/* Now go through all things referencing the changes
*
* Resets
* exit->key
*
*/
for (CurArea=first_area; CurArea != NULL; CurArea=CurArea->next)
{
for (pList=CurArea->first_area_room; pList != NULL; pList=pList->next)
{
/* Check keys and exits*/
pRoomIndex=pList->data;
for (a=0; a<=5; a++)
{
if ( pRoomIndex->exit[a] != NULL )
{
if ( pRoomIndex->exit[a]->key != 0
&& (new_vnum=(int) get_hash_entry(obj_hash,pRoomIndex->exit[a]->key)) != 0)
{
pRoomIndex->exit[a]->key = new_vnum;
area_modified(CurArea);
}
if ( (new_vnum=(int) get_hash_entry(room_hash,pRoomIndex->exit[a]->vnum)) != 0)
{
pRoomIndex->exit[a]->vnum = new_vnum;
area_modified(CurArea);
}
}
}
}
/* Scan through resets */
for (pReset=CurArea->first_reset; pReset != NULL; pReset=pReset->next)
{
switch (pReset->command)
{
case 'M':
if ( (new_vnum=(int) get_hash_entry(mob_hash,pReset->arg1)) != 0)
{
area_modified(CurArea);
pReset->arg1=new_vnum;
}
if ( (new_vnum=(int) get_hash_entry(room_hash,pReset->arg3)) != 0)
{
area_modified(CurArea);
pReset->arg3=new_vnum;
}
break;
case 'O':
if ( (new_vnum=(int) get_hash_entry(obj_hash,pReset->arg1)) != 0)
{
area_modified(CurArea);
pReset->arg1=new_vnum;
}
if ( (new_vnum=(int) get_hash_entry(room_hash,pReset->arg3)) != 0)
{
area_modified(CurArea);
pReset->arg3=new_vnum;
}
break;
case 'P':
if ( (new_vnum=(int) get_hash_entry(obj_hash,pReset->arg1)) != 0)
{
area_modified(CurArea);
pReset->arg1=new_vnum;
}
if ( (new_vnum=(int) get_hash_entry(obj_hash,pReset->arg3)) != 0)
{
area_modified(CurArea);
pReset->arg3=new_vnum;
}
break;
case 'G':
case 'E':
if ( (new_vnum=(int) get_hash_entry(obj_hash,pReset->arg1)) != 0)
{
area_modified(CurArea);
pReset->arg1=new_vnum;
}
break;
case 'D':
case 'R':
if ( (new_vnum=(int) get_hash_entry(room_hash,pReset->arg1)) != 0)
{
area_modified(CurArea);
pReset->arg1=new_vnum;
}
break;
}
}
}
/* FINISHED */
delete_hash_table(room_hash);
delete_hash_table(obj_hash);
delete_hash_table(mob_hash);
return;
}
void do_check_area(CHAR_DATA * ch, char * argument)
{
send_to_char("You must say check_areas in full.\n\r",ch);
return;
}