Argila2.0/
Argila2.0/pp/
Argila2.0/pp/lib/save/objs/g/
Argila2.0/pp/lib/save/player/g/
Argila2.0/pp/regions/
Argila2.0/pp/regions/Lscripts/
Argila2.0/pp/src/lib/

/* constants */
#include "structs.h"
#include "protos.h"
#include "utils.h"


/** Cyle through all rooms looking for scripts **/
void larg_trigger_time_select(void)
{
	CHAR_DATA 	*tch = NULL;
	OBJ_DATA  	*tobj = NULL;
	ROOM_DATA	*troom = NULL;
	char 		buf[80] = {'\0'};
	int 		rnum = 0;
	
	/* go through the rooms */
	for (troom = full_room_list; troom; troom = troom->lnext)
	{		
		if (troom->people){
			if (troom->triggers){
				larg_room_trigger_time(troom, troom->people);
			}
			
			for ( tobj = troom->contents; tobj; tobj = tobj->lnext ) {
				if (tobj->triggers){
					larg_obj_trigger_time(tobj, troom->people);
				}
			}
			
			for ( tch = troom->people; tch; tch = tch->next_in_room ) {
				if (tch->triggers){
					larg_mob_trigger_time(tch, troom->people);
				}
			}
			
		}//end of people

	}//end of rooms
	
	return;
}
/**********************************************************************/
/*********************** TIMMER TRIGGERS ******************************/
/**********************************************************************/

void larg_room_trigger_time(ROOM_DATA *targ, CHAR_DATA *ch_targ)
{
	TRIGGER_DATA 	*trig = NULL;
	TRIGGER_DATA 	*next_t = NULL;
	int 				result = 0;
	
	//trig = targ->triggers->list;
	trig = targ->triggers;
	
	while(trig){
		next_t = trig->next;
		if (trig->type == TT_TIME) {
			result = larg_execute_script(trig->script,
										trig->func,
										TS_ROOM,
										trig->me,
										targ->virtual,
										ch_targ,
										NULL,
										NULL,
										NULL);
		}
		trig = next_t;
	}
	
	return;
}
/**********************************************************************/
void larg_obj_trigger_time(OBJ_DATA *targ, CHAR_DATA *tch)
{
	TRIGGER_DATA 	*trig = NULL;
	TRIGGER_DATA 	*next_t = NULL;
	int 				result = 0;
	OBJ_DATA		*tobj = NULL;
	
	//trig = targ->triggers->list;
	trig = targ->triggers;

	while(trig){
		next_t = trig->next;
		
		if (trig->type == TT_TIME) {
		
			tobj = get_obj_in_list_vis (tch, targ->name, tch->room->contents);
			if (tobj){
				result = larg_execute_script(trig->script,
										trig->func,
										TS_ROOM,
										trig->me,
										tobj->in_room,  //room
										tch,
										NULL,
										NULL,
										NULL);
			}
		}
		
		trig = next_t;
	}
	
	return;
}
/**********************************************************************/
void larg_mob_trigger_time(CHAR_DATA *targ, CHAR_DATA *tch)
{
	TRIGGER_DATA 	*trig = NULL;
	TRIGGER_DATA 	*next_t = NULL;
	int 			result = 0;
	CHAR_DATA		*tmob = NULL;
	
	//trig = targ->triggers->list;
	trig = targ->triggers;
	
	while(trig){
		next_t = trig->next;
		
		if (trig->type == TT_TIME) {
			result = larg_execute_script(trig->script,
										trig->func,
										TS_ROOM,
										trig->me,
										targ->in_room,  //room
										tch,
										NULL,
										NULL,
										NULL);
		}
		
		trig = next_t;
	}
	
	return;
}
/**********************************************************************/
/*************************** CREATE TRIGGERS **************************/
/**********************************************************************/

