/
mudtem/
mudtem/area/scripts/
mudtem/bin/
mudtem/log/
mudtem/player/
mudtem/slang/autoconf/
mudtem/slang/doc/
mudtem/slang/doc/OLD/help/
mudtem/slang/doc/internal/
mudtem/slang/doc/text/
mudtem/slang/doc/tm/tools/
mudtem/slang/examples/
mudtem/slang/modules/
mudtem/slang/slsh/
mudtem/slang/slsh/lib/
mudtem/slang/slsh/scripts/
mudtem/slang/src/mkfiles/
mudtem/slang/src/util/
mudtem/src/CVS/
mudtem/src/include/
mudtem/src/include/CVS/
mudtem/src/var/CVS/
#include "include.h"
#include "recycle.h"

const char * entidadToString( Entity * ent )
{
	if (ent == NULL)
		return "";

	switch( ent->tipo )
	{
		case ENT_STRING:	return ent->u.string;
		case ENT_CH:		return SELFPERS(ent->u.ch);
		case ENT_OBJ:		return ent->u.obj->short_descr;
		case ENT_INT:		return itos(ent->u.entero);
		case ENT_ROOM:		return ent->u.room->name;
	}

	bugf( "entidadToString : tipo %d invalido", ent->tipo );
	return "";
}

const char * entidadToStringNoColor( Entity * ent )
{
	if ( ent == NULL )
		return "";

	switch( ent->tipo )
	{
		case ENT_STRING:	return ent->u.string;
		case ENT_CH:		return IS_NPC(ent->u.ch) ? ent->u.ch->short_descr : ent->u.ch->name;
		case ENT_OBJ:		return ent->u.obj->short_descr;
		case ENT_INT:		return itos(ent->u.entero);
		case ENT_ROOM:		return ent->u.room->name;
	}

	bugf( "entidadToStringNoColor : tipo %d invalido", ent->tipo );
	return "";
}

const char * entidadToStringExt( Entity * ent )
{
static	char buf[MSL];

	if ( ent == NULL )
		return "";

	switch( ent->tipo )
	{
		case ENT_STRING:	strcpy(buf, ent->u.string);							break;
		case ENT_CH:		sprintf(buf, "%s(%d)", SELFPERS(ent->u.ch), CHARVNUM(ent->u.ch) );		break;
		case ENT_OBJ:		sprintf(buf, "%s(%d)", ent->u.obj->short_descr, ent->u.obj->pIndexData->vnum);	break;
		case ENT_INT:		strcpy(buf, itos(ent->u.entero));						break;
		case ENT_ROOM:		sprintf(buf, "%s(%d)", ent->u.room->name, ent->u.room->vnum );			break;
		default:		bugf( "entidadToStringExt : tipo %d invalido", ent->tipo );
					return "";
	}

	return buf;
}

int entidadGetNivel( Entity * ent )
{
	switch( ent->tipo )
	{
		case ENT_CH:		return getNivelPr(ent->u.ch);
		case ENT_OBJ:		return ent->u.obj->level;
	}

	return 0;
}

Entity * ent_temp;

Entity * objToEntidad( OBJ_DATA * obj, bool permanente )
{
	Entity * temp;
	
	if (obj == NULL)
		return NULL;

	temp		= new_entity();
	temp->tipo	= ENT_OBJ;
	temp->u.obj	= obj;

	if (permanente == FALSE)
	{
		temp->next	= ent_temp;
		ent_temp	= temp;
	} /* lo pegamos a la lista ent_temp */

	return temp;
}

Entity * intToEntidad( int entero, bool permanente, ROOM_INDEX_DATA * room )
{
	Entity * temp = new_entity();

	temp->tipo = ENT_INT;
	temp->u.entero = entero;
	temp->whereis = room;

	if (permanente == FALSE)
	{
		temp->next	= ent_temp;
		ent_temp	= temp;
	} /* lo pegamos a la lista ent_temp */

	return temp;
}

