alanthia/area/
alanthia/gods/
alanthia/player/
/***************************************************************************
 *  File: mem.c                                                            *
 *                                                                         *
 *  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 code was freely distributed with the The Isles 1.1 source code,   *
 *  and has been used here for OLC - OLC would not be what it is without   *
 *  all the previous coders who released their source code.                *
 *                                                                         *
 ***************************************************************************/



#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "utils.h"
#include "olc.h"
#include "tables.h"

/*
 * Globals
 */
extern int top_reset;
extern int top_area;
extern int top_exit;
extern int top_ed;
extern int top_room;

AREA_DATA *area_free;
EXTRA_DESCR_DATA *extra_descr_free;
EXIT_DATA *exit_free;
ROOM_INDEX_DATA *room_index_free;
OBJ_INDEX_DATA *obj_index_free;
SHOP_DATA *shop_free;
MOB_INDEX_DATA *mob_index_free;
RESET_DATA *reset_free;
HELP_DATA *help_free;
RACE_DATA *race_free;

HELP_DATA *help_last;
RACE_DATA *race_last;
MPROG_CODE *mpcode_free;


void free_extra_descr(EXTRA_DESCR_DATA * pExtra);
void free_affect(AFFECT_DATA * af);

RESET_DATA *new_reset_data(void)
{
    RESET_DATA *pReset;

    if (!reset_free) {
	pReset = alloc_perm(sizeof(*pReset));
	top_reset++;
    } else {
	pReset = reset_free;
	reset_free = reset_free->next;
    }

    pReset->next = NULL;
    pReset->command = 'X';
    pReset->arg1 = 0;
    pReset->arg2 = 0;
    pReset->arg3 = 0;
    pReset->arg4 = 0;

    return pReset;
}



void free_reset_data(RESET_DATA * pReset)
{
    pReset->next = reset_free;
    reset_free = pReset;
    return;
}



AREA_DATA *new_area(void)
{
    AREA_DATA *pArea;
    char buf[MAX_INPUT_LENGTH];

    if (!area_free) {
	pArea = alloc_perm(sizeof(*pArea));
	top_area++;
    } else {
	pArea = area_free;
	area_free = area_free->next;
    }

    pArea->next = NULL;
    pArea->name = str_dup("New area");
    pArea->area_flags = AREA_ADDED;
    pArea->security = 1;
    pArea->builders = str_dup("None");
    pArea->min_vnum = 0;
    pArea->max_vnum = 0;
    pArea->age = 0;
    pArea->nplayer = 0;
    pArea->empty = TRUE;	
    sprintf(buf, "area%ld.are", pArea->vnum);
    pArea->file_name = str_dup(buf);
    pArea->vnum = top_area - 1;

    return pArea;
}



void free_area(AREA_DATA * pArea)
{
    free_string(pArea->name);
    free_string(pArea->file_name);
    free_string(pArea->builders);

    pArea->next = area_free->next;
    area_free = pArea;
    return;
}



EXIT_DATA *new_exit(void)
{
    EXIT_DATA *pExit;

    if (!exit_free) {
	pExit = alloc_perm(sizeof(*pExit));
	top_exit++;
    } else {
	pExit = exit_free;
	exit_free = exit_free->next;
    }

    pExit->u1.to_room = NULL;	/* ROM OLC */
    pExit->next = NULL;
/*  pExit->vnum         =   0;                        ROM OLC */
    pExit->exit_info = 0;
    pExit->key = 0;
    pExit->keyword = &str_empty[0];
    pExit->description = &str_empty[0];
    pExit->rs_flags = 0;

    return pExit;
}



void free_exit(EXIT_DATA * pExit)
{
    int flag;

    for (flag = 0; exit_flags[flag].name != NULL; flag++) {
	if (IS_SET(pExit->exit_info, exit_flags[flag].bit)) {
	    TOGGLE_BIT(pExit->rs_flags, exit_flags[flag].bit);
	    TOGGLE_BIT(pExit->exit_info, exit_flags[flag].bit);
	}
    }

    free_string(pExit->keyword);
    free_string(pExit->description);

    pExit->next = exit_free;
    exit_free = pExit;
    return;
}


/*
   EXTRA_DESCR_DATA *new_extra_descr( void )
   {
   EXTRA_DESCR_DATA *pExtra;

   if ( !extra_descr_free )
   {
   pExtra              =   alloc_perm( sizeof(*pExtra) );
   top_ed++;
   }
   else
   {
   pExtra              =   extra_descr_free;
   extra_descr_free    =   extra_descr_free->next;
   }

   pExtra->keyword         =   NULL;
   pExtra->description     =   NULL;
   pExtra->next            =   NULL;

   return pExtra;
   } */


/*
   void free_extra_descr( EXTRA_DESCR_DATA *pExtra )
   {
   free_string( pExtra->keyword );
   free_string( pExtra->description );

   pExtra->next        =   extra_descr_free;
   extra_descr_free    =   pExtra;
   return;
   }
 */