TRIGGER_DATA *larg_trigger_room_create(int type, char *script, int rvnum, 																		int source){

	TRIGGER_DATA 	*t;
	char 			*ptr;

	CREATE(t, TRIGGER_DATA, 1);
	t->type   = type;
	t->me     = rvnum;
	t->source = source;

	if ((ptr = strchr(script, ':')) != NULL){
		*ptr = 0;
		t->script = str_dup(script);
		t->func   = add_hash(str_dup(ptr + 1));
	}
	else{
		t->script = add_hash(str_dup(script));
	}

	return t;
}


/**********************************************************************/
TRIGGER_DATA *larg_trigger_obj_create(int type, char *script, int ovnum, 																		int source){

	TRIGGER_DATA 	*t;
	char 			*ptr;

	CREATE(t, TRIGGER_DATA, 1);
	t->type   = type;
	t->me     = ovnum;
	t->source = source;

	if ((ptr = strchr(script, ':')) != NULL)
	{
		*ptr = 0;
		t->script = str_dup(script);
		t->func   = add_hash(str_dup(ptr + 1));
	}
	else
	{
		t->script = add_hash(str_dup(script));
	}

	return t;
}

/**********************************************************************/
TRIGGER_DATA *larg_trigger_mob_create(int type, char *script, int mvnum, 																		int source){

	TRIGGER_DATA 	*t;
	char 			*ptr;

	CREATE(t, TRIGGER_DATA, 1);
	t->type   = type;
	t->me     = mvnum;
	t->source = source;

	if ((ptr = strchr(script, ':')) != NULL)
	{
		*ptr = 0;
		t->script = str_dup(script);
		t->func   = add_hash(str_dup(ptr + 1));
	}
	else
	{
		t->script = add_hash(str_dup(script));
	}

	return t;
}

/**********************************************************************/
/************************* TRIGGER UTILITIES **************************/
/**********************************************************************/
void larg_trigger_add(TRIGGER_DATA *t, TRIGGER_DATA **l)
{
	TRIGGER_DATA *add_trigger;

	t->next = *l;
	*l = t;

	for (add_trigger = *l; add_trigger; add_trigger = add_trigger->next)
	{
		add_trigger->list = t;
	}
	return;
}

/**********************************************************************/
void larg_trigger_remove(TRIGGER_DATA *t)
{
	TRIGGER_DATA	*temp;
	TRIGGER_DATA	*ind;
	

	for (ind = t->list; ind; ind = ind->next)
	{
		if (ind == t){
			ind->next = t->next;
			t->next = NULL;
			t->list = NULL;
		}
	}


	return;
	
}

/**********************************************************************/
/*
 * FUNCTION:  execute_script
 * ARGUMENTS:  char *script, char *func, int source, int me, int room,  OBJ_DATA *              obj,  CHAR_DATA *ch,  char *txt
  DESCRIPTION: Load a Lua script, and eventually call a function in it.
 * RETURNS:     -1 if something went wrong
 *               0 if script was executed
 */