Entity * chToEntidad( CHAR_DATA * ch, bool permanente )
{
	Entity * temp;

	if ( ch == NULL )
		return NULL;

	if ( permanente == FALSE
	&&  !IS_NPC(ch)
	&&   ch->ent != NULL )
		return ch->ent;

	temp		= new_entity();
	temp->tipo	= ENT_CH;
	temp->u.ch	= ch;
	temp->whereis	= ch->in_room;

	if (permanente == FALSE)
	{
		temp->next	= ent_temp;
		ent_temp	= temp;
	} /* lo pegamos a la lista ent_temp */

	return temp;
}

Entity * stringToEntidad( char * string, bool permanente, ROOM_INDEX_DATA * room )
{
	Entity * temp;

	if ( string == NULL )
		return NULL;

	temp		= new_entity();
	temp->tipo	= ENT_STRING;
	temp->u.string	= string;
	temp->whereis	= room;

	if (permanente == FALSE)
	{
		temp->next	= ent_temp;
		ent_temp	= temp;
	}

	return temp;
}

Entity * roomToEntidad( ROOM_INDEX_DATA * room, bool permanente )
{
	Entity * temp;

	if ( room == NULL )
		return NULL;

	temp		= new_entity();
	temp->tipo	= ENT_ROOM;
	temp->u.room	= room;
	temp->whereis	= room;

	if (permanente == FALSE)
	{
		temp->next	= ent_temp;
		ent_temp	= temp;
	}

	return temp;
}

int free_ent_watermark = 0;

void limpiar_ent_temp( void )
{
	Entity * ent, * ent_next;
	int cnt = 0;

	if ( ent_temp == NULL )
		return;

	for ( ent = ent_temp; ent; ent = ent_next )
	{
		ent_next = ent->next;
		cnt++;
		free_entity(ent);
	}

	if ( free_ent_watermark < cnt )
		free_ent_watermark = cnt;

	ent_temp = NULL;
}

int entidadGetVnum( Entity * ent )
{
	if (ent == NULL)
		return -1;

	switch(ent->tipo)
	{
		case ENT_CH:	return CHARVNUM(ent->u.ch);
		case ENT_OBJ:	return ent->u.obj->pIndexData->vnum;
		case ENT_ROOM:	return ent->u.room->vnum;
	}

	return -1;
}

char * entidadGetTipo( Entity * ent )
{
	if (ent == NULL)
		return "ERROR";

	switch(ent->tipo)
	{
		case ENT_CH:		return "char";
		case ENT_OBJ:		return "obj";
		case ENT_STRING:	return "string";
		case ENT_INT:		return "int";
		case ENT_ROOM:		return "room";
	}

	bugf( "entidadGetTipo : tipo %d inexistente", ent->tipo );

	return "";
}

char * newPERS( Entity * ent, CHAR_DATA * looker )
{
	if ( ent == NULL || looker == NULL )
		return "ERROR";

	switch(ent->tipo)
	{
		case ENT_CH:
		return PERS(ent->u.ch, looker);

		case ENT_OBJ:
		if ( can_see_obj(looker, ent->u.obj) )
			return ent->u.obj->short_descr;
		else
			return "algo";

		case ENT_ROOM:
		if ( can_see_room(looker, ent->u.room) )
			return ent->u.room->name;
		else
			return "algun lugar";
	}

	bugf( "newPERS : tipo %d invalido", ent->tipo );
	return "";
}

ROOM_INDEX_DATA * entWhereIs( Entity * ent )
{
	ROOM_INDEX_DATA *room = NULL;

	if (ent == NULL)
		return NULL;

	switch(ent->tipo)
	{
		case ENT_CH:
		room = ent->u.ch->in_room;
		break;

		case ENT_OBJ:
		room = obj_whereis(ent->u.obj);
		break;

		case ENT_ROOM:
		room = ent->u.room;
		break;
	}

	if (room == NULL)
	{
		if (ent->whereis == NULL)
			bugf( "entWhereIs : entidad %s, tipo %d invalido",
				entToStringExt(ent), ent->tipo );
		else
			room = ent->whereis;
	}

	return room;
}

