/* -------------------------------------------
 * Room Affects for ROM24, 1.00 - 11/15/98
 * -------------------------------------------
 * This is code which provides your ROOMS with
 * the same ability to hold affects as your
 * standard objects and mobs/chars.
 *
 * As with all else, please email me if you use
 * this code so I know my time is not going
 * to waste. :) If you have any corrections also,
 * please let me know.
 *
 * Brian Babey (aka Varen)
 * [bbabey@iname.com]
 * http://www.erols.com/bribe/
 * ------------------------------------------- */

/* NOTES: This does not include messages for room
 * affects wearing off or any sample room affects
 * or what not, just the storage and use capabilities.
 * The affects are defined the same way as affects
 * for chars/objs, but you use affect_to_room to set
 * them. To check for room affects and thus put this
 * to use, you'd use something like this:
 * if ( IS_SET(ch->in_room->affected_by,AFF_DEATHROOM))
 * and then call it to do whatever. You can put
 * these checks/calls in your update.c and run them
 * every pulse_whatever to achieve the desired effect.
 *
 * I also have not included any display for the affects
 * in the room (for imm's stat command or what-not) but
 * you may want to - follow examples for room/mobs */


/* -----------------------------------------------
 * In merc.h, in the definition of the room_index_data
 * structure, add these components */

        AFFECT_DATA *affected;
        long affected_by;


/* ----------------------------------------------
 * In merc.h, in the list of functions for handler.c
 * place this near the other affect functions */

void    affect_to_room  args( (ROOM_INDEX_DATA *room, AFFECT_DATA *paf ) );
void	affect_remove_room args((ROOM_INDEX_DATA *room, AFFECT_DATA *paf) );


/* ----------------------------------------------
 * In db.c, under the Semi-Local function declarations,
 * insert this line */

void	room_update ( AREA_DATA *pArea );


/* ----------------------------------------------
 * In handler.c, under the local function declarations,
 * insert these lines */

void	room_update	args( ( AREA_DATA *pArea ) );
void 	room_aff_update	args( ( ROOM_INDEX_DATA *room ) );


/* ----------------------------------------------
 * In handler.c, insert these function definitions;
 * you'll want to do it near the other affects just
 * for reference or whatever */

void affect_to_room( ROOM_INDEX_DATA *room, AFFECT_DATA *paf )
{
    AFFECT_DATA *paf_new;

    paf_new = new_affect();

    *paf_new		= *paf;
    paf_new->next	= room->affected;
    room->affected	= paf_new;

    if ( paf->where == TO_AFFECTS )
	SET_BIT(room->affected_by,paf->bitvector);

    return;
}

void affect_remove_room( ROOM_INDEX_DATA *room, AFFECT_DATA *paf )
{
    int where, vector;
    if ( room->affected == NULL )
    {
        bug( "Affect_remove_room: no affect.", 0 );
        return;
    }

    where = paf->where;
    vector = paf->bitvector;

    if (paf->bitvector)
	switch( paf->where)
        {
        case TO_AFFECTS:
            REMOVE_BIT(room->affected_by,paf->bitvector);
            break;
        }

    if ( paf == room->affected )
    {    
        room->affected    = paf->next;
    }
    else
    {
        AFFECT_DATA *prev;

        for ( prev = room->affected; prev != NULL; prev = prev->next )
        {
            if ( prev->next == paf )
            {
                prev->next = paf->next;
                break;
            }
        }

        if ( prev == NULL )
        {
            bug( "Affect_remove_room: cannot find paf.", 0 );
            return;
        }
    }

    free_affect(paf);

    return;

}


/* ----------------------------------------------
 * In update.c, place these function definitions
 * with your other update functions */

void room_update( AREA_DATA *pArea )
{
	ROOM_INDEX_DATA *room;
	int vnum;

  for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum ++ )
	{
	  if ( (room = get_room_index(vnum)) )
		room_aff_update(room);
	}

   return;
}


void room_aff_update( ROOM_INDEX_DATA *room )
{
	AFFECT_DATA *paf;
	AFFECT_DATA *paf_next;

	for ( paf = room->affected; paf != NULL; paf = paf_next )
	{
	    paf_next	= paf->next;
	    if ( paf->duration > 0 )
	    {
		paf->duration--;
		if (number_range(0,4) == 0 && paf->level > 0)
		  paf->level--;  /* spell strength fades with time */
            }
	    else if ( paf->duration < 0 )
		;
	    else
	    {
		if ( paf_next == NULL
		||   paf_next->type != paf->type
		||   paf_next->duration > 0 )
		{
		    if ( paf->type > 0 && skill_table[paf->type].msg_off )
		    {
		/*	send_to_char( skill_table[paf->type].msg_off, ch);
			send_to_char( "\n\r", ch );  */
		    }
		}
	        
		affect_remove_room( room, paf );
	    }
	}

}


/* ---------------------------------------------
 * In db.c, inside area_update, insert this line
 * at the beginning of the first loop of pArea: */

    for ( pArea = area_first; pArea != NULL; pArea = pArea->next )
    {
        room_update ( pArea );  /*<<<< INSERT THIS LINE <<<<*/

	if ( ++pArea->age < 3 )
	    continue;


/* ---------------------------------------------
 * In db.c, inside load_rooms, find the initialization
 * section and insert these TWO lines: */

	pRoomIndex			= alloc_perm( sizeof(*pRoomIndex) );
	pRoomIndex->owner		= str_dup("");
	pRoomIndex->people		= NULL;
	pRoomIndex->contents		= NULL;
	pRoomIndex->extra_descr		= NULL;
	pRoomIndex->area		= area_last;
        pRoomIndex->affected            = NULL;         /* << THIS LINE */
        pRoomIndex->affected_by         = 0;            /* << THIS LINE */
	pRoomIndex->vnum		= vnum;