int larg_execute_script(char *script, char *func, int source, int me, int room, CHAR_DATA *targ_ch,  OBJ_DATA *obj,  CHAR_DATA *ch,  char *txt)
{
	
	char buf[MAX_STRING_LENGTH] = {'\0'};
	int err = 0;
	char *mess = NULL;
	char *command = NULL;
	int mess_room_num = 0;
	int room_sect = 0;
	
	snprintf(buf, MAX_STRING_LENGTH, "%s/%s", SCRIPT_DIR, script);
	
	err = luaL_dofile(luaVM, buf);

	if (err == 1){
		send_to_gods("Error in execute_script");
		return (-1);
	}
		
	
	lua_getglobal(luaVM, func);
	
	lua_newtable(luaVM);        /* We will pass a table */

/* To put values into the table, we first push the index, then the
 * value, and then call lua_rawset() with the index of the table in the
 * stack. Let's see why it's -3: In Lua, the value -1 always refers to
 * the top of the stack. When you create the table with lua_newtable(),
 * the table gets pushed into the top of the stack. When you push the
 * index and then the cell value, the stack looks like:
 *
 * <- [stack bottom] -- table, index, value [top]
 *
 * So the -1 will refer to the cell value, thus -3 is used to refer to
 * the table itself. Note that lua_rawset() pops the two last elements
 * of the stack, so that after it has been called, the table is at the
 * top of the stack.
*/
	
	lua_pushnumber(luaVM, 1);   /* Push the table index */
	lua_pushnumber(luaVM, time_info.hour); /* Push the cell value */
	lua_rawset(luaVM, -3);      /* Stores the pair in the table*/

	lua_pushnumber(luaVM, 2);   /* Push the table index */
	lua_pushnumber(luaVM, time_info.day); /* Push the cell value */
	lua_rawset(luaVM, -3);      /* Stores the pair in the table*/
	
	room_sect = vtor(room)->sector_type;
	
	lua_pushnumber(luaVM, 3);   /* Push the table index */
	lua_pushnumber(luaVM, room_sect); /* Push the cell value */
	lua_rawset(luaVM, -3);      /* Stores the pair in the table*/

/*
 * A table must be terminated by a cell which is indexed by the literal
 * "n" and contains the total number of elements in the table.
 */
	lua_pushliteral(luaVM, "n");  /* Pushes the literal */
    lua_pushnumber(luaVM, 4);     /* Pushes the total number of cells */
    lua_rawset(luaVM, -3);        /* Stores the pair in the table */


	/* Send data to be used by Lua scripts */
	
	lua_pushnumber (luaVM, source);
	lua_pushnumber (luaVM, me);
	lua_pushnumber (luaVM, room);
	
/***************************************************************
 call script and get results back 
 sent table, source, me value and room number
 returns the command string to be used by 
 command_interpreter (CHAR_DATA *ch, char *argument)
 Could use a case statment here or call selection function
****************************************************************/


	lua_call(luaVM, 4, 2);
	
	command = (char *)lua_tostring(luaVM, -2);
	mess = (char *)lua_tostring(luaVM, -1);
	
	if (!strcmp(command, "echo")){
		send_to_room(mess, room);
	}
	
	else if (!strcmp(command, "r_loadmob")){
		r_loadmob(mess);
	}

	return (0);

	
}

/**********************************************************************/
/*************************** SETUP TRIGGERS **************************/
/**********************************************************************/

void larg_setup_room_triggers(FILE *fl, ROOM_DATA *room)
{
	int 			trig_type;
	char			*trig_script = NULL;
	TRIGGER_DATA	*trig = NULL;


	fscanf(fl, "%d", &trig_type);
	trig_script = fread_string(fl);

	trig = larg_trigger_room_create(trig_type, trig_script, room->virtual, TS_ROOM);

	larg_trigger_add(trig, &room->triggers);
	
	return;
}
/**********************************************************************/
void larg_setup_obj_triggers(FILE *fl, OBJ_DATA *obj)
{
	int 			trig_type;
	char			*trig_script = NULL;
	char			*temp_arg = NULL;
	TRIGGER_DATA	*trig = NULL;

	temp_arg = fread_word(fl);  //gets rid of the R
	trig_type = fread_number(fl);
	trig_script = fread_string(fl);
	
	
	trig = larg_trigger_obj_create(trig_type, trig_script, obj->virtual, TS_OBJECT);

	larg_trigger_add(trig, &obj->triggers);
	
	return;
}
/**********************************************************************/
void larg_setup_mob_triggers(FILE *fl, CHAR_DATA *tch)
{
	int 			trig_type;
	char			*trig_script = NULL;
	char			*temp_arg = NULL;
	TRIGGER_DATA	*trig = NULL;

	temp_arg = fread_word(fl);  //gets rid of the R
	trig_type = fread_number(fl);
	trig_script = fread_string(fl);
	
	
	trig = larg_trigger_mob_create(trig_type, trig_script, tch->mob->virtual, TS_MOBILE);

	larg_trigger_add(trig, &tch->triggers);
	
	return;
}