bool entComparar( Entity * ent1, Entity * ent2 )
{
	if ( ent1 == NULL || ent2 == NULL )
		return FALSE;

	if ( ent1->tipo != ent2->tipo )
		return FALSE;

	switch( ent1->tipo )
	{
		case ENT_CH:		return entEsCh(ent2) && ent1->u.ch == ent2->u.ch;
		case ENT_OBJ:		return entEsObj(ent2) && ent1->u.obj == ent2->u.obj;
		case ENT_STRING:	return entEsStr(ent2) && !str_cmp(ent1->u.string, ent2->u.string);
		case ENT_INT:		return entEsInt(ent2) && ent1->u.entero == ent2->u.entero;
		case ENT_ROOM:		return entEsRoom(ent2) && ent1->u.room == ent2->u.room;
	}

	bugf( "entidadComparar : tipo %d inexistente", ent1->tipo );
	return FALSE;
}

CHAR_DATA * ent_get_char_room( Entity * ent, char * argument )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;
    ROOM_INDEX_DATA *room;
    CHAR_DATA *ch = entidadEsCh(ent) ? entidadGetCh(ent) : NULL;
    int number;
    int count;

    room = entWhereIs(ent);

    number = number_argument( argument, arg );
    count  = 0;

    if ( !str_cmp( arg, "self" ) )
	return ch;

    if (room == NULL)
    	return NULL;

    for ( rch = room->people; rch != NULL; rch = rch->next_in_room )
    {
	if ( (ch && !can_see( ch, rch )) || !is_name( arg, rch->name ) )
	    continue;
	if ( ++count == number )
	    return rch;
    }

    return NULL;
}

bool entHasTarget( Entity * ent )
{
	if (ent == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:	return ent->u.ch->mprog_target != NULL;
	};

	return FALSE;
}

#if !defined(USAR_MACROS)
Entity * entGetTarget( Entity * ent )
{
	if ( ent == NULL )
		return NULL;

	switch(ent->tipo)
	{
		case ENT_CH:	return ent->u.ch->mprog_target;
	};

	return NULL;
}

int entGetSex(Entity * ent)
{
	if ( ent == NULL)
		return SEX_NEUTRAL;

	switch(ent->tipo)
	{
		case ENT_CH:
		return URANGE(0, ent->u.ch->sex, 2);
	}

	return SEX_NEUTRAL;
}

long entGetId( Entity * ent )
{
	if (ent == NULL)
		return 0;

	switch(ent->tipo)
	{
		case ENT_CH:	return ent->u.ch->id;
	}

	return 0;
}

char * entGetClanGod( Entity * ent )
{
	if (ent == NULL)
		return "Mota";

	switch(ent->tipo)
	{
		case ENT_CH:	return CLAN_GOD(ent->u.ch);
	}

	return "Mota";
}

int entGetRace( Entity * ent )
{
	if (ent == NULL)
		return 0;

	if ( entEsCh(ent) )
		return ent->u.ch->race;

	return 0;
}
#endif

void send_to_ent( char * msg, Entity * ent )
{
	if (ent == NULL)
		return;

	if ( entEsCh(ent) )
		send_to_char( msg, ent->u.ch );
}

void entSetTarget( Entity * ent, Entity * target )
{
	if (ent == NULL)
		return;

	switch(ent->tipo)
	{
		case ENT_CH:
		if (ent->u.ch->mprog_target != NULL)
			free_entity(ent->u.ch->mprog_target);
		if (target == NULL)
			ent->u.ch->mprog_target = NULL;
		else
			ent->u.ch->mprog_target = entCopiar(target);
		break;
	}
}

