mud++0.35/etc/
mud++0.35/etc/guilds/
mud++0.35/help/propert/
mud++0.35/mudC/
mud++0.35/player/
mud++0.35/src/interface/
mud++0.35/src/os/cygwin32/
mud++0.35/src/os/win32/
mud++0.35/src/os/win32/bcppbuilder/
mud++0.35/src/osaddon/
mud++0.35/src/util/
/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All
................................................ contributions are welcome.
....Copyright(C).1995.Melvin.Smith.............. Enjoy.
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@hom.net
MUD++ development mailing list    mudpp@van.ml.org
------------------------------------------------------------------------------
action.cc
*/

#include "config.h"
#include "action.h"
#include "string.h"
#include "room.h"
#include "llist.h"
#include "repop.h"
#include "bit.h"
#include "combat.h"
#include "char.h"
#include "area.h"
#include "object.h"
#include "affect.h"
#include "pc.h"

#include "global.h"

// todo - need to add something to put action onto owner's llist

const bitType trigger_bit_list[] =
{
	{0,				0			},
	{"enter",			TRIGGER_ENTER		},
	{"say",				TRIGGER_SAY		},
	{"leave",			TRIGGER_LEAVE		},
	{"cast"	,			TRIGGER_CAST		},
	{"fight",			TRIGGER_FIGHT		},
	{"timer",			TRIGGER_TIMER		},
	{"groupenter",			TRIGGER_GROUP_ENTER	},
	{"groupleave",			TRIGGER_GROUP_LEAVE	},
	{0,				0			}
};

int Action::total_count = 0;

/*
============
Action::~Action destructor

Action destructor - removes action from global list
============
*/
Action::~Action()
{
	total_count--;
	// Remove from global list
	// already done in extract
	// fromWorld();
}

/*
============
Action::update

Updates an action.  Updates the action timer and calls the action func
if timer ends
============
*/
void Action::update( void )
{
	PC * player;

	if( owner && owner->isChar() && (( Char * )owner)->isPC() )
	{
		player = ( PC * ) owner;

		// Players not playing should not have actions
		if ( player->getState() < STATE_PLAYING )
		{
			interrupt();
			return;
		}

		// Suspend action until player reconnects
		// TEST this code!  It may better to allow actions to
		// finish even though player is not there (or editing).
		// (eg. when a player drops link while fighting, and while
		// casting a spell, it may be better to allow the spell to
		// finish because when the player reconnects, the fight
		// may be over!)
		if ( !player->getSocket() )
			return;

		// Suspend action until player is done editing or reading
		// mail.  Test this too
		if ( player->getState() > STATE_PLAYING )
			return;
	}

	// if time is up, call the function
	if ( counter++ >= total_time )
	{
		detach();

		if ( da_func )
			callDaFunc();

		// We've done our duty so go bye-bye
		this->fordelete();
	}
}

/*
============
Action::setTotalTime

Sets the amount of time for the timer to wait
============
*/
void Action::setTotalTime( int t )
{
	total_time = t;
}

/*
============
Action::interrupt

Interrupts this action.  action is destroyed and removed from all lists
============
*/
void Action::interrupt( void )
{
	detach();
	this->extract();
	this->fordelete();
}

/*
============
Action::setType

Sets the action's type (ACTION_????)
============
*/
void Action::setType( int t )
{
	if ( type < ACTION_MAX && type > -1 )
		type = t;
}

/*
============
Action::toWorld

Adds action to global list (must be called so it gets updated!)
============
*/
void Action::toWorld( void )
{
	actions.addTop( this );
}

/*
============
Action::fromWorld

Removes action from the global list (called by destructor)
============
*/
void Action::fromWorld( void )
{
	actions.remove( this );
}

/*
============
Action::toOwner

Attaches the action to either the owner's doing pointer or to its
linked list (triggers are attached to llist and regular commands, like cast,
are attached to the doing ptr)
============
*/
void Action::toOwner( void )
{
	if ( owner )
	{
		if ( type == ACTION_NORMAL && owner->isChar() )
		{
			if ( ! (( Char * )owner)->doing )
				(( Char * )owner)->doing = this;
			else
				Cout << "BUG: Action::toOwner - owner already has an action\n";
		}
		else
			owner->o_list.addTop( this );
	}
}

/*
============
Action::fromOwner

Remove action from the owner's list
============
*/
void Action::fromOwner()
{
	if ( owner )
	{
		if ( type == ACTION_NORMAL && owner->isChar() )
			if ( (( Char * )owner )->doing )
				(( Char * )owner)->doing = 0;
			else
				Cout << "BUG: Action::fromOwner - owner has no action\n";
		else
			owner->o_list.remove( this );
	}
}

/*
============
Action::toTarget

Attach action to the target's llist of target actions
============
*/
void Action::toTarget( void )
{
	if ( target )
		target->t_list.addTop( this );
}

/*
============
Action::fromTarget

Remove action from target's llist of target actions
============
*/
void Action::fromTarget( void )
{
	if ( target )
		target->t_list.remove( this );
}

/*
============
Action::attach

Attach action to both target and owner
============
*/
void Action::attach( void )
{
	toOwner();
	toTarget();
}

/*
============
Action::detach

Remove action from both target and owner
============
*/
void Action::detach( void )
{
	fromOwner();
	fromTarget();
}