ROOM_INDEX_DATA *new_room_index(void)
{
    ROOM_INDEX_DATA *pRoom;
    int door;

    if (!room_index_free) {
	pRoom = alloc_perm(sizeof(*pRoom));
	top_room++;
    } else {
	pRoom = room_index_free;
	room_index_free = room_index_free->next;
    }

    pRoom->next = NULL;
    pRoom->people = NULL;
    pRoom->contents = NULL;
    pRoom->extra_descr = NULL;
    pRoom->area = NULL;

    for (door = 0; door < MAX_DIR; door++)
	pRoom->exit[door] = NULL;

    pRoom->name = &str_empty[0];
    pRoom->description = &str_empty[0];
    pRoom->vnum = 0;
    pRoom->room_flags = 0;
    pRoom->light = 0;
    pRoom->sector_type = 0;
    pRoom->clan = 0;
    pRoom->heal_rate = 100;
    pRoom->mana_rate = 100;

    return pRoom;
}



void free_room_index(ROOM_INDEX_DATA * pRoom)
{
    int door;
    EXTRA_DESCR_DATA *pExtra;
    RESET_DATA *pReset;

    free_string(pRoom->name);
    free_string(pRoom->description);

    for (door = 0; door < MAX_DIR; door++) {
	if (pRoom->exit[door])
	    free_exit(pRoom->exit[door]);
    }

    for (pExtra = pRoom->extra_descr; pExtra; pExtra = pExtra->next) {
	free_extra_descr(pExtra);
    }

    for (pReset = pRoom->reset_first; pReset; pReset = pReset->next) {
	free_reset_data(pReset);
    }

    pRoom->next = room_index_free;
    room_index_free = pRoom;
    return;
}

extern AFFECT_DATA *affect_free;
/*
   AFFECT_DATA *new_affect( void )
   {
   AFFECT_DATA *pAf;

   if ( !affect_free )
   {
   pAf             =   alloc_perm( sizeof(*pAf) );
   top_affect++;
   }
   else
   {
   pAf             =   affect_free;
   affect_free     =   affect_free->next;
   }

   pAf->next       =   NULL;
   pAf->location   =   0;
   pAf->modifier   =   0;
   pAf->type       =   0;
   pAf->duration   =   0;
   pAf->bitvector  =   0;

   return pAf;
   }
 */

/*
   void free_affect( AFFECT_DATA* pAf )
   {
   pAf->next           = affect_free;
   affect_free         = pAf;
   return;
   }
 */


SHOP_DATA *new_shop(void)
{
    SHOP_DATA *pShop;
    int buy;

    if (!shop_free) {
	pShop = alloc_perm(sizeof(*pShop));
	top_shop++;
    } else {
	pShop = shop_free;
	shop_free = shop_free->next;
    }

    pShop->next = NULL;
    pShop->keeper = 0;

    for (buy = 0; buy < MAX_TRADE; buy++)
	pShop->buy_type[buy] = 0;

    pShop->profit_buy = 100;
    pShop->profit_sell = 100;
    pShop->open_hour = 0;
    pShop->close_hour = 23;

    return pShop;
}



void free_shop(SHOP_DATA * pShop)
{
    pShop->next = shop_free;
    shop_free = pShop;
    return;
}



OBJ_INDEX_DATA *new_obj_index(void)
{
    OBJ_INDEX_DATA *pObj;
    int value;

    if (!obj_index_free) {
	pObj = alloc_perm(sizeof(*pObj));
	top_obj_index++;
    } else {
	pObj = obj_index_free;
	obj_index_free = obj_index_free->next;
    }

    pObj->next = NULL;
    pObj->extra_descr = NULL;
    pObj->affected = NULL;
    pObj->area = NULL;
    pObj->name = str_dup("no name");
    pObj->short_descr = str_dup("(no short description)");
    pObj->description = str_dup("(no description)");
    pObj->vnum = 0;
    pObj->item_type = ITEM_TRASH;
    pObj->extra_flags = 0;
    pObj->wear_flags = 0;
    pObj->count = 0;
    pObj->weight = 0;
    pObj->cost = 0;
    pObj->material = str_dup("unknown");	/* ROM */
    pObj->condition = 100;	/* ROM */
    for (value = 0; value < 5; value++)	/* 5 - ROM */
	pObj->value[value] = 0;

    pObj->new_format = TRUE;	/* ROM */

    return pObj;
}



void free_obj_index(OBJ_INDEX_DATA * pObj)
{
    EXTRA_DESCR_DATA *pExtra;
    AFFECT_DATA *pAf;

    free_string(pObj->name);
    free_string(pObj->short_descr);
    free_string(pObj->description);

    for (pAf = pObj->affected; pAf; pAf = pAf->next) {
	free_affect(pAf);
    }

    for (pExtra = pObj->extra_descr; pExtra; pExtra = pExtra->next) {
	free_extra_descr(pExtra);
    }

    pObj->next = obj_index_free;
    obj_index_free = pObj;
    return;
}

RACE_DATA *new_race(void)
{
    RACE_DATA *NewRace;
	int value;

    NewRace = alloc_perm(sizeof(*NewRace));

    if (race_first == NULL)
		race_first = NewRace;
          
    if (race_last != NULL)
		race_last->next = NewRace;
          
      race_last = NewRace;
      NewRace->next = NULL;
      top_race++;

    NewRace->name = str_dup("RaceName");
    NewRace->who_name = str_dup("{!R{!a{!c{!e{!N{!a{!m{!e{x");
    NewRace->gen_name = str_dup("Race Name");
    NewRace->pc_race = 0;      
    NewRace->act = C;          
    NewRace->aff = 0;          
    NewRace->off = 0;          
    NewRace->imm = 0;          
    NewRace->res = 0;          
    NewRace->vuln = 0;         
    NewRace->form = 0;         
    NewRace->parts = 0;        
    NewRace->sex = 0;          
    NewRace->size = 0;         
	NewRace->lifespan = 100;
	NewRace->min_level = 1;
	NewRace->max_level = 50;
	NewRace->points = 0;
	NewRace->deleted = FALSE;

    for (value = 0; value < MAX_STATS; value++)
    	NewRace->stats[value] = 25;

    for (value = 0; value < MAX_SENSES; value++)
    	NewRace->senses[value] = 25;

    for (value = 0; value < MAX_RACE_SKILLS; value++)
    	NewRace->skills[value] = str_dup("");

    for (value = 0; value < MAX_RACE_FEEDS; value++)
    	NewRace->feeds[value] = str_dup("");

    return NewRace;
}

HELP_DATA *new_help(void)
{
    HELP_DATA *NewHelp;

    NewHelp = alloc_perm(sizeof(*NewHelp));
    top_help++;

    NewHelp->level = 0;
    NewHelp->keyword = str_dup("");
    NewHelp->text = str_dup("");
    NewHelp->next = NULL;

    return NewHelp;
}



MOB_INDEX_DATA *new_mob_index(void)
{
    MOB_INDEX_DATA *pMob;

    if (!mob_index_free) {
	pMob = alloc_perm(sizeof(*pMob));
	top_mob_index++;
    } else {
	pMob = mob_index_free;
	mob_index_free = mob_index_free->next;
    }

    pMob->next = NULL;
    pMob->spec_fun = NULL;
    pMob->pShop = NULL;
    pMob->area = NULL;
    pMob->player_name = str_dup("no name");
    pMob->short_descr = str_dup("(no short description)");
    pMob->long_descr = str_dup("(no long description)\n\r");
    pMob->description = &str_empty[0];
    pMob->vnum = 0;
    pMob->count = 0;
    pMob->killed = 0;
    pMob->sex = 0;
    pMob->level = 0;
    pMob->act = ACT_IS_NPC;
    pMob->affected_by = 0;
    pMob->alignment = 0;
    pMob->hitroll = 0;
    pMob->race = race_lookup("human");
    pMob->form = 0;
    pMob->parts = 0;
    pMob->imm_flags = 0;
    pMob->res_flags = 0;
    pMob->vuln_flags = 0;
    pMob->material = str_dup("unknown");
    pMob->off_flags = 0;
    pMob->size = SIZE_MEDIUM;
    pMob->ac[AC_PIERCE] = 0;
    pMob->ac[AC_BASH] = 0;
    pMob->ac[AC_SLASH] = 0;
    pMob->ac[AC_EXOTIC] = 0;
    pMob->hit[DICE_NUMBER] = 0;
    pMob->hit[DICE_TYPE] = 0;
    pMob->hit[DICE_BONUS] = 0;
    pMob->mana[DICE_NUMBER] = 0;
    pMob->mana[DICE_TYPE] = 0;
    pMob->mana[DICE_BONUS] = 0;
    pMob->damage[DICE_NUMBER] = 0;
    pMob->damage[DICE_TYPE] = 0;
    pMob->damage[DICE_NUMBER] = 0;
    pMob->start_pos = POS_STANDING;
    pMob->default_pos = POS_STANDING;
    pMob->wealth = 0;
    pMob->mprogs = NULL;


    pMob->new_format = TRUE;	/* ROM */

    return pMob;
}



void free_mob_index(MOB_INDEX_DATA * pMob)
{
    free_string(pMob->player_name);
    free_string(pMob->short_descr);
    free_string(pMob->long_descr);
    free_string(pMob->description);

    free_shop(pMob->pShop);
    free_mprog(pMob->mprogs);

    pMob->next = mob_index_free;
    mob_index_free = pMob;
    return;
}

MPROG_CODE *new_mpcode(void)
{
    MPROG_CODE *NewCode;

    if (!mpcode_free) {
	NewCode = alloc_perm(sizeof(*NewCode));
	top_mprog_index++;
    } else {
	NewCode = mpcode_free;
	mpcode_free = mpcode_free->next;
    }

    NewCode->vnum = 0;
    NewCode->code = str_dup("");
    NewCode->next = NULL;

    return NewCode;
}

void free_mpcode(MPROG_CODE * pMcode)
{
    free_string(pMcode->code);
    pMcode->next = mpcode_free;
    mpcode_free = pMcode;
    return;
}