OBJ_DATA *ent_get_obj_here( Entity * ent, char *argument )
{
    OBJ_DATA *obj;

    if (ent == NULL)
    	return NULL;

    switch(ent->tipo)
    {
    	case ENT_CH:
    	obj = get_obj_list( ent->u.ch, argument, ent->u.ch->in_room->contents );

	if ( obj != NULL )
		return obj;

	if ( ( obj = get_obj_carry( ent->u.ch, argument, ent->u.ch ) ) != NULL )
		return obj;

	if ( ( obj = get_obj_wear( ent->u.ch, argument ) ) != NULL )
		return obj;
	break;
    }

    return NULL;
}

CHAR_DATA *ent_get_char_world( Entity * ent, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *wch;
    CHAR_DATA *ch = entidadEsCh(ent) ? entidadGetCh(ent) : NULL;
    int number;
    int count;

    if (ent == NULL)
    	return NULL;

    if ( ( wch = ent_get_char_room( ent, argument ) ) != NULL )
	return wch;

    number = number_argument( argument, arg );
    count  = 0;

    for ( wch = char_list; wch != NULL ; wch = wch->next )
    {
	if ( wch->in_room == NULL
	||   (ch && !can_see( ch, wch ))
	||   !is_name( arg, wch->name ) )
	    continue;
	if ( ++count == number )
	    return wch;
    }

    return NULL;
}

/*
 * Find an obj in the world.
 */
OBJ_DATA *ent_get_obj_world( Entity * ent, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *ch = entidadEsCh(ent) ? entidadGetCh(ent) : NULL;
    OBJ_DATA *obj;
    int number;
    int count;

    if (ent == NULL)
    	return NULL;

    if ( ( obj = ent_get_obj_here( ent, argument ) ) != NULL )
	return obj;

    number = number_argument( argument, arg );
    count  = 0;
    for ( obj = object_list; obj != NULL; obj = obj->next )
    {
	if ( (!ch || can_see_obj( ch, obj )) && is_name( arg, obj->name ) )
	{
	    if ( ++count == number )
		return obj;
	}
    }

    return NULL;
}

bool ent_can_see( Entity * looker, Entity * target )
{
	if ( looker == NULL || target == NULL )
		return FALSE;

	switch(looker->tipo)
	{
		case ENT_CH:
		switch(target->tipo)
		{
			case ENT_CH:
			return can_see(entidadGetCh(looker),entidadGetCh(target));
			case ENT_OBJ:
			return can_see_obj(entidadGetCh(looker),entidadGetObj(target));
			default:
			return TRUE;
		}
		break;
	}

	return TRUE;
}

int entGetClan( Entity * ent )
{
	switch(ent->tipo)
	{
		case ENT_CH:
		return ent->u.ch->clan;

		case ENT_OBJ:
		return ent->u.obj->pIndexData->clan;

		case ENT_ROOM:
		return ent->u.room->clan;
	}

	return 0;
}

char * entGetName( Entity * ent )
{
	if (ent == NULL)
		return "";

	switch(ent->tipo)
	{
		case ENT_CH:
		return ent->u.ch->name;

		case ENT_OBJ:
		return ent->u.obj->name;

		case ENT_ROOM:
		return ent->u.room->name;
	}

	return "ERROR";
}

char * entGetShortDescr( Entity * ent )
{
	if (ent == NULL)
		return "";

	switch(ent->tipo)
	{
		case ENT_CH:
		return ent->u.ch->short_descr;

		case ENT_OBJ:
		return ent->u.obj->short_descr;

		case ENT_ROOM:
		return ent->u.room->name;
	}

	return "ERROR";
}

const char * entPERS(Entity * looker, Entity * target)
{
	if (looker == NULL || target == NULL)
		return "";

	if ( ent_can_see(looker, target) )
		return entidadToString(target);
	else
	{
		switch(target->tipo)
		{
			case ENT_CH:	return "alguien";
			case ENT_OBJ:	return "algo";
			case ENT_ROOM:	return "algun lugar";
		}
	}

	return "algo";
}

