/****************************************************************************
 * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame      |   \\._.//   *
 * -----------------------------------------------------------|   (0...0)   *
 * SMAUG 1.4 (C) 1994, 1995, 1996, 1998  by Derek Snider      |    ).:.(    *
 * -----------------------------------------------------------|    {o o}    *
 * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,      |   / ' ' \   *
 * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek,      |~'~.VxvxV.~'~*
 * Tricops and Fireblade                                      |             *
 * ------------------------------------------------------------------------ *
 * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael        *
 * Chastain, Michael Quan, and Mitchell Tse.                                *
 * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.     *
 * ------------------------------------------------------------------------ *
 *                  Game Reset Handler and Editing Module                   *
 *                         SmaugFUSS 1.8 Version                            *
 ****************************************************************************/

#include <stdio.h>
#include <string.h>
#include "mud.h"

/*
 * Create a new reset (for online building) - Thoric
 */
RESET_DATA *make_reset( char letter, int extra, int arg1, int arg2, int arg3 )
{
   RESET_DATA *pReset;

   CREATE( pReset, RESET_DATA, 1 );
   pReset->command = letter;
   pReset->extra = extra;
   pReset->arg1 = arg1;
   pReset->arg2 = arg2;
   pReset->arg3 = arg3;
   return pReset;
}

/* Setup put nesting levels, regardless of whether or not the resets will
   actually reset, or if they're bugged. */
void renumber_put_resets( ROOM_INDEX_DATA * room )
{
   RESET_DATA *pReset, *tReset, *lastobj = NULL;

   for( pReset = room->first_reset; pReset; pReset = pReset->next )
   {
      switch ( pReset->command )
      {
         default:
            break;

         case 'O':
            lastobj = pReset;
            for( tReset = pReset->first_reset; tReset; tReset = tReset->next_reset )
            {
               switch ( tReset->command )
               {
                  case 'P':
                     if( tReset->arg3 == 0 )
                     {
                        if( !lastobj )
                           tReset->extra = 1000000;
                        else if( lastobj->command != 'P' || lastobj->arg3 > 0 )
                           tReset->extra = 0;
                        else
                           tReset->extra = lastobj->extra + 1;
                        lastobj = tReset;
                     }
                     break;
               }
            }
            break;
      }
   }
}

/*
 * Add a reset to an area -Thoric
 */
RESET_DATA *add_reset( ROOM_INDEX_DATA * room, char letter, int extra, int arg1, int arg2, int arg3 )
{
   RESET_DATA *pReset;

   if( !room )
   {
      bug( "%s: NULL room!", __FUNCTION__ );
      return NULL;
   }

   letter = UPPER( letter );
   pReset = make_reset( letter, extra, arg1, arg2, arg3 );
   pReset->sreset = true;

   switch ( letter )
   {
      case 'M':
         room->last_mob_reset = pReset;
         break;

      case 'E':
      case 'G':
         if( !room->last_mob_reset )
         {
            bug( "%s: Can't add '%c' reset to room: last_mob_reset is NULL.", __FUNCTION__, letter );
            return NULL;
         }
         room->last_obj_reset = pReset;
         LINK( pReset, room->last_mob_reset->first_reset, room->last_mob_reset->last_reset, next_reset, prev_reset );
         return pReset;

      case 'P':
         if( !room->last_obj_reset )
         {
            bug( "%s: Can't add '%c' reset to room: last_obj_reset is NULL.", __FUNCTION__, letter );
            return NULL;
         }
         LINK( pReset, room->last_obj_reset->first_reset, room->last_obj_reset->last_reset, next_reset, prev_reset );
         return pReset;

      case 'O':
         room->last_obj_reset = pReset;
         break;

      case 'T':
         if( IS_SET( extra, TRAP_OBJ ) )
         {
            pReset->prev_reset = NULL;
            pReset->next_reset = room->last_obj_reset->first_reset;
            if( room->last_obj_reset->first_reset )
               room->last_obj_reset->first_reset->prev_reset = pReset;
            room->last_obj_reset->first_reset = pReset;
            if( !room->last_obj_reset->last_reset )
               room->last_obj_reset->last_reset = pReset;
            return pReset;
         }
         break;

      case 'H':
         pReset->prev_reset = NULL;
         pReset->next_reset = room->last_obj_reset->first_reset;
         if( room->last_obj_reset->first_reset )
            room->last_obj_reset->first_reset->prev_reset = pReset;
         room->last_obj_reset->first_reset = pReset;
         if( !room->last_obj_reset->last_reset )
            room->last_obj_reset->last_reset = pReset;
         return pReset;
   }
   LINK( pReset, room->first_reset, room->last_reset, next, prev );
   return pReset;
}