/* 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 ***/ /*********************************************************************/