bool ent_can_see_ch( Entity * ent, CHAR_DATA *target )
{
	if (ent == NULL || target == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:
		return can_see(ent->u.ch, target);
	}

	return FALSE;
}

MPROG_LIST * entGetProgs( Entity * ent )
{
	if (ent == NULL)
		return NULL;

	switch(ent->tipo)
	{
		case ENT_CH:	return IS_NPC(ent->u.ch) ? ent->u.ch->pIndexData->mprogs : NULL;
		case ENT_OBJ:	return ent->u.obj->pIndexData->mprogs;
		case ENT_ROOM:	return ent->u.room->mprogs;
	}

	return NULL;
}

void affect_to_ent( Entity * ent, AFFECT_DATA * aff )
{
	if (ent == NULL)
		return;

	switch(ent->tipo)
	{
		case ENT_CH:	affect_to_char( ent->u.ch, aff );	return;
		case ENT_OBJ:	affect_to_obj( ent->u.obj, aff );	return;
		case ENT_ROOM:	affect_to_room( ent->u.room, aff );	return;
	}
}

void entSetSavingThrow( Entity * ent, int valor )
{
	if (ent == NULL)
		return;

	switch(ent->tipo)
	{
		case ENT_CH:	ent->u.ch->saving_throw = valor;	return;
	}
}

int entGetSavingThrow( Entity * ent )
{
	if (ent == NULL)
		return 0;

	switch(ent->tipo)
	{
		case ENT_CH:	return ent->u.ch->saving_throw;
	}

	return 0;
}

bool ent_is_part( Entity * ent, long part )
{
	if (ent == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:	return IS_PART(ent->u.ch, part);
	}

	return FALSE;
}

void obj_to_ent( OBJ_DATA *obj, Entity * ent )
{
	if (obj == NULL || ent == NULL)
		return;

	switch(ent->tipo)
	{
		case ENT_CH:	obj_to_char(obj, ent->u.ch);	return;
		case ENT_OBJ:	obj_to_obj(obj, ent->u.obj);	return;
		case ENT_ROOM:	obj_to_room(obj, ent->u.room);	return;
	}

	bugf( "obj_to_ent : entidad %s(%s) invalida",
		entToString(ent), entGetTipo(ent) );
	return;
}

void change_health( Entity *ent, Entity *victim, int mod )
{
/*	FIGHT_DATA * fd; */

	if (ent == NULL || victim == NULL)
		return;

	if ( entGetMaxHit(victim) < entGetHit(victim) + mod )
		mod = entGetMaxHit(victim) - entGetHit(victim);

	entSetHit( victim, entGetHit(victim) + mod );

/*	if ( entEsCh(victim) )
		for ( fd = entGetCh(victim)->fdata; fd; fd = fd->next )
			fd->dam = UMAX(0, fd->dam - (getNivelPr(entGetCh(victim)) > 29) ? mod*2 : mod); */
}

void entSetAlignment( Entity * ent, int align )
{
	if (ent == NULL)
		return;

	switch(ent->tipo)
	{
		case ENT_CH:	ent->u.ch->alignment = align;	break;
	}

	return;
}

int entGetAlignment( Entity * ent )
{
	if (ent == NULL)
		return 0;

	switch(ent->tipo)
	{
		case ENT_CH:	return ent->u.ch->alignment;
	}

	return 0;
}

int entGetHit( Entity * ent )
{
	if (ent == NULL)
		return 0;

	switch(ent->tipo)
	{
		case ENT_CH:	return ent->u.ch->hit;
	}

	return 0;
}

int entGetMaxHit( Entity * ent )
{
	if (ent == NULL)
		return 0;

	switch(ent->tipo)
	{
		case ENT_CH:	return ent->u.ch->max_hit;
	}

	return 0;
}

