/*
* $Id: recycle.c,v 1.45 1999/04/16 15:52:21 fjoe Exp $
*/
/***************************************************************************
* 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 *
***************************************************************************/
#include <sys/types.h>
#include <sys/time.h>
#include <regex.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "db/db.h"
/* stuff for recycling extended descs */
extern int top_ed;
ED_DATA *ed_new(void)
{
ED_DATA *ed;
ed = calloc(1, sizeof(*ed));
top_ed++;
return ed;
}
ED_DATA *ed_new2(const ED_DATA *ed, const char* name)
{
ED_DATA *ed2 = ed_new();
ed2->keyword = str_qdup(ed->keyword);
ed2->description = mlstr_printf(ed->description, name);
return ed2;
}
ED_DATA *ed_dup(const ED_DATA *ed)
{
ED_DATA *ned = NULL;
ED_DATA **ped = &ned;
for (; ed; ed = ed->next) {
*ped = ed_new();
(*ped)->keyword = str_qdup(ed->keyword);
(*ped)->description = mlstr_dup(ed->description);
ped = &(*ped)->next;
}
return ned;
}
void ed_free(ED_DATA *ed)
{
ED_DATA *ed_next;
for (; ed; ed = ed_next) {
ed_next = ed->next;
free_string(ed->keyword);
mlstr_free(ed->description);
free(ed);
top_ed--;
}
}
void ed_fread(FILE *fp, ED_DATA **edp)
{
ED_DATA *ed = ed_new();
ed->keyword = fread_string(fp);
ed->description = mlstr_fread(fp);
SLIST_ADD(ED_DATA, *edp, ed);
}
void ed_fwrite(FILE *fp, ED_DATA *ed)
{
fprintf(fp, "E\n%s~\n", fix_string(ed->keyword));
mlstr_fwrite(fp, NULL, ed->description);
}
AFFECT_DATA *aff_new(void)
{
return calloc(1, sizeof(AFFECT_DATA));
}
AFFECT_DATA *aff_dup(const AFFECT_DATA *paf)
{
AFFECT_DATA *naf = aff_new();
naf->where = paf->where;
naf->type = paf->type;
naf->level = paf->level;
naf->duration = paf->duration;
naf->location = paf->location;
naf->modifier = paf->modifier;
naf->bitvector = paf->bitvector;
return naf;
}
void aff_free(AFFECT_DATA *af)
{
free(af);
}
OBJ_DATA *free_obj_list;
extern int obj_count;
extern int obj_free_count;
OBJ_DATA *new_obj(void)
{
OBJ_DATA *obj;
if (free_obj_list) {
obj = free_obj_list;
free_obj_list = free_obj_list->next;
memset(obj, '\0', sizeof(*obj));
obj_free_count--;
}
else {
obj = calloc(1, sizeof(*obj));
obj_count++;
}
return obj;
}
void free_obj(OBJ_DATA *obj)
{
AFFECT_DATA *paf, *paf_next;
if (!obj)
return;
for (paf = obj->affected; paf; paf = paf_next) {
paf_next = paf->next;
aff_free(paf);
}
obj->affected = NULL;
ed_free(obj->ed);
obj->ed = NULL;
free_string(obj->name);
obj->name = NULL;
mlstr_free(obj->description);
obj->description = NULL;
mlstr_free(obj->short_descr);
obj->short_descr = NULL;
mlstr_free(obj->owner);
obj->owner = NULL;
free_string(obj->material);
obj->material = NULL;
obj->next = free_obj_list;
free_obj_list = obj;
obj_free_count++;
}
CHAR_DATA *free_char_list;
extern int mob_count;
extern int mob_free_count;
CHAR_DATA *new_char (void)
{
CHAR_DATA *ch;
int i;
if (free_char_list) {
ch = free_char_list;
free_char_list = free_char_list->next;
memset(ch, '\0', sizeof(*ch));
mob_free_count--;
}
else {
ch = calloc(1, sizeof(*ch));
mob_count++;
}
RESET_FIGHT_TIME(ch);
ch->last_death_time = -1;
ch->prefix = str_empty;
ch->lines = PAGELEN;
ch->logon = current_time;
ch->hit = 20;
ch->max_hit = 20;
ch->mana = 100;
ch->max_mana = 100;
ch->move = 100;
ch->max_move = 100;
ch->position = POS_STANDING;
for (i = 0; i < 4; i++)
ch->armor[i] = 100;
for (i = 0; i < MAX_STATS; i ++)
ch->perm_stat[i] = 13;
return ch;
}
void free_char(CHAR_DATA *ch)
{
OBJ_DATA *obj;
OBJ_DATA *obj_next;
AFFECT_DATA *paf;
AFFECT_DATA *paf_next;
if (!ch)
return;
nuke_pets(ch);
for (obj = ch->carrying; obj; obj = obj_next) {
obj_next = obj->next_content;
extract_obj(obj, XO_F_NOCOUNT);
}
for (paf = ch->affected; paf; paf = paf_next) {
paf_next = paf->next;
affect_remove(ch,paf);
}
ch->affected = NULL;
free_string(ch->name);
ch->name = NULL;
mlstr_free(ch->short_descr);
ch->short_descr = NULL;
mlstr_free(ch->long_descr);
ch->long_descr = NULL;
mlstr_free(ch->description);
ch->description = NULL;
free_string(ch->prompt);
ch->prompt = NULL;
free_string(ch->prefix);
ch->prefix = NULL;
free_string(ch->material);
ch->material = NULL;
free_string(ch->in_mind);
ch->in_mind = NULL;
free_pcdata(ch->pcdata);
ch->pcdata = NULL;
ch->next = free_char_list;
free_char_list = ch;
mob_free_count++;
}
PC_DATA *new_pcdata(void)
{
PC_DATA *pcdata;
pcdata = calloc(1, sizeof(*pcdata));
pcdata->buffer = buf_new(-1);
pcdata->learned.nsize = sizeof(pcskill_t);
pcdata->learned.nstep = 8;
pcdata->pwd = str_empty;
pcdata->bamfin = str_empty;
pcdata->bamfout = str_empty;
pcdata->title = str_empty;
pcdata->twitlist = str_empty;
pcdata->granted = str_empty;
return pcdata;
}
void free_pcdata(PC_DATA *pcdata)
{
int alias;
if (!pcdata)
return;
varr_free(&pcdata->learned);
free_string(pcdata->pwd);
free_string(pcdata->bamfin);
free_string(pcdata->bamfout);
free_string(pcdata->title);
free_string(pcdata->twitlist);
free_string(pcdata->granted);
buf_free(pcdata->buffer);
for (alias = 0; alias < MAX_ALIAS; alias++) {
free_string(pcdata->alias[alias]);
free_string(pcdata->alias_sub[alias]);
}
free(pcdata);
}
/* stuff for setting ids */
long last_pc_id;
long last_mob_id;
long get_pc_id(void)
{
return last_pc_id = (current_time <= last_pc_id) ?
last_pc_id + 1 : current_time;
}
long get_mob_id(void)
{
last_mob_id++;
return last_mob_id;
}
MPTRIG *mptrig_new(int type, const char *phrase, int vnum)
{
const char *p;
MPTRIG *mptrig;
mptrig = calloc(1, sizeof(*mptrig));
mptrig->type = type;
mptrig->vnum = vnum;
mptrig->phrase = str_dup(phrase);
for (p = mptrig->phrase; *p; p++)
if (ISUPPER(*p)) {
SET_BIT(mptrig->flags, TRIG_CASEDEP);
break;
}
if ((type == TRIG_ACT || type == TRIG_SPEECH) && phrase[0] == '*') {
int errcode;
int cflags = REG_EXTENDED | REG_NOSUB;
SET_BIT(mptrig->flags, TRIG_REGEXP);
if (!IS_SET(mptrig->flags, TRIG_CASEDEP))
cflags |= REG_ICASE;
mptrig->extra = malloc(sizeof(regex_t));
errcode = regcomp(mptrig->extra, phrase+1, cflags);
if (errcode) {
char buf[MAX_STRING_LENGTH];
regerror(errcode, mptrig->extra, buf, sizeof(buf));
log_printf("bad trigger for vnum %d (phrase '%s'): %s",
vnum, phrase, buf);
}
}
return mptrig;
}
void mptrig_add(MOB_INDEX_DATA *mob, MPTRIG *mptrig)
{
SET_BIT(mob->mptrig_types, mptrig->type);
SLIST_ADD(MPTRIG, mob->mptrig_list, mptrig);
}
void mptrig_fix(MOB_INDEX_DATA *mob)
{
MPTRIG *mptrig;
for (mptrig = mob->mptrig_list; mptrig; mptrig = mptrig->next)
SET_BIT(mob->mptrig_types, mptrig->type);
}
void mptrig_free(MPTRIG *mp)
{
if (!mp)
return;
if (IS_SET(mp->flags, TRIG_REGEXP)) {
regfree(mp->extra);
free(mp->extra);
}
free_string(mp->phrase);
free(mp);
}