btmux-0.6-rc4/doc/
btmux-0.6-rc4/event/
btmux-0.6-rc4/game/
btmux-0.6-rc4/game/maps/
btmux-0.6-rc4/game/mechs/
btmux-0.6-rc4/game/text/help/
btmux-0.6-rc4/game/text/help/cat_faction/
btmux-0.6-rc4/game/text/help/cat_inform/
btmux-0.6-rc4/game/text/help/cat_misc/
btmux-0.6-rc4/game/text/help/cat_mux/
btmux-0.6-rc4/game/text/help/cat_mux/cat_commands/
btmux-0.6-rc4/game/text/help/cat_mux/cat_functions/
btmux-0.6-rc4/game/text/help/cat_templates/
btmux-0.6-rc4/game/text/wizhelp/
btmux-0.6-rc4/include/
btmux-0.6-rc4/misc/
btmux-0.6-rc4/python/
btmux-0.6-rc4/src/hcode/btech/
btmux-0.6-rc4/tree/
/*
 * player_c.c -- Player cache routines 
 */

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

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

int compare_pcache(dbref left, dbref right)
{
	return (left - right);
}

void pcache_init(void)
{
	pcache_tree = rb_init((void *)compare_pcache, NULL);
	pcache_head = NULL;
}

static void pcache_reload1(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(dbref player)
{
	PCACHE *pp;

	if(!Good_obj(player) || !OwnsOthers(player))
		return NULL;

	pp = (PCACHE *) rb_find(pcache_tree, (void *)player);
	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;
	rb_insert(pcache_tree, (void *)player, (void *)pp);
	return pp;
}

void pcache_reload(dbref player)
{
	PCACHE *pp;

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

static void pcache_save(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;
	return;

	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);
				rb_delete(pcache_tree, (void *)pp->player);
			}
			free(pp);
			pp = ppnext;
		}
	}
}

void pcache_sync(void)
{
	PCACHE *pp;

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

#if 0

// Not used?

void pcache_purge(dbref player)
{
	PCACHE *pp;

	pp = rb_find(pcache_tree, player);
	if(!pp)
		return;
	pp->cflags = PF_DEAD;
	rb_delete(pcache_tree, pp->player);
	free(pp);
}
#endif

int a_Queue(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(dbref player, int val)
{
	PCACHE *pp;

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

int QueueMax(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;
}

int Pennies(dbref obj)
{
	char *cp;

	PCACHE *pp;

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

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

	PCACHE *pp;

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