/**********************************************************************/
/*************************** ROOM UTILITIES **************************/
/**********************************************************************/
void do_rscript_add (CHAR_DATA *ch, char *argument, int cmd)
{
	ROOM_DATA 	*temp_room = NULL;
	
	temp_room = vtor (ch->in_room);
	larg_room_script_add (ch, argument, temp_room);
	return;
}
/**********************************************************************/
void do_rscript_del (CHAR_DATA *ch, char *argument, int cmd)
{
	ROOM_DATA 	*temp_room = NULL;
	
	temp_room = vtor (ch->in_room);
	larg_room_script_delete (ch, argument, temp_room);
	return;
}
/**********************************************************************/
void do_rscript_list (CHAR_DATA *ch, char *argument, int cmd)
{
	ROOM_DATA 	*temp_room = NULL;
		
	temp_room = vtor (ch->in_room);
	larg_room_script_list (ch, argument, temp_room);
}

/**********************************************************************/
void larg_room_script_list(CHAR_DATA *ch, char *argument, ROOM_DATA *room)
{
	char		buf	[MAX_STRING_LENGTH] = { '\0' };
	TRIGGER_DATA		*temp_trig = NULL;
	
	snprintf (buf, MAX_STRING_LENGTH,  "This room has the following scripts:\n\n Type     Script     Function\n");
		send_to_char (buf, ch);
			
		for (temp_trig = room->triggers; temp_trig; temp_trig = temp_trig->next){
			snprintf (buf, MAX_STRING_LENGTH,  "%d     %s     %s\n", temp_trig->type, temp_trig->script, temp_trig->func);
			send_to_char (buf, ch);
		}
	return;	
}
/**********************************************************************/
void larg_room_script_add (CHAR_DATA *ch, char *argument, ROOM_DATA *room)
{
	char		buf	[MAX_STRING_LENGTH] = { '\0' };
	TRIGGER_DATA		*temp_trig = NULL;
	int			sct_type = 0;
	char		*sct_script = NULL;
	char		*sct_func = NULL;


		if ( !*argument ) {
			send_to_char("Correct format is - rscriptadd Type Script_name  Function_name.\nTypes are 1-Timed, 2-Enter, 3-Leave, 4-Tell, 5-Ask, 6-Say, 7-Give\nType 1 is the only one implemented at this time\n", ch);
			return;
		}
		else {	
			sscanf (argument, "%d%s%s", &sct_type, &sct_script, &sct_func);

			
			temp_trig = (TRIGGER_DATA *)alloc ((int)sizeof (TRIGGER_DATA), 24);

			argument = one_argument (argument, buf);
			if ( !isdigit (*buf) || strtol(buf, NULL, 10) > 7 ) {
				send_to_char ("Expected type 1..7\n", ch);
				return;
			}
			temp_trig->type = strtol(buf, NULL, 10);
			
			argument = one_argument (argument, buf);
			if ( !(*buf)) {
				send_to_char ("Expected Name of script\n", ch);
				return;
			}
			temp_trig->script = add_hash(buf);
			
			argument = one_argument (argument, buf);
			if ( !(*buf)) {
				send_to_char ("Expected Name of function\n", ch);
				return;
			}
			temp_trig->func = add_hash(buf);
			

			temp_trig->source = 0; //0-room, 1-obj, 2-mobile
			temp_trig->me = ch->in_room;
			
			larg_trigger_add(temp_trig, &room->triggers);
		}
		

	return;
}
/**********************************************************************/
void larg_room_script_delete (CHAR_DATA *ch, char *argument, ROOM_DATA *room)
{
	char		buf	[MAX_STRING_LENGTH] = { '\0' };
	TRIGGER_DATA		*head_trig = NULL;
	TRIGGER_DATA		*current_trig = NULL;
	TRIGGER_DATA		*temp_trig = NULL;

	int			trig_type = 0;
	int			trig_source = 0;
	int			trig_me = 0;
	char		*trig_script = NULL;
	char		*trig_func = NULL;


		if ( !*argument ) {
			send_to_char("Correct format is - rscriptdel Type Script_name  Function_name.\nTypes are 1-Timed, 2-Enter, 3-Leave, 4-Tell, 5-Ask, 6-Say, 7-Give\nType 1 is the only one implemented at this time\n", ch);
			return;
		}
		else {	
						
			argument = one_argument (argument, buf);
			if ( !isdigit (*buf) || strtol(buf, NULL, 10) > 7 ) {
				send_to_char ("Expected type 1..7\n", ch);
				return;
			}
			trig_type = strtol(buf, NULL, 10);
			
			argument = one_argument (argument, buf);
			if ( !(*buf)) {
				send_to_char ("Expected Name of script\n", ch);
				return;
			}
			trig_script = add_hash(buf);
			
			argument = one_argument (argument, buf);
			if ( !(*buf)) {
				send_to_char ("Expected Name of function\n", ch);
				return;
			}
			trig_func = add_hash(buf);
			
			trig_source = 0; //0-room, 1-obj, 2-mobile
			trig_me = ch->in_room;
		}

/** delete the head node **/
		if (room->triggers &&
			room->triggers->type == trig_type &&
			room->triggers->source == trig_source &&
			!(strcmp(room->triggers->script,trig_script)) &&
			!(strcmp(room->triggers->func, trig_func)) &&
			room->triggers->me == trig_me){
				temp_trig = room->triggers;
				room->triggers = temp_trig->next;
		}

/** delete other nodes **/
		else {
			for (current_trig = room->triggers; current_trig; current_trig = current_trig->next){
				if (!(current_trig->next == NULL) &&
					current_trig->next->type == trig_type &&
					current_trig->next->source == trig_source &&
					!(strcmp(current_trig->next->script,trig_script)) &&
					!(strcmp(current_trig->next->func, trig_func)) &&
					current_trig->next->me == trig_me){
										
						temp_trig = current_trig->next;
						current_trig->next = temp_trig->next;
				}
			}
		}
		
		

	return;
}