void entSetHit( Entity * ent, int valor )
{
	if (ent == NULL)
		return;

	switch(ent->tipo)
	{
		case ENT_CH:	ent->u.ch->hit = valor;		break;
	}

	return;
}

void ent_update_pos( Entity * ent )
{
	if (ent == NULL)
		return;

	switch(ent->tipo)
	{
		case ENT_CH:	update_pos(ent->u.ch);		break;
	}

	return;
}

void ent_wear_obj( Entity * ent, OBJ_DATA *obj, bool arg )
{
	if (ent == NULL)
		return;

	switch(ent->tipo)
	{
		case ENT_CH:	wear_obj( ent->u.ch, obj, arg );	break;
	}

	return;
}

OBJ_DATA * ent_get_eq_char( Entity * ent, int arg )
{
	if (ent == NULL)
		return NULL;

	switch(ent->tipo)
	{
		case ENT_CH:	return get_eq_char(ent->u.ch, arg);
	}

	return NULL;
}

bool ent_is_npc( Entity * ent )
{
	if (ent == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:	return IS_NPC(ent->u.ch);
	}

	return TRUE;
}

bool ent_saves_spell( int level, Entity * ent, int dam_type )
{
	if (ent == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:	return saves_spell( level, ent->u.ch, dam_type );
	}

	return TRUE;
}

bool ent_is_affected( Entity * ent, int sn )
{
	if (ent == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:	return is_affected(ent->u.ch, sn);
		case ENT_OBJ:	return is_obj_affected(ent->u.obj, sn);
		case ENT_ROOM:	return is_room_affected(ent->u.room, sn);
	}

	return FALSE;
}

bool ent_is_safe_spell( Entity * ent, Entity * target, bool arg )
{
	if (ent == NULL || target == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:
		switch(target->tipo)
		{
			case ENT_CH:	return is_safe_spell(ent->u.ch, target->u.ch, arg);
		}
	}

	return TRUE;
}

bool ent_IS_AFFECTED(Entity * ent, long arg)
{
	if (ent == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:	return (IS_AFFECTED(ent->u.ch, arg) ? TRUE : FALSE);
	}

	return FALSE;
}

bool ent_IS_AFFECTED2(Entity * ent, long arg)
{
	if (ent == NULL)
		return FALSE;

	switch(ent->tipo)
	{
		case ENT_CH:	return (IS_AFFECTED2(ent->u.ch, arg) ? TRUE : FALSE);
	}

	return FALSE;
}

int ent_get_skill( Entity * ent, int sn )
{
	if (ent == NULL)
		return 0;

	switch(ent->tipo)
	{
		case ENT_CH:	return get_skill(ent->u.ch, sn);
	}

	return 0;
}

bool ent_is_same_group( Entity * ent, Entity * ent2 )
{
	if (ent == NULL || ent2 == NULL)
		return 0;

	if ( entEsCh(ent) )
	{
		if (entEsCh(ent2)
		&&   is_same_group(ent->u.ch, ent2->u.ch) )
		return TRUE;

		// no es ch
		if (entEsObj(ent2)
		&&  obj_carried_by(ent2->u.obj) == ent->u.ch )
			return TRUE;
	}
	else
	if ( entEsObj(ent) )
	{
		if (entEsCh(ent2)
		&&  obj_carried_by(ent->u.obj) == ent2->u.ch )
			return TRUE;
	}

	return FALSE;
}

int ent_get_curr_stat( Entity * ent, int arg )
{
	if (ent == NULL)
		return 0;

	if ( entEsCh(ent) )
		return get_curr_stat(ent->u.ch, arg);

	return 0;
}

CHAR_DATA * entGetPet( Entity * ent )
{
	if (ent == NULL)
		return NULL;

	if ( entEsCh(ent) )
		return ent->u.ch->pet;

	return NULL;
}

