btmux/autom4te.cache/
btmux/doc/.svn/
btmux/event/.svn/
btmux/game/.svn/
btmux/game/bin/.svn/
btmux/game/data/.svn/
btmux/game/logs/.svn/
btmux/game/maps/
btmux/game/maps/.svn/
btmux/game/maps/.svn/prop-base/
btmux/game/maps/.svn/props/
btmux/game/maps/.svn/text-base/
btmux/game/maps/.svn/wcprops/
btmux/game/mechs/
btmux/game/mechs/.svn/
btmux/game/mechs/.svn/prop-base/
btmux/game/mechs/.svn/props/
btmux/game/mechs/.svn/text-base/
btmux/game/mechs/.svn/wcprops/
btmux/game/text/.svn/
btmux/include/.svn/
btmux/misc/
btmux/misc/.svn/
btmux/misc/.svn/prop-base/
btmux/misc/.svn/props/
btmux/misc/.svn/text-base/
btmux/misc/.svn/wcprops/
btmux/python/
btmux/python/.svn/
btmux/python/.svn/prop-base/
btmux/python/.svn/props/
btmux/python/.svn/text-base/
btmux/python/.svn/wcprops/
btmux/src/.svn/prop-base/
btmux/src/.svn/props/
btmux/src/.svn/text-base/
btmux/src/.svn/wcprops/
btmux/src/hcode/.svn/
btmux/src/hcode/btech/
btmux/src/hcode/btech/.svn/
btmux/src/hcode/btech/.svn/prop-base/
btmux/src/hcode/btech/.svn/props/
btmux/src/hcode/btech/.svn/text-base/
btmux/src/hcode/btech/.svn/wcprops/
btmux/src/hcode/include/.svn/
/*
 * player_c.c -- Player cache routines 
 */

/*
 * $Id: player_c.c,v 1.3 2005/08/08 09:43:07 murrayma Exp $ 
 */

#include "copyright.h"
#include "config.h"

#include "mudconf.h"
#include "htab.h"
#include "externs.h"
#include "alloc.h"
#include "attrs.h"
#include "db.h"

#ifndef STANDALONE

typedef struct player_cache {
    dbref player;
    int money;
    int queue;
    int qmax;
    int cflags;
    struct player_cache *next;
} PCACHE;

NHSHTAB pcache_htab;
PCACHE *pcache_head;

#define	PF_DEAD		0x0001
#define	PF_REF		0x0002
#define	PF_MONEY_CH	0x0004
#define	PF_QMAX_CH	0x0008

void pcache_init(void)
{
    nhashinit(&pcache_htab, 15 * HASH_FACTOR);
    pcache_head = NULL;
}

static void pcache_reload1(player, pp)
dbref player;
PCACHE *pp;
{
    char *cp;

    cp = atr_get_raw(player, A_MONEY);
    if (cp && *cp)
	pp->money = atoi(cp);
    else
	pp->money = 0;

    cp = atr_get_raw(player, A_QUEUEMAX);
    if (cp && *cp)
	pp->qmax = atoi(cp);
    else if (!Wizard(player))
	pp->qmax = mudconf.queuemax;
    else
	pp->qmax = -1;
}


PCACHE *pcache_find(player)
dbref player;
{
    PCACHE *pp;

    if (!Good_obj(player) || !OwnsOthers(player))
	return NULL;
    pp = (PCACHE *) nhashfind(player, &pcache_htab);
    if (pp) {
	pp->cflags |= PF_REF;
	return pp;
    }
    pp = malloc(sizeof(PCACHE));
    pp->queue = 0;
    pp->cflags = PF_REF;
    pp->player = player;
    pcache_reload1(player, pp);
    pp->next = pcache_head;
    pcache_head = pp;
    nhashadd(player, (int *) pp, &pcache_htab);
    return pp;
}

void pcache_reload(player)
dbref player;
{
    PCACHE *pp;

    pp = pcache_find(player);
    if (!pp)
	return;
    pcache_reload1(player, pp);
}

static void pcache_save(pp)
PCACHE *pp;
{
    IBUF tbuf;

    if (pp->cflags & PF_DEAD)
	return;
    if (pp->cflags & PF_MONEY_CH) {
	sprintf(tbuf, "%d", pp->money);
	atr_add_raw(pp->player, A_MONEY, tbuf);
    }
    if (pp->cflags & PF_QMAX_CH) {
	sprintf(tbuf, "%d", pp->qmax);
	atr_add_raw(pp->player, A_QUEUEMAX, tbuf);
    }
    pp->cflags &= ~(PF_MONEY_CH | PF_QMAX_CH);
}

void pcache_trim(void)
{
    PCACHE *pp, *pplast, *ppnext;

    pp = pcache_head;
    pplast = NULL;
    while (pp) {
	if (!(pp->cflags & PF_DEAD) && (pp->queue ||
		(pp->cflags & PF_REF))) {
	    pp->cflags &= ~PF_REF;
	    pplast = pp;
	    pp = pp->next;
	} else {
	    ppnext = pp->next;
	    if (pplast)
		pplast->next = ppnext;
	    else
		pcache_head = ppnext;
	    if (!(pp->cflags & PF_DEAD)) {
		pcache_save(pp);
		nhashdelete(pp->player, &pcache_htab);
	    }
        free(pp);
	    pp = ppnext;
	}
    }
}

void pcache_sync(void)
{
    PCACHE *pp;

    pp = pcache_head;
    while (pp) {
	pcache_save(pp);
	pp = pp->next;
    }
}

void pcache_purge(player)
dbref player;
{
    PCACHE *pp;

    pp = (PCACHE *) nhashfind(player, &pcache_htab);
    if (!pp)
	return;
    pp->cflags = PF_DEAD;
    nhashdelete(pp->player, &pcache_htab);
}

int a_Queue(player, adj)
dbref player;
int adj;
{
    PCACHE *pp;

    if (OwnsOthers(player)) {
	pp = pcache_find(player);
	if (pp)
	    pp->queue += adj;
	return pp->queue;
    }
    return 0;
}

void s_Queue(player, val)
dbref player;
int val;
{
    PCACHE *pp;

    if (OwnsOthers(player)) {
	pp = pcache_find(player);
	if (pp)
	    pp->queue = val;
    }
}

int QueueMax(player)
dbref player;
{
    PCACHE *pp;
    int m;

    m = 0;
    if (OwnsOthers(player)) {
	pp = pcache_find(player);
	if (pp) {
	    if (pp->qmax >= 0) {
		m = pp->qmax;
	    } else {
		m = mudstate.db_top + 1;
		if (m < mudconf.queuemax)
		    m = mudconf.queuemax;
	    }
	}
    }
    return m;
}

#endif

int Pennies(obj)
dbref obj;
{
    char *cp;

#ifndef STANDALONE
    PCACHE *pp;

    if (OwnsOthers(obj)) {
	pp = pcache_find(obj);
	if (pp)
	    return pp->money;
    }
#endif
    cp = atr_get_raw(obj, A_MONEY);
    return (safe_atoi(cp));
}

void s_Pennies(obj, howfew)
dbref obj;
int howfew;
{
    IBUF tbuf;

#ifndef STANDALONE
    PCACHE *pp;

    if (OwnsOthers(obj)) {
	pp = pcache_find(obj);
	if (pp) {
	    pp->money = howfew;
	    pp->cflags |= PF_MONEY_CH;
	}
    }
#endif
    sprintf(tbuf, "%d", howfew);
    atr_add_raw(obj, A_MONEY, tbuf);
}