area/
build/testing/
log/
player/
player/backup/
/***************************************************************************
 *  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.                                                  *
 ***************************************************************************/
#include <glib.h>

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <merc.h>
#include <recycle.h>
#include <olc.h>
#include <interp.h>
#include <fight.h>
#include <tables.h>

extern GMemChunk *sphere_mem_chunk;
SPHERE_DATA     *sphere_free;
/* Mage handlers */
/*
 * Apply or remove an affect to a character.
 */
void sphere_modify( CHAR_DATA *ch, SPHERE_DATA *paf, bool fAdd )
{
	/*Sphere_affected_by needz {4] */
	
	if ( fAdd )
	{
		SET_BIT( ch->sphere_affected_by[paf->type], paf->bitvector );
		switch ( paf->type )
		{
			default:
				bug("Sphere Modify: Unknown Type",0);
				return;	
			case TYPE_SPHERE_ADDED:
				SET_BIT(ch->added,paf->bitvector);
				break;
			case TYPE_SPHERE_AFFECT:
				SET_BIT(ch->affected_by,paf->bitvector);
				break;
			case TYPE_SPHERE_ACT:
				SET_BIT(ch->act,paf->bitvector);
				break;
			case TYPE_SPHERE_SPAFFECT:
				SET_BIT(ch->sphere_spaffect,paf->bitvector);
				break;
			case TYPE_SIGHT:
				SET_BIT(ch->sight,paf->bitvector);
				break;
			case TYPE_PLANE:
				ch->plane = paf->bitvector;
				break;
		}	
	}
	else
	{
		if (paf->bitvector == PLR_WIZINVIS)
            ch->invis_level = 0;

        REMOVE_BIT( ch->sphere_affected_by[paf->type], paf->bitvector );
		switch ( paf->type )
		{
			default:
				bug("Sphere Modify: Unknown Type",0);
				return;	
			case TYPE_SPHERE_ADDED:
				REMOVE_BIT(ch->added,paf->bitvector);
				break;
			case TYPE_SPHERE_AFFECT:
				REMOVE_BIT(ch->affected_by,paf->bitvector);
				break;
			case TYPE_SPHERE_ACT:
				REMOVE_BIT(ch->act,paf->bitvector);
				break;
			case TYPE_SPHERE_SPAFFECT:
				REMOVE_BIT(ch->sphere_spaffect,paf->bitvector);
				break;
			case TYPE_SIGHT:
				REMOVE_BIT(ch->sight,paf->bitvector);
				break;
			case TYPE_PLANE:
				ch->plane = PLANE_NORMAL;
				break;
		}	
	}
	return;
}

SPHERE_DATA *new_sphere(void)
{
	static SPHERE_DATA af_zero;
	SPHERE_DATA *af;
	
	if (sphere_free == NULL)
		af = g_chunk_new (SPHERE_DATA, sphere_mem_chunk);
	else
	{
		af = sphere_free;
		sphere_free = sphere_free->next;
	}
	
	*af = af_zero;
	
	
	VALIDATE(af);
	return af;
}

void free_sphere(SPHERE_DATA *af)
{
	if (!IS_VALID(af))
		return;
	
	INVALIDATE(af);
	af->next = sphere_free;
	sphere_free = af;
}

/*
 * Remove an affect from a char.
 */
void sphere_remove( CHAR_DATA *ch, SPHERE_DATA *paf )
{
	if ( ch->sphere_affected == NULL )
	{
		bug( "Sphere_remove: no affect.", 0 );
		return;
	}
	
	sphere_modify( ch, paf, FALSE );
	
	if ( paf == ch->sphere_affected )
	{
		ch->sphere_affected	= paf->next;
	}
	else
	{
		SPHERE_DATA *prev;
		
		for ( prev = ch->sphere_affected; prev != NULL; prev = prev->next )
		{
			if ( prev->next == paf )
			{
				prev->next = paf->next;
				break;
			}
		}
		
		if ( prev == NULL )
		{
			bug( "Sphere_remove: cannot find paf.", 0 );
			return;
		}
	}
	
  	free_sphere(paf);	
	return;
}

/*
 * Give an affect to a char.
 */
void sphere_to_char( CHAR_DATA *ch, SPHERE_DATA *paf )
{
	SPHERE_DATA *paf_new;
	
	paf_new = new_sphere();	
	*paf_new		= *paf;
	paf_new->next	= ch->sphere_affected;
	ch->sphere_affected	= paf_new;
	
	sphere_modify( ch, paf_new, TRUE );
	return;
}

SPHERE_DATA *find_spaffect( CHAR_DATA *ch, int bitvector)
{
	
	SPHERE_DATA *paf;
	SPHERE_DATA *paf_next;
	
	for ( paf = ch->sphere_affected; paf != NULL; paf = paf_next )
	{
		paf_next	= paf->next;
		if ( paf->bitvector == bitvector )
			return paf;
	}
	return NULL;
}