/**********************************************************************/
/*************************** MOB UTILITIES ***************************/
/** See mset for add, del, and list utilities                      ***/
/*********************************************************************/
void larg_mo_script_delete (TRIGGER_DATA *targ, TRIGGER_DATA *list_scrpt)
{
	char		buf	[MAX_STRING_LENGTH] = { '\0' };
	TRIGGER_DATA		*head_trig = NULL;
	TRIGGER_DATA		*current_trig = NULL;
	TRIGGER_DATA		*temp_trig = NULL;
		
/** delete the head node **/
		if (list_scrpt &&
			list_scrpt->type == targ->type &&
			list_scrpt->source == targ->source &&
			!(strcmp(list_scrpt->script, targ->script)) &&
			!(strcmp(list_scrpt->func, targ->func)) &&
			list_scrpt->me == targ->me){
				temp_trig = list_scrpt;
				list_scrpt = temp_trig->next;
		}

/** delete other nodes **/
		else {
			for (current_trig = list_scrpt; current_trig; current_trig = current_trig->next){
				if (!(current_trig->next == NULL) &&
					current_trig->next->type == targ->type &&
					current_trig->next->source == targ->source &&
					!(strcmp(current_trig->next->script, targ->script)) &&
					!(strcmp(current_trig->next->func, targ->func)) &&
					current_trig->next->me == targ->me){
										
						temp_trig = current_trig->next;
						current_trig->next = temp_trig->next;
				}
			}
		}
	return;
}
/**********************************************************************/
/*************************** OBJ UTILITIES ***************************/
/** See oset for add, del, and list utilities                      ***/
/*********************************************************************/