void ent_multi_hit( Entity * ent, Entity * target, int arg )
{
	if (ent == NULL || target == NULL)
		return;

	if ( entEsCh(ent)
	&&   entEsCh(target) )
		multi_hit(ent->u.ch, target->u.ch, arg);
}

void ent_add_follower( Entity * ent, Entity * arg )
{
	if (ent == NULL || arg == NULL)
		return;

	if ( entEsCh(ent) && entEsCh(arg) )
		add_follower( ent->u.ch, arg->u.ch );
}

CHAR_DATA * entGetPeopleRoom( Entity * ent )
{
	ROOM_INDEX_DATA * room = entWhereIs(ent);

	if (room == NULL)
		return NULL;
	else
		return room->people;
}

ROOM_INDEX_DATA *ent_find_location( Entity *ent, char *arg )
{
    CHAR_DATA *victim;
    OBJ_DATA *obj;

    if ( is_number(arg) )
	return (atoi(arg) < 0 ? NULL : get_room_index( atoi( arg ) ) );

    if ( ( victim = ent_get_char_world( ent, arg ) ) != NULL )
	return victim->in_room;

    if ( ( obj = ent_get_obj_world( ent, arg ) ) != NULL )
	return obj->in_room;

    return NULL;
}

void ent_free_event( EVENT * ev )
{
	Entity * ent = ev->item.ent;

	free_entity(ent);
}

Entity * entCopiar( Entity * ent )
{
	Entity * temp;

	if ( ent == NULL )
	{
		bugf( "entCopiar : NULL ent" );
		return NULL;
	}

	temp		= new_entity();
	temp->tipo	= ent->tipo;

	switch(temp->tipo)
	{
		case ENT_CH:	temp->u.ch = ent->u.ch;		break;
		case ENT_OBJ:	temp->u.obj = ent->u.obj;	break;
		case ENT_ROOM:	temp->u.room = ent->u.room;	break;
		case ENT_INT:	temp->u.entero = ent->u.entero;	break;
		case ENT_STRING:temp->u.string = ent->u.string;	break;
		default:
		bugf( "entCopiar : tipo %d invalido", temp->tipo );
	}

	return temp;
}

Entity * ent_dead;

void poner_ent_lista( Entity * ent )
{
	ent->next	= ent_dead;
	ent_dead	= ent;
}

void dead_update( void )
{
	Entity * ent, * ent_next;

	if ( ent_dead == NULL )
		return;

	for ( ent = ent_dead; ent; ent = ent_next )
	{
		ent_next = ent->next;

		free_entity(ent);
	}

	ent_dead = NULL;
}

bool ent_died( Entity * ent )
{
	Entity * temp;

	if ( ent == NULL )
		return FALSE;

	for ( temp = ent_dead; temp; temp = temp->next )
		if ( entComparar(temp, ent) )
			return TRUE;

	return FALSE;
}

int get_prog_delay( Entity * ent )
{
	EVENT * ev, * evlist;

	switch(ent->tipo)
	{
		case ENT_CH:
		evlist = entGetCh(ent)->events;
		break;

		case ENT_ROOM:
		evlist = entGetRoom(ent)->events;
		break;

		case ENT_OBJ:
		evlist = entGetObj(ent)->events;
		break;

		default:
		return 0;
	}

	ev = event_pending( evlist, ent_timer );

	return ev ? ev->when - pulseclock : 0;
}

char * entGetNombre( Entity * ent )
{
	if (ent == NULL)
		return "ERROR";

	switch(ent->tipo)
	{
		case ENT_CH:		return ent->u.ch->name;
		case ENT_OBJ:		return ent->u.obj->name;
		case ENT_ROOM:		return ent->u.room->name;
		case ENT_STRING:	return ent->u.string;
		case ENT_INT:		return itos(ent->u.entero);
	}

	bugf("entGetNombre : tipo %d indefinido, ent %s", ent->tipo, entToStringExt(ent) );
	return "ERROR";
}