/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements 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 * * benefiting. We hope that you share your changes too. What goes * * around, comes around. * *************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * *************************************************************************** * 1stMUD ROM Derivative (c) 2001-2002 by Ryan Jennings * * http://1stmud.dlmud.com/ <r-jenn@shaw.ca> * ***************************************************************************/ #include <sys/types.h> #if !defined(WIN32) #include <sys/time.h> #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include "merc.h" #include "recycle.h" #include "olc.h" #include "tables.h" #include "interp.h" /* stuff for recycling ban structures */ BAN_DATA *ban_free; BAN_DATA *new_ban(void) { static BAN_DATA ban_zero; BAN_DATA *ban; GET_FREE(ban, BAN_DATA, next, ban_free); *ban = ban_zero; VALIDATE(ban); ban->name = &str_empty[0]; return ban; } void free_ban(BAN_DATA * ban) { if (!IS_VALID(ban)) return; free_string(ban->name); INVALIDATE(ban); PUT_FREE(ban, next, ban_free); } /* stuff for recycling descriptors */ DESCRIPTOR_DATA *new_descriptor(void) { static DESCRIPTOR_DATA d_zero; DESCRIPTOR_DATA *d; GET_FREE(d, DESCRIPTOR_DATA, next, descriptor_free); *d = d_zero; VALIDATE(d); d->connected = CON_GET_TERM; d->showstr_head = NULL; d->showstr_point = NULL; d->run_buf = NULL; d->run_head = NULL; d->outsize = 2000; alloc_mem(d->outbuf, char, d->outsize); return d; } void free_descriptor(DESCRIPTOR_DATA * d) { if (!IS_VALID(d)) return; free_string(d->host); free_mem(d->outbuf); INVALIDATE(d); PUT_FREE(d, next, descriptor_free); } /* stuff for recycling gen_data */ GEN_DATA *gen_data_free; GEN_DATA *new_gen_data(void) { static GEN_DATA gen_zero; GEN_DATA *gen; GET_FREE(gen, GEN_DATA, next, gen_data_free); *gen = gen_zero; VALIDATE(gen); alloc_mem(gen->skill_chosen, bool, maxSkill); alloc_mem(gen->group_chosen, bool, maxGroup); return gen; } void free_gen_data(GEN_DATA * gen) { if (!IS_VALID(gen)) return; INVALIDATE(gen); free_mem(gen->skill_chosen); free_mem(gen->group_chosen); PUT_FREE(gen, next, gen_data_free); } /* stuff for recycling extended descs */ EXTRA_DESCR_DATA *extra_descr_free; EXTRA_DESCR_DATA *new_extra_descr(void) { EXTRA_DESCR_DATA *ed; GET_FREE(ed, EXTRA_DESCR_DATA, next, extra_descr_free); ed->keyword = &str_empty[0]; ed->description = &str_empty[0]; VALIDATE(ed); return ed; } void free_extra_descr(EXTRA_DESCR_DATA * ed) { if (!IS_VALID(ed)) return; free_string(ed->keyword); free_string(ed->description); INVALIDATE(ed); PUT_FREE(ed, next, extra_descr_free); } /* stuff for recycling affects */ AFFECT_DATA *new_affect(void) { static AFFECT_DATA af_zero; AFFECT_DATA *af; GET_FREE(af, AFFECT_DATA, next, affect_free); *af = af_zero; VALIDATE(af); return af; } void free_affect(AFFECT_DATA * af) { if (!IS_VALID(af)) return; INVALIDATE(af); PUT_FREE(af, next, affect_free); } /* stuff for recycling objects */ OBJ_DATA *new_obj(void) { static OBJ_DATA obj_zero; OBJ_DATA *obj; GET_FREE(obj, OBJ_DATA, next, obj_free); *obj = obj_zero; VALIDATE(obj); return obj; } void free_obj(OBJ_DATA * obj) { AFFECT_DATA *paf, *paf_next; EXTRA_DESCR_DATA *ed, *ed_next; if (!IS_VALID(obj)) return; for (paf = obj->first_affect; paf != NULL; paf = paf_next) { paf_next = paf->next; free_affect(paf); } obj->first_affect = NULL; for (ed = obj->first_extra_descr; ed != NULL; ed = ed_next) { ed_next = ed->next; free_extra_descr(ed); } obj->first_extra_descr = NULL; free_string(obj->name); free_string(obj->description); free_string(obj->short_descr); free_string(obj->owner); INVALIDATE(obj); PUT_FREE(obj, next, obj_free); } /* stuff for recyling characters */ CHAR_DATA *new_char(void) { static CHAR_DATA ch_zero; CHAR_DATA *ch; int i; GET_FREE(ch, CHAR_DATA, next, char_free); *ch = ch_zero; VALIDATE(ch); ch->name = &str_empty[0]; ch->short_descr = &str_empty[0]; ch->long_descr = &str_empty[0]; ch->description = &str_empty[0]; ch->prompt = &str_empty[0]; ch->prefix = &str_empty[0]; ch->logon = current_time; ch->lines = PAGELEN; ch->clan = NULL; ch->invited = NULL; ch->rank = 0; ch->deity = NULL; for (i = 0; i < 4; i++) ch->armor[i] = 100; ch->position = POS_STANDING; ch->hit = 20; ch->max_hit = 20; ch->mana = 100; ch->max_mana = 100; ch->move = 100; ch->max_move = 100; for (i = 0; i < MAX_STATS; i++) { ch->perm_stat[i] = 13; ch->mod_stat[i] = 0; } return ch; } void free_char(CHAR_DATA * ch) { OBJ_DATA *obj; OBJ_DATA *obj_next; AFFECT_DATA *paf; AFFECT_DATA *paf_next; if (!IS_VALID(ch)) return; if (IS_NPC(ch)) mobile_count--; for (obj = ch->first_carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; extract_obj(obj); } for (paf = ch->first_affect; paf != NULL; paf = paf_next) { paf_next = paf->next; affect_remove(ch, paf); } free_string(ch->name); free_string(ch->short_descr); free_string(ch->long_descr); free_string(ch->description); free_string(ch->prompt); free_string(ch->prefix); free_pcdata(ch->pcdata); PUT_FREE(ch, next, char_free); INVALIDATE(ch); return; } void clear_history(PC_DATA * pcdata) { int i; int x; for (i = 0; i < LAST_MAX; i++) { for (x = 0; x < LAST_PAGE_LENGTH; x++) { pcdata->history[i][x] = &str_empty[0]; } } } void free_history(PC_DATA * pcdata) { int i, x; for (i = 0; i < LAST_MAX; i++) { for (x = 0; x < LAST_PAGE_LENGTH; x++) { free_string(pcdata->history[i][x]); } } } PC_DATA *new_pcdata(void) { int alias, bud; static PC_DATA pcdata_zero; PC_DATA *pcdata; GET_FREE(pcdata, PC_DATA, next, pcdata_free); *pcdata = pcdata_zero; for (alias = 0; alias < MAX_ALIAS; alias++) { pcdata->alias[alias] = NULL; pcdata->alias_sub[alias] = NULL; } for (bud = 0; bud < MAX_BUDDY; bud++) { pcdata->buddies[bud] = NULL; } clear_history(pcdata); pcdata->buffer = new_buf(); alloc_mem(pcdata->learned, int, maxSkill); alloc_mem(pcdata->group_known, bool, maxGroup); pcdata->str_ed_key = '/'; VALIDATE(pcdata); return pcdata; } void free_pcdata(PC_DATA * pcdata) { int alias, pos; if (!IS_VALID(pcdata)) return; free_string(pcdata->pwd); free_string(pcdata->bamfin); free_string(pcdata->bamfout); free_string(pcdata->title); free_string(pcdata->who_descr); free_string(pcdata->webpass); free_buf(pcdata->buffer); free_mem(pcdata->learned); free_mem(pcdata->group_known); for (alias = 0; alias < MAX_ALIAS; alias++) { free_string(pcdata->alias[alias]); free_string(pcdata->alias_sub[alias]); } for (pos = 0; pos < MAX_BUDDY; pos++) free_string(pcdata->buddies[pos]); free_history(pcdata); INVALIDATE(pcdata); PUT_FREE(pcdata, next, pcdata_free); return; } /* stuff for setting ids */ long last_pc_id; long last_mob_id; long get_pc_id(void) { int val; val = (current_time <= last_pc_id) ? last_pc_id + 1 : current_time; last_pc_id = val; return val; } long get_mob_id(void) { last_mob_id++; return last_mob_id; } MEM_DATA *mem_data_free; /* procedures and constants needed for buffering */ BUFFER *buf_free; MEM_DATA *new_mem_data(void) { MEM_DATA *memory; GET_FREE(memory, MEM_DATA, next, mem_data_free); memory->next = NULL; memory->id = 0; memory->reaction = 0; memory->when = 0; VALIDATE(memory); return memory; } void free_mem_data(MEM_DATA * memory) { if (!IS_VALID(memory)) return; INVALIDATE(memory); PUT_FREE(memory, next, mem_data_free); } /* buffer sizes */ const int buf_size[MAX_BUF_LIST] = { 16, 32, 64, 128, 256, 1024, 2048, 4096, 8192, 16384 }; /* local procedure for finding the next acceptable size */ /* -1 indicates out-of-boundary error */ int get_size(int val) { int i; for (i = 0; i < MAX_BUF_LIST; i++) if (buf_size[i] >= val) { return buf_size[i]; } return -1; } BUFFER *new_buf() { BUFFER *buffer; GET_FREE(buffer, BUFFER, next, buf_free); buffer->next = NULL; buffer->state = BUFFER_SAFE; buffer->size = get_size(BASE_BUF); alloc_mem(buffer->string, char, buffer->size); buffer->string[0] = '\0'; VALIDATE(buffer); return buffer; } BUFFER *new_buf_size(int size) { BUFFER *buffer; GET_FREE(buffer, BUFFER, next, buf_free); buffer->next = NULL; buffer->state = BUFFER_SAFE; buffer->size = get_size(size); if (buffer->size == -1) { bug("new_buf: buffer size %d too large.", size); exit(1); } alloc_mem(buffer->string, char, buffer->size); buffer->string[0] = '\0'; VALIDATE(buffer); return buffer; } void free_buf(BUFFER * buffer) { if (!IS_VALID(buffer)) return; free_mem(buffer->string); buffer->string = NULL; buffer->size = 0; buffer->state = BUFFER_FREED; INVALIDATE(buffer); PUT_FREE(buffer, next, buf_free); } bool add_buf(BUFFER * buffer, const char *string) { int len; char *oldstr; int oldsize; oldstr = buffer->string; oldsize = buffer->size; if (buffer->state == BUFFER_OVERFLOW) /* don't waste time on bad strings! */ return FALSE; len = strlen(buffer->string) + strlen(string) + 1; while (len >= buffer->size) /* increase the buffer size */ { buffer->size = get_size(buffer->size + 1); { if (buffer->size == -1) /* overflow */ { buffer->size = oldsize; buffer->state = BUFFER_OVERFLOW; bug("buffer overflow past size %d", buffer->size); return FALSE; } } } if (buffer->size != oldsize) { alloc_mem(buffer->string, char, buffer->size); strcpy(buffer->string, oldstr); free_mem(oldstr); } strcat(buffer->string, string); return TRUE; } void clear_buf(BUFFER * buffer) { buffer->string[0] = '\0'; buffer->state = BUFFER_SAFE; } char *buf_string(BUFFER * buffer) { return buffer->string; } /* stuff for recycling mobprograms */ PROG_LIST *prog_free; PROG_LIST *new_prog(void) { static PROG_LIST mp_zero; PROG_LIST *mp; GET_FREE(mp, PROG_LIST, next, prog_free); *mp = mp_zero; mp->vnum = 0; mp->trig_type = 0; mp->code = str_dup(""); VALIDATE(mp); return mp; } void free_prog(PROG_LIST * mp) { if (!IS_VALID(mp)) return; INVALIDATE(mp); PUT_FREE(mp, next, prog_free); } HELP_DATA *help_free; HELP_DATA *new_help(void) { HELP_DATA *help; GET_FREE(help, HELP_DATA, next, help_free); help->keyword = &str_empty[0]; help->text = &str_empty[0]; return help; } void free_help(HELP_DATA * help) { free_string(help->keyword); free_string(help->text); PUT_FREE(help, next, help_free); } /* * stuff for recycling statlist structures */ STAT_DATA *stat_free; STAT_DATA *new_stat_data(void) { static STAT_DATA stat_zero; STAT_DATA *stat; GET_FREE(stat, STAT_DATA, next, stat_free); *stat = stat_zero; VALIDATE(stat); stat->name = &str_empty[0]; return stat; } void free_stat_data(STAT_DATA * stat) { if (!IS_VALID(stat)) return; free_string(stat->name); INVALIDATE(stat); PUT_FREE(stat, next, stat_free); } CORPSE_DATA *corpse_free; CORPSE_DATA *new_corpse(void) { static CORPSE_DATA corpse_zero; CORPSE_DATA *corpse; GET_FREE(corpse, CORPSE_DATA, next, corpse_free); *corpse = corpse_zero; corpse->corpse = NULL; return corpse; } void free_corpse(CORPSE_DATA * corpse) { if (corpse == NULL) return; if (corpse->corpse != NULL) free_obj(corpse->corpse); PUT_FREE(corpse, next, corpse_free); return; } AUCTION_DATA *auction_free; AUCTION_DATA *new_auction(void) { static AUCTION_DATA auc_zero; AUCTION_DATA *auction; GET_FREE(auction, AUCTION_DATA, next, auction_free); *auction = auc_zero; VALIDATE(auction); return auction; } void free_auction(AUCTION_DATA * auction) { if (!IS_VALID(auction)) return; auction->high_bidder = NULL; auction->item = NULL; auction->owner = NULL; INVALIDATE(auction); PUT_FREE(auction, next, auction_free); } WPWD_DATA *WPWD_free; WPWD_DATA *new_pwd(void) { static WPWD_DATA WPWD_zero; WPWD_DATA *pwd; GET_FREE(pwd, WPWD_DATA, next, WPWD_free); *pwd = WPWD_zero; pwd->name = &str_empty[0]; pwd->passw = &str_empty[0]; VALIDATE(pwd); return pwd; } void free_pwd(WPWD_DATA * pwd) { if (!IS_VALID(pwd)) return; free_string(pwd->name); free_string(pwd->passw); INVALIDATE(pwd); PUT_FREE(pwd, next, WPWD_free); } RACE_DATA *race_free; RACE_DATA *new_race(void) { static RACE_DATA race_zero; RACE_DATA *race; int x; GET_FREE(race, RACE_DATA, next, race_free); *race = race_zero; race->name = &str_empty[0]; race->who_name = &str_empty[0]; race->pc_race = FALSE; race->act = 0; race->aff = 0; race->off = 0; race->imm = 0; race->res = 0; race->vuln = 0; race->form = 0; race->parts = 0; for (x = 0; x < 5; x++) race->skills[x] = NULL; for (x = 0; x < STAT_MAX; x++) { race->stats[x] = 0; race->max_stats[x] = 0; } alloc_mem(race->class_mult, int, maxClass); race->points = 0; race->size = SIZE_MEDIUM; maxRace++; VALIDATE(race); return race; } void free_race(RACE_DATA * race) { int x; if (!IS_VALID(race)) return; free_string(race->name); free_string(race->who_name); for (x = 0; x < 5; x++) free_string(race->skills[x]); free_mem(race->class_mult); maxRace--; INVALIDATE(race); PUT_FREE(race, next, race_free); } MBR_DATA *new_mbr(void) { static MBR_DATA mbr_zero; MBR_DATA *mbr; GET_FREE(mbr, MBR_DATA, next, mbr_free); *mbr = mbr_zero; mbr->name = &str_empty[0]; mbr->clan = NULL; mbr->rank = 0; VALIDATE(mbr); return mbr; } void free_mbr(MBR_DATA * mbr) { if (!IS_VALID(mbr)) return; free_string(mbr->name); INVALIDATE(mbr); PUT_FREE(mbr, next, mbr_free); } SOCIAL_DATA *social_free; SOCIAL_DATA *new_social(void) { static SOCIAL_DATA social_zero; SOCIAL_DATA *soc; GET_FREE(soc, SOCIAL_DATA, next, social_free); *soc = social_zero; soc->name = &str_empty[0]; soc->char_no_arg = &str_empty[0]; soc->others_no_arg = &str_empty[0]; soc->char_found = &str_empty[0]; soc->others_found = &str_empty[0]; soc->vict_found = &str_empty[0]; soc->char_not_found = &str_empty[0]; soc->char_auto = &str_empty[0]; soc->others_auto = &str_empty[0]; maxSocial++; VALIDATE(soc); return soc; } void free_social(SOCIAL_DATA * soc) { if (!IS_VALID(soc)) return; free_string(soc->name); free_string(soc->char_no_arg); free_string(soc->others_no_arg); free_string(soc->char_found); free_string(soc->others_found); free_string(soc->vict_found); free_string(soc->char_not_found); free_string(soc->char_auto); free_string(soc->others_auto); maxSocial--; INVALIDATE(soc); PUT_FREE(soc, next, social_free); } DEITY_DATA *deity_free; DEITY_DATA *new_deity(void) { static DEITY_DATA deity_zero; DEITY_DATA *deity; GET_FREE(deity, DEITY_DATA, next, deity_free); *deity = deity_zero; deity->name = &str_empty[0]; deity->desc = &str_empty[0]; deity->skillname = &str_empty[0]; maxDeity++; VALIDATE(deity); return deity; } void free_deity(DEITY_DATA * deity) { if (!IS_VALID(deity)) return; free_string(deity->name); free_string(deity->desc); free_string(deity->skillname); maxDeity--; INVALIDATE(deity); PUT_FREE(deity, next, deity_free); } CLAN_DATA *clan_free; CLAN_DATA *new_clan(void) { static CLAN_DATA clan_zero; CLAN_DATA *clan; int x; GET_FREE(clan, CLAN_DATA, next, clan_free); *clan = clan_zero; clan->name = &str_empty[0]; clan->who_name = &str_empty[0]; for (x = 0; x < MAX_RANK; x++) clan->rank[x].rankname = &str_empty[0]; maxClan++; VALIDATE(clan); return clan; } void free_clan(CLAN_DATA * clan) { int x; if (!IS_VALID(clan)) return; free_string(clan->name); free_string(clan->who_name); for (x = 0; x < MAX_RANK; x++) free_string(clan->rank[x].rankname); maxClan--; INVALIDATE(clan); PUT_FREE(clan, next, clan_free); } CMD_DATA *cmd_free; CMD_DATA *new_command(void) { static CMD_DATA cmd_zero; CMD_DATA *cmd; GET_FREE(cmd, CMD_DATA, next, cmd_free); *cmd = cmd_zero; cmd->name = &str_empty[0]; cmd->do_fun = do_null; cmd->level = 0; cmd->position = POS_DEAD; cmd->show = TRUE; cmd->log = LOG_NORMAL; maxCommands++; VALIDATE(cmd); return cmd; } void free_command(CMD_DATA * cmd) { if (!IS_VALID(cmd)) return; free_string(cmd->name); maxCommands--; INVALIDATE(cmd); PUT_FREE(cmd, next, cmd_free); }