#include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "emlen.h" /*char *itoa (int);*/ void remove_trigger_from_list (SINGLE_TRIGGER * tr); /* Finds a trigger given a set trigger id name */ SINGLE_TRIGGER * find_trigger (char *trigname) { int i; SINGLE_TRIGGER *tr; MARK_DEBUG ("Find_trigger") for (i = 0; i < TMAX_TRIGGERS; i++) { for (tr = trigger_list[i]; tr != NULL; tr = tr->next) { if (!str_cmp (tr->trigger_id, trigname)) return tr; } } return NULL; } /* Creates a new trigger, names it, and puts it in the trigger list with type 1 */ SINGLE_TRIGGER * new_trigger (char *trigname) { SINGLE_TRIGGER *tr; tr = mem_alloc (sizeof (*tr)); bzero (tr, sizeof (*tr)); if (strlen (trigname) > 19) trigname[19] = '\0'; strcpy (tr->trigger_id, trigname); tr->keywords = &str_empty[0]; tr->trigger_type = 1; tr->next = trigger_list[1]; trigger_list[1] = tr; return tr; } /* returns the type of the trigger given a specific trigger name */ int trigger_name (char *trig) { int i = TMAX_TRIGGERS; if (!str_cmp (trig, "Enters")) i = TENTERS; else if (!str_cmp (trig, "Leaves")) i = TLEAVES; else if (!str_cmp (trig, "Created")) i = TCREATED; else if (!str_cmp (trig, "Command")) i = TCOMMAND; else if (!str_cmp (trig, "Moves")) i = TMOVES; else if (!str_cmp (trig, "Destroyed")) i = TDESTROYED; else if (!str_cmp (trig, "Say")) i = TSAYS; else if (!str_cmp (trig, "Tell")) i = TTELLS; else if (!str_cmp (trig, "Hourly")) i = TEVERY_HOUR; else if (!str_cmp (trig, "Quicktick")) i = TEVERY_QUICKTICK; else if (!str_cmp (trig, "Regentick")) i = TEVERY_REGENTICK; else if (!str_cmp (trig, "At_hour")) i = TAT_HOUR; if (!str_cmp (trig, "Given")) i = TGIVEN; else if (!str_cmp (trig, "Dropped")) i = TDROPPED; else if (!str_cmp (trig, "Equipped")) i = TEQUIPPED; else if (!str_cmp (trig, "Attacked")) i = TATTACKED; else if (!str_cmp (trig, "Sacced")) i = TOBJ_SACCED; else if (!str_cmp (trig, "Money")) i = TGIVEN_MONEY; return i; } /* returns the name of the trigger given a specific trigger number */ char * trigger_type (int trig) { static char trigret[100]; strcpy (trigret, "Bad_Trgger"); if (trig == TENTERS) strcpy (trigret, "Enters "); else if (trig == TLEAVES) strcpy (trigret, "Leaves "); else if (trig == TCREATED) strcpy (trigret, "Created "); else if (trig == TCOMMAND) strcpy (trigret, "Command "); else if (trig == TMOVES) strcpy (trigret, "Moves "); else if (trig == TDESTROYED) strcpy (trigret, "Destroyed "); else if (trig == TSAYS) strcpy (trigret, "Say "); else if (trig == TTELLS) strcpy (trigret, "Tell "); else if (trig == TEVERY_HOUR) strcpy (trigret, "Hourly "); else if (trig == TEVERY_QUICKTICK) strcpy (trigret, "Quicktick "); else if (trig == TEVERY_REGENTICK) strcpy (trigret, "Regentick "); else if (trig == TAT_HOUR) strcpy (trigret, "At_hour "); else if (trig == TGIVEN) strcpy (trigret, "Given "); else if (trig == TDROPPED) strcpy (trigret, "Dropped "); else if (trig == TEQUIPPED) strcpy (trigret, "Equipped "); else if (trig == TATTACKED) strcpy (trigret, "Attacked "); else if (trig == TOBJ_SACCED) strcpy (trigret, "Sacced "); else if (trig == TGIVEN_MONEY) strcpy (trigret, "Money "); return trigret; } void list_triggers (CHAR_DATA * ch, char *argy) { int i; SINGLE_TRIGGER *tr; DEFINE_COMMAND ("listtriggers", list_triggers, POSITION_DEAD, 110, LOG_NORMAL, "Lists all triggers.") hugebuf_o[0] = '\0'; sprintf (hugebuf_o, "%-20s %s %5s %5s %5s\n\r", "Trigger ID", "TrigType ", "Room", "Mob", "Objct"); strcat (hugebuf_o, "------------------------------------------------------------------------------\n\r"); for (i = 0; i < TMAX_TRIGGERS; i++) { for (tr = trigger_list[i]; tr != NULL; tr = tr->next) { sprintf (hugebuf_o + strlen (hugebuf_o), "%-20s %s %5d %5d %5d\n\r", tr->trigger_id, trigger_type (tr->trigger_type), tr->attached_to_room, tr->attached_to_mob, tr->attached_to_obj); } } page_to_char (hugebuf_o, ch); return; } void script_editor (CHAR_DATA * ch, char *argy) { char arg1[500]; char arg2[500]; SINGLE_TRIGGER *tr; DEFINE_COMMAND ("scriptedit", script_editor, POSITION_DEAD, 110, LOG_NORMAL, "For Orin's use only right now.") if (!ch->desc) return; argy = one_argy (argy, arg1); argy = one_argy (argy, arg2); if (!str_cmp (arg1, "create") && arg2[0] != '\0') { if (find_trigger (arg2) != NULL) { send_to_char ("That trigger already exists!\n\r", ch); return; } tr = new_trigger (arg2); ch->desc->pEdit = (void *) tr; ch->desc->connected = CON_SCRIPTEDITOR; return; } if (!str_cmp (arg1, "delete") && arg2[0] != '\0') { if ((tr = find_trigger (arg2)) == NULL) { send_to_char ("That trigger doesn't exist!\n\r", ch); return; } remove_trigger_from_list (tr); free_string (tr->keywords); free (tr); send_to_char ("Trigger deleted.\n\r", ch); return; } if (arg1[0] == '\0') return; tr = find_trigger (arg1); if (!tr) { send_to_char ("That trigger was not found.\n\r", ch); return; } ch->desc->pEdit = (void *) tr; ch->desc->connected = CON_SCRIPTEDITOR; return; } void show_this_trigger (CHAR_DATA * ch, char *trig) { SINGLE_TRIGGER *tr; char buf[500]; if ((tr = find_trigger (trig)) == NULL) { send_to_char ("Trigger not found.\n\r", ch); return; } sprintf (buf, "Trigger ID: \x1B[37;1m%s\x1B[37;0m Trigger Type: \x1B[37;1m%s\x1B[37;0m\n\r", tr->trigger_id, trigger_type (tr->trigger_type)); send_to_char (buf, ch); sprintf (buf, "Room: %d Mob: %d Object: %d Interruptable: %s\n\r", tr->attached_to_room, tr->attached_to_mob, tr->attached_to_obj, (tr->interrupted == 1 ? "Yes" : (tr->interrupted == 2 ? "Yes, and multiple!" : "No"))); send_to_char (buf, ch); sprintf (buf, "\x1B[37;1mPlayer\x1B[37;0m only: %s \x1B[37;1mStop\x1B[37;0ms if player leaves: %s\n\r", (tr->players_only == 1 ? "Yes" : "No"), (tr->leaves_room == 1 ? "Yes" : "No")); send_to_char (buf, ch); sprintf (buf, "Calls code label: \x1B[34;1m%s\x1B[37;0m\n\r", tr->code_label); send_to_char (buf, ch); sprintf (buf, "Keywords: \x1B[37;1m%s\x1B[37;0m\n\r", tr->keywords); send_to_char (buf, ch); return; } void remove_trigger_from_list (SINGLE_TRIGGER * tr) { SINGLE_TRIGGER *tt; if (tr == trigger_list[tr->trigger_type]) { trigger_list[tr->trigger_type] = tr->next; tr->next = NULL; return; } for (tt = trigger_list[tr->trigger_type]; tt != NULL; tt = tt->next) { if (tt->next == tr) { tt->next = tr->next; tr->next = NULL; return; } } fprintf (stderr, "Trigger not found to remove from trigger list!!\n"); return; } void scriptedit (CHAR_DATA * ch, char *argy) { SINGLE_TRIGGER *tr; int tmp; char orig_argy[500]; char arg1[500]; if (!ch->desc) return; if (!ch->desc->pEdit) { ch->desc->connected = CON_PLAYING; return; } tr = (SINGLE_TRIGGER *) ch->desc->pEdit; strcpy (orig_argy, argy); if (!str_cmp (argy, "done")) { ch->desc->pEdit = NULL; ch->desc->connected = CON_PLAYING; return; } if (argy[0] == '\0' || argy[0] == ' ') { show_this_trigger (ch, tr->trigger_id); return; } argy = one_argy (argy, arg1); if ((tmp = trigger_name (arg1)) > 0 && tmp < TMAX_TRIGGERS) { remove_trigger_from_list (tr); tr->trigger_type = tmp; /* Must place in the new hash position */ tr->next = trigger_list[tmp]; trigger_list[tmp] = tr; send_to_char ("Trigger type set.\n\r", ch); return; } if (!str_cmp (arg1, "code") && argy[0] != '\0') { if (strlen (argy) > 9) { send_to_char ("Invalid code label. Must be less than 10 letters.\n\r", ch); return; } strcpy (tr->code_label, argy); send_to_char ("Code label set.\n\r", ch); return; } if (!str_prefix ("inter", arg1)) { if (argy[0] != '\0' && is_number (argy)) { tr->interrupted = atoi (argy); return; } if (tr->interrupted) { tr->interrupted = FALSE; send_to_char ("Script cannot be interrupted.\n\r", ch); } else { tr->interrupted = TRUE; send_to_char ("Script can now be interrupted.\n\r", ch); } return; } if (!str_prefix ("player", arg1)) { if (argy[0] != '\0' && is_number (argy)) { tr->players_only = atoi (argy); return; } if (tr->players_only) { tr->players_only = FALSE; send_to_char ("Script can now be triggered by mobs as well.\n\r", ch); } else { tr->players_only = TRUE; send_to_char ("Script can only be triggered by players now.\n\r", ch); } return; } if (!str_prefix ("stop", arg1)) { if (argy[0] != '\0' && is_number (argy)) { tr->leaves_room = atoi (argy); return; } if (tr->leaves_room) { tr->leaves_room = FALSE; send_to_char ("Script continues if char leaves the room.\n\r", ch); } else { tr->leaves_room = TRUE; send_to_char ("Script now stops if the character leaves the room.\n\r", ch); } return; } if (!str_prefix ("keyword", arg1)) { free_string (tr->keywords); tr->keywords = str_dup (argy); send_to_char ("Key words set.\n\r", ch); return; } if (!str_cmp ("obj", arg1) && is_number (argy)) { tr->attached_to_obj = atoi (argy); send_to_char ("Object vnum set.\n\r", ch); return; } if (!str_cmp ("room", arg1) && is_number (argy)) { tr->attached_to_room = atoi (argy); send_to_char ("Room vnum set.\n\r", ch); return; } if (!str_cmp ("mob", arg1) && is_number (argy)) { tr->attached_to_mob = atoi (argy); send_to_char ("Mob vnum set.\n\r", ch); return; } interpret (ch, orig_argy); return; } /* Finds a code label */ CODE * find_code (char *id) { CODE *c; int i; for (i = 0; i < 256; i++) { for (c = code_list[i]; c != NULL; c = c->next) { if (!str_cmp (id, c->label)) return c; } } return NULL; } CODE * new_code (char *id) { CODE *c; c = mem_alloc (sizeof (*c)); bzero (c, sizeof (*c)); if (strlen (id) > 9) id[9] = '\0'; strcpy (c->label, id); c->next = code_list[c->label[0]]; code_list[c->label[0]] = c; c->code=&str_empty[0]; return c; } void online_coding (CHAR_DATA * ch, char *argy) { char arg1[500]; CODE *cd; CODE *c; DEFINE_COMMAND ("edit", online_coding, POSITION_DEAD, 110, LOG_NORMAL, "Add/Modify online script code.") argy = one_argy (argy, arg1); if (!str_cmp (arg1, "delete") && argy[0] != '\0') { if ((cd = find_code (argy)) == NULL) { send_to_char ("That label does not exist!!\n\r", ch); return; } if (code_list[cd->label[0]] == cd) { code_list[cd->label[0]] = cd->next; } else for (c = code_list[cd->label[0]]; c != NULL; c = c->next) { if (c->next == cd) { c->next = cd->next; goto duu; } } duu: free_string (cd->code); free (cd); send_to_char ("Code label and code freed.\n\r", ch); return; } if (!str_cmp (arg1, "create") && argy[0] != '\0') { if (find_code (argy) != NULL) { send_to_char ("That label already exists!!\n\r", ch); return; } cd = new_code (argy); string_append (ch, &cd->code); return; } if ((cd = find_code (arg1)) == NULL) { send_to_char ("Code label was not found.\n\r", ch); return; } string_append (ch, &cd->code); return; } void list_code (CHAR_DATA * ch, char *argy) { int i; int col = 0; CODE *tr; DEFINE_COMMAND ("listcode", list_code, POSITION_DEAD, 110, LOG_NORMAL, "Lists all code labels.") hugebuf_o[0] = '\0'; for (i = 0; i < 256; i++) { for (tr = code_list[i]; tr != NULL; tr = tr->next) { col++; if (col == 7) { strcat (hugebuf_o, "\n\r"); col = 1; } sprintf (hugebuf_o + strlen (hugebuf_o), "%-10s ", tr->label); } } strcat (hugebuf_o, "\n\r"); page_to_char (hugebuf_o, ch); return; } void save_triggers (void) { FILE *fp; SINGLE_TRIGGER *tr; int i; if ((fp = fopen ("trig.dat", "w+")) == NULL) { fprintf (stderr, "Error on trigger write open!! NOT GOOD!\n"); return; } for (i = 0; i < TMAX_TRIGGERS; i++) { for (tr = trigger_list[i]; tr != NULL; tr = tr->next) { fprintf (fp, "ID %s~\n", tr->trigger_id); fprintf (fp, "Keywords %s~\n", tr->keywords); fprintf (fp, "TT %d\n", tr->trigger_type); fprintf (fp, "Room %d\n", tr->attached_to_room); fprintf (fp, "Mob %d\n", tr->attached_to_mob); fprintf (fp, "Obj %d\n", tr->attached_to_obj); fprintf (fp, "Int %d\n", tr->interrupted); fprintf (fp, "Plo %d\n", tr->players_only); fprintf (fp, "Clr %d\n", tr->leaves_room); fprintf (fp, "Code %s~\n", tr->code_label); } } fprintf (fp, "END\n"); fclose (fp); return; } void load_triggers (void) { SINGLE_TRIGGER *tr = NULL; FILE *fp; int ntr; char txt[100]; if ((fp = fopen ("trig.dat", "r")) == NULL) { return; } for (;;) { strcpy (txt, fread_word (fp)); if (!str_cmp (txt, "END")) break; if (!str_cmp (txt, "ID")) { strcpy (txt, fread_string2 (fp, NULL)); tr = new_trigger (txt); continue; } if (!str_cmp (txt, "TT")) { ntr = fread_number (fp); remove_trigger_from_list (tr); tr->trigger_type = ntr; tr->next = trigger_list[tr->trigger_type]; trigger_list[tr->trigger_type] = tr; continue; } if (!str_cmp (txt, "Keywords")) { tr->keywords = fread_string (fp, NULL); continue; } if (!str_cmp (txt, "Room")) { tr->attached_to_room = fread_number (fp); continue; } if (!str_cmp (txt, "Mob")) { tr->attached_to_mob = fread_number (fp); continue; } if (!str_cmp (txt, "Obj")) { tr->attached_to_obj = fread_number (fp); continue; } if (!str_cmp (txt, "Plo")) { tr->players_only = fread_number (fp); continue; } if (!str_cmp (txt, "Clr")) { tr->leaves_room = fread_number (fp); continue; } if (!str_cmp (txt, "Int")) { tr->interrupted = fread_number (fp); continue; } if (!str_cmp (txt, "Code")) { strcpy (tr->code_label, fread_string2 (fp, NULL)); continue; } } fclose (fp); return; } void save_code (void) { FILE *fp; CODE *c; int i; if ((fp = fopen ("code.dat", "w+")) == NULL) { fprintf (stderr, "Error on code write open!! NOT GOOD!\n"); return; } for (i = 0; i < 256; i++) { for (c = code_list[i]; c != NULL; c = c->next) { fprintf (fp, "LABEL %s~\n", c->label); if (c->code) fprintf (fp, "CODE %s~\n", fix_string (c->code)); else fprintf (fp, "CODE done~\n"); } } fprintf (fp, "END\n"); fclose (fp); return; } void load_code (void) { CODE *c = NULL; char txt[1100]; FILE *fp; if ((fp = fopen ("code.dat", "r")) == NULL) { return; } for (;;) { strcpy (txt, fread_word (fp)); if (!str_cmp (txt, "END")) break; if (!str_cmp (txt, "LABEL")) { strcpy (txt, fread_string2 (fp, NULL)); c = new_code (txt); continue; } if (!str_cmp (txt, "CODE")) { c->code = fread_string (fp, NULL); continue; } } fclose (fp); return; } /* ----------------------------------------------------- */ /* Stuff below here is for actually running the scripts! */ /* ----------------------------------------------------- */ CHAR_DATA *debugger = NULL; /* This holds who debugging should go to */ char e_buf[500]; int executed_lines = 0; /* Keeps track of lines executed.. traps repeating loops */ void debug (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("debug", debug, POSITION_DEAD, 110, LOG_NORMAL, "Sets all script error messages to go to you.") debugger = ch; send_to_char ("You now will recieve all script error messages.\n\r", ch); return; } void end_script (SCRIPT_INFO * scr) { SCRIPT_INFO *ls; MARK_DEBUG ("End_script") scr->called_by->running_info = NULL; if (scr == info_list) { info_list = scr->next; scr->next = NULL; } else for (ls = info_list; ls != NULL; ls = ls->next) { if (ls->next == scr) { ls->next = scr->next; scr->next = NULL; break; } } free (scr); return; } void e_goto_invalid_line_number (SCRIPT_INFO * scr, char *ln, int linenum) { sprintf (e_buf, "Invalid goto line number '%s' in code label %s, line %d. Script ended.\n\r", ln, scr->code_seg, linenum); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } void e_couldnt_find_label (SCRIPT_INFO * scr, char *lab, int linenum) { sprintf (e_buf, "Couldn't find code label %s, line %d, in trigger %s. Script ended.\n\r", lab, linenum, scr->called_by->trigger_id); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } void e_bad_wait_value (SCRIPT_INFO * scr, char *cmd) { sprintf (e_buf, "Bad wait value of '%s', line %d, code label %s. Script ended.\n\r", cmd, scr->current_line - 1, scr->code_seg); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } void e_bad_wait_type (SCRIPT_INFO * scr, char *typ) { sprintf (e_buf, "Bad wait type '%s', line %d, code label %s. Script ended.\n\r", typ, scr->current_line - 1, scr->code_seg); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } void e_repeating_loop (SCRIPT_INFO * scr) { sprintf (e_buf, "Apparent repeating loop in code label %s, trigger %s. Script ended.\n\r", scr->code_seg, scr->called_by->trigger_id); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } void e_invalid_create_obj (SCRIPT_INFO * scr, char *ln) { sprintf (e_buf, "Invalid create object vnum '%s', code label %s line %d. Script ended.\n\r", ln, scr->code_seg, scr->current_line - 1); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } void e_invalid_create_mob (SCRIPT_INFO * scr, char *ln) { sprintf (e_buf, "Invalid create mob vnum '%s', code label %s line %d. Script ended.\n\r", ln, scr->code_seg, scr->current_line - 1); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } void e_bad_if (SCRIPT_INFO * scr, char *ln) { sprintf (e_buf, "Invalid if statement '%s', code label %s line %d. Script ended.\n\r", ln, scr->code_seg, scr->current_line - 1); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } void e_bad_destroy_num (SCRIPT_INFO * scr, char *ln) { sprintf (e_buf, "Bad destroy vnum: %s, code label %s line %d. Script ended.\n\r", ln, scr->code_seg, scr->current_line - 1); if (debugger) send_to_char (e_buf, debugger); end_script (scr); return; } char * substitue_vars (SCRIPT_INFO * scr, char *ln) { static char curln[8000]; char *t; int pos = 0; curln[0] = '\0'; MARK_DEBUG ("Substitute_vars") for (t = ln; *t != '\0'; t++) { if (*t == '@') { t++; if (*t == '\0') break; if (UPPER (*t) == 'C') { char toad[8000]; toad[0] = '\0'; curln[pos] = '\0'; t++; if (*t == 't') { sprintf(toad,"%d",time_info.hour); } else if (*t == 'r') { sprintf(toad,"%d",scr->current->pcdata->remort_times); } else if (*t == 'K') { sprintf(toad,"%d",scr->current->pcdata->totalkills); } else if (*t == 'k') { sprintf(toad,"%d",scr->current->pcdata->killpoints); } else if (*t == 'c') { sprintf(toad,"%d",clan_number(scr->current)); } else if (*t == 'C') { sprintf(toad,"%d",clan_number_2(scr->current)); } else if (*t == 'm') { sprintf(toad,"%d",scr->current->move); } else if (*t == 'M') { sprintf(toad,"%d",scr->current->max_move); } else if (*t == 'H') { sprintf(toad,"%d",scr->current->max_hit); } else if (*t == 'h') { sprintf(toad,"%d",scr->current->hit); } else if (*t == 'w') { sprintf(toad,"%d",(IS_PLAYER(scr->current)?scr->current->pcdata->warpoints:0)); } else if (*t == 'g') { if (!IS_EVIL (scr->current)) { strcpy (toad, "1"); } else strcpy (toad, "0"); } else if (*t == 'e') { if (!IS_EVIL (scr->current)) { strcpy (toad, "0"); } else strcpy (toad, "1"); } else if (*t == 'l') { sprintf(toad,"%d",LEVEL(scr->current)); } strcat (curln, toad); pos += strlen (toad); continue; } if (UPPER (*t) == 'V') { char vv[500]; curln[pos] = '\0'; if (scr->obj && scr->obj->pIndexData->item_type==ITEM_CORPSE_NPC) { sprintf(vv,"%d",((I_CONTAINER *) (scr->obj->more))->key_vnum); strcat(curln,vv); pos += strlen(vv); } else if (scr->mob) { char tmp[50]; sprintf(tmp,"%d",scr->mob->pIndexData->vnum); strcat (curln,tmp); pos += strlen (tmp); } else if (scr->obj) { char tmp[50]; sprintf(tmp,"%d",scr->obj->pIndexData->vnum); strcat (curln, tmp); pos += strlen (tmp); } else if (scr->room) { char tmp[50]; sprintf(tmp,"%d",scr->room->vnum); strcat (curln, tmp); pos += strlen (tmp); } else continue; } if (UPPER (*t) == 'P') { /* Player name */ curln[pos] = '\0'; if (scr->current) { strcat (curln, NAME (scr->current)); pos += strlen (NAME (scr->current)); } continue; } if (UPPER (*t) == 'M') { /* Mob name */ curln[pos] = '\0'; if (scr->mob) { strcat (curln, NAME (scr->mob)); pos += strlen (NAME (scr->mob)); } continue; } if (UPPER (*t) == 'O') { /* Obj name */ curln[pos] = '\0'; if (scr->obj) { strcat (curln, scr->obj->pIndexData->short_descr); pos += strlen (scr->obj->pIndexData->short_descr); } continue; } if (UPPER (*t) == 'R') { /* Random number eg... @R(1,10) */ char num1[50]; char num2[50]; int n1; int n2; int rn; int tt = 0; curln[pos] = '\0'; t++; if (*t != '(') continue; t++; for (; *t != ',' && *t != ')'; t++) { num1[tt] = *t; tt++; } num1[tt] = '\0'; t++; tt = 0; for (; *t != ')'; t++) { if (*t != ' ') num2[tt] = *t; tt++; } { char tmp[50]; num2[tt] = '\0'; n1 = atoi (num1); n2 = atoi (num2); rn = number_range (n1, n2); sprintf(tmp,"%d",rn); strcat (curln, tmp); pos += strlen (tmp); continue; } } continue; } curln[pos] = *t; pos++; } curln[pos] = '\0'; return curln; } void execute_code (SCRIPT_INFO * scr) { CODE *c; char cur_line[5000]; char arg1[5000]; char curl2[5000]; char *ln; int i; int linenum; char *t; char argg[5000]; executed_lines = 0; MARK_DEBUG ("Execute_code") if (!scr->current || !scr->called_by || !scr->current->in_room) { end_script (scr); return; } /*sprintf(cl,":Current (%s) (%d)",NAME(scr->current),scr->current->in_room->vnum); sprintf(cl+strlen(cl),":Called_by (%s)",scr->called_by->trigger_id); */ /* Halt script if character left the room and the script says to do so */ if (scr->called_by && scr->called_by->leaves_room && ((scr->mob && scr->mob->in_room != scr->current->in_room) || (scr->room && scr->room != scr->current->in_room))) { end_script (scr); return; } execute: /* Main execute loop */ cur_line[0] = '\0'; i = 0; linenum = 0; t = NULL; ln = NULL; arg1[0] = '\0'; scr->tick_type = 0; scr->delay_ticks = 0; c = NULL; if ((c = find_code (scr->code_seg)) == NULL) { e_couldnt_find_label (scr, scr->code_seg, 0); return; } if (scr->current_line == 0) scr->current_line = 1; for (t = c->code; *t != '\0'; t++) { if (*t == ':') linenum++; if (linenum == scr->current_line) { t++; for (; *t != ' ' && *t != ':' && *t != '\0'; t++) { } if (*t != '\0') t++; for (; *t != '\n' && *t != ':' && *t != '\0'; t++) { cur_line[i] = *t; i++; } cur_line[i] = '\0'; goto foundit; } } end_script (scr); /* Past the max line numbers */ return; foundit: strcpy (curl2, substitue_vars (scr, cur_line)); strcpy (cur_line, curl2); one_argy (curl2, argg); ln = cur_line; /*sprintf(cl,"Scriptline: %s\n",cur_line); */ scr->current_line++; /* Increment 'program counter' */ /* Begin interpretting commands */ if (!str_cmp (argg, "call")) { /* Call <other code label> */ char clab[500]; ln = one_argy (ln, arg1); if ((c = find_code (ln)) == NULL) { e_couldnt_find_label (scr, ln, scr->current_line - 1); return; } strcpy(clab,scr->code_seg); strcpy (scr->code_seg, ln); scr->current_line = 1; execute_code(scr); strcpy(scr->code_seg,clab); return; } else if (!str_cmp (argg, "goto")) { int totl = 0; int got = 0; char *tt; ln = one_argy (ln, arg1); for (tt = c->code; *tt != '\0'; tt++) { if (*tt == ':') totl++; } if (!is_number (ln)) { e_goto_invalid_line_number (scr, ln, scr->current_line - 1); return; } got = atoi (ln); if (got < 1 || got > totl) { e_goto_invalid_line_number (scr, ln, scr->current_line - 1); return; } scr->current_line = got; } else if (!str_cmp (argg, "wait")) { char *l; char rg1[500]; char rg2[500]; int wait; l = cur_line; l = one_argy (l, rg1); l = one_argy (l, rg2); /* rg1 holds wait, rg2 holds number, l holds tick type */ if ((wait = atoi (rg2)) < 1) { e_bad_wait_value (scr, rg2); return; } if (!str_cmp (l, "superquick")) { scr->tick_type = 4; scr->delay_ticks = wait; } else if (!str_cmp (l, "quick")) { scr->tick_type = 1; scr->delay_ticks = wait; } else if (!str_prefix ("heart", l)) { scr->tick_type = 2; scr->delay_ticks = wait; } else if (!str_cmp (l, "hour")) { scr->tick_type = 3; scr->delay_ticks = wait; } else { e_bad_wait_type (scr, l); } return; } else if (!str_cmp (cur_line, "done")) { end_script (scr); return; } else if (!str_prefix ("create_mob", argg)) { int mnum; MOB_PROTOTYPE *m; CHAR_DATA *mob; char *l = cur_line; l = one_argy (l, argg); if (!is_number (l)) { e_invalid_create_mob (scr, l); return; } mnum = atoi (l); if ((m = get_mob_index (mnum)) == NULL) { e_invalid_create_mob (scr, l); return; } mob = create_mobile (m); /* Created the mob.. now place in room.. */ if (scr->mob) { char_to_room (mob, scr->mob->in_room); } else if (scr->room) { char_to_room (mob, scr->room); } if (scr->obj) { if (scr->obj->carried_by != NULL) char_to_room (mob, scr->current->in_room); else if (scr->obj->in_room != NULL) char_to_room (mob, scr->obj->in_room); } } else if (!str_prefix ("destroy_mob", argg)) { char *l = cur_line; l = one_argy (l, argg); if (scr->current) { stop_fighting (scr->current, TRUE); char_from_room (scr->current); extract_char (scr->current, TRUE); return; } } else if (!str_prefix ("destroy_obj", argg)) { char *l = cur_line; OBJ_PROTOTYPE *op; l = one_argy (l, argg); if (scr->obj) { obj_from (scr->obj); free_it (scr->obj); /*free_it also stops ends script! */ return; } if (!is_number (l)) { e_bad_destroy_num (scr, l); return; } if ((op = get_obj_index (atoi (l))) == NULL) { e_bad_destroy_num (scr, l); return; } if (scr->mob) { SINGLE_OBJECT *o; SINGLE_OBJECT *o_next_content; bool des = FALSE; for (o = scr->mob->carrying; o != NULL && !des; o = o_next_content) { o_next_content = o->next_content; if (o->pIndexData == op) { obj_from (o); free_it (o); des = TRUE; } } } else if (scr->room) { SINGLE_OBJECT *o; SINGLE_OBJECT *o_next_content; bool des = FALSE; if (scr->room->more) for (o = scr->room->more->contents; o != NULL && !des; o = o_next_content) { o_next_content = o->next_content; if (o->pIndexData == op) { obj_from (o); free_it (o); des = TRUE; } } } } else if (!str_prefix ("create_obj_char", argg)) { int onum; OBJ_PROTOTYPE *o; SINGLE_OBJECT *obj; char *l = cur_line; l = one_argy (l, argg); if (!is_number (l)) { e_invalid_create_obj (scr, l); return; } onum = atoi (l); if ((o = get_obj_index (onum)) == NULL) { e_invalid_create_obj (scr, l); return; } obj = create_object (o, 1); if (scr->current) { obj_to (obj, scr->current); } } else if (!str_prefix ("create_obj", argg)) { int onum; OBJ_PROTOTYPE *o; SINGLE_OBJECT *obj; char *l = cur_line; l = one_argy (l, argg); if (!is_number (l)) { e_invalid_create_obj (scr, l); return; } onum = atoi (l); if ((o = get_obj_index (onum)) == NULL) { e_invalid_create_obj (scr, l); return; } obj = create_object (o, 1); /* Created the object.. now place in room, on char, on mob.. */ if (scr->mob) { obj_to (obj, scr->mob); } else if (scr->room) { obj_to (obj, scr->room); } if (scr->obj) { if (scr->obj->carried_by != NULL) obj_to (obj, scr->obj->carried_by); else if (scr->obj->in_room != NULL) obj_to (obj, scr->obj->in_room); else if (scr->obj->in_obj != NULL) obj_to (obj, scr->obj->in_obj); } } else if (!str_cmp (argg, "if")) { char *l = cur_line; char *tc; char leftnum[50]; int cci = 0; bool beq = FALSE; bool bge = FALSE; bool bgt = FALSE; bool ble = FALSE; bool blt = FALSE; bool bne = FALSE; char rightnum[50]; l = one_argy (l, argg); if (*l == '(') { int st; bool ne = FALSE; l++; if (*l == '!') { ne = TRUE; l++; } for (tc = l; *tc != ')'; tc++) { if (*tc == '\0') { e_bad_if (scr, cur_line); return; } leftnum[cci] = *tc; cci++; } leftnum[cci] = '\0'; for (st = 0; st < 3000; st++) { if (!scr->current->pcdata->script_flags[st] || scr->current->pcdata->script_flags[st][0] == '\0') continue; if (!str_cmp (scr->current->pcdata->script_flags[st], leftnum)) goto matched; } scr->current_line++; goto dunw; matched: if (ne) scr->current_line++; dunw: if (scr) {}; } else { for (tc = l; *tc != '=' && *tc != '>' && *tc != '<' && *tc != '!'; tc++) { if (*tc == '\0') { e_bad_if (scr, cur_line); return; } if (*tc == ' ') continue; leftnum[cci] = *tc; cci++; } leftnum[cci] = '\0'; if (*tc == '=') { if (*(tc + 1) == '=') tc++; beq = TRUE; } else if (*tc == '>') { if (*(tc + 1) == '=') { tc++; bge = TRUE; } else bgt = TRUE; } else if (*tc == '<') { if (*(tc + 1) == '=') { tc++; ble = TRUE; } else blt = TRUE; } else if (*tc == '!') { if (*(tc + 1) == '=') { tc++; } bne = TRUE; } else { e_bad_if (scr, cur_line); return; } tc++; cci = 0; for (; *tc != ' '; tc++) { if (*tc == '\0') { e_bad_if (scr, cur_line); return; } rightnum[cci] = *tc; cci++; } rightnum[cci] = '\0'; if (is_number (leftnum)) { int lnm; int rnm; lnm = atoi (leftnum); rnm = atoi (rightnum); if (beq && lnm != rnm) { scr->current_line++; } else if (bgt && lnm <= rnm) { scr->current_line++; } else if (bge && lnm < rnm) { scr->current_line++; } else if (blt && lnm >= rnm) { scr->current_line++; } else if (ble && lnm > rnm) { scr->current_line++; } else if (bne && lnm == rnm) { scr->current_line++; } } else { if (bne && !str_cmp (leftnum, rightnum)) { scr->current_line++; } else if (!bne && str_cmp (leftnum, rightnum)) { scr->current_line++; } } } } else if (!str_cmp (argg, "recho")) { char *l = cur_line; l = one_argy (l, argg); do_recho (scr->current, l); } else if (!str_cmp (argg, "show")) { char *l = cur_line; l = one_argy (l, argg); send_to_char (l, scr->current); send_to_char ("\n\r", scr->current); } else if (!str_cmp (argg, "show_to_room")) { char *l = cur_line; l = one_argy (l, argg); act (l, scr->current, NULL, scr->current, TO_ROOM); } else if (scr->mob) { interpret (scr->mob, cur_line); } else if (scr->room || scr->obj) { /* Warning.. should ONLY be used for pset, etc.. not recho! */ CHAR_DATA *sch; sch=create_mobile(get_mob_index(1)); if (scr->room) char_to_room(sch,scr->room); else char_to_room(sch,get_room_index(1)); interpret (sch, cur_line); extract_char(sch,TRUE); } /* End interpretting commands */ executed_lines++; if (executed_lines > 300) { e_repeating_loop (scr); return; } goto execute; return; } char * string_unpad (char *argy) { char buf[STD_LENGTH]; char *s; s = argy; while (*s == ' ') s++; strcpy (buf, s); s = buf; if (*s != '\0') { while (*s != '\0') s++; s--; while (*s == ' ') s--; s++; *s = '\0'; } free_string (argy); return str_dup (buf); } char * string_proper (char *argy) { char *s; s = argy; while (*s != '\0') { if (*s != ' ') { *s = UPPER (*s); while (*s != ' ' && *s != '\0') s++; } else { s++; } } return argy; } char * string_replace (char *orig, char *old, char *new) { char xbuf[STD_LENGTH]; int i; xbuf[0] = '\0'; strcpy (xbuf, orig); if (strstr (orig, old) != NULL) { i = strlen (orig) - strlen (strstr (orig, old)); xbuf[i] = '\0'; strcat (xbuf, new); strcat (xbuf, &orig[i + strlen (old)]); free_string (orig); } return str_dup (xbuf); } void string_edit (CHAR_DATA * ch, char **pString) { send_to_char ("-=======================================-\n\r", ch); send_to_char (" Entering line editing mode.\n\r", ch); send_to_char (" Terminate with a @ on a blank line.\n\r", ch); send_to_char ("-=======================================-\n\r", ch); if (*pString == NULL) { *pString = str_dup (""); } else { free_string (*pString); *pString = str_dup (""); } ch->desc->pString = pString; return; } void string_append (CHAR_DATA * ch, char **pString) { send_to_char ("------------------------ LINE Editor -------------------------\n\r", ch); send_to_char (" Type .c to clear the whole text, .f to format the text,\n\r", ch); send_to_char (" .r 'orig' 'new' to replace, and .s to view the string so far.\n\r", ch); send_to_char (" Use @ on a blank line to save and quit the editor.\n\r", ch); send_to_char ("--------------------------------------------------------------\n\r", ch); if (*pString == NULL) { *pString = str_dup (""); } send_to_char ("Editing description:\n\r", ch); send_edit_char (*pString, ch); send_to_char ("-=======================================-\n\r", ch); ch->desc->pString = pString; return; } void string_add (CHAR_DATA * ch, char *argy) { char buf[40000]; if (!ch->desc) return; if (!ch->pcdata->name) return; if (!argy || argy == "") return; if (*argy == ':') { char texts[202][255]; char *lne; char *t; int i = 0; int mrk = 0; int curline = -1; int linenum = 0; buf[0] = '\0'; for (t = argy; *t != ' ' && *t != '\0'; t++) { mrk++; } *t = '\0'; lne = (argy + 1); if ((linenum = atoi (lne)) < 1 || linenum > 199) { send_to_char ("Invalid line number!\n\r", ch); return; } argy += mrk + 1; for (t = *ch->desc->pString; *t != '\0'; t++) { if (*t == ':' || t == *ch->desc->pString) { for (; *(t + 1) != '\0' && *t != ' '; t++) { }; if (curline >= 0) texts[curline][i] = '\0'; curline++; i = 0; continue; } if (curline < 0) curline = 0; if (*t == '\r') continue; if (*t == '\n') continue; texts[curline][i] = *t; i++; } texts[curline][i] = '\0'; /* Insert into correct place */ for (i = curline; i >= linenum - 1; i--) { strcpy (texts[i + 1], texts[i]); } strcpy (texts[linenum - 1], argy); curline++; /* Now reconstruct in the char buffer */ buf[0] = '\0'; for (i = 0; i <= curline; i++) { sprintf (buf + strlen (buf), ":%d ", i + 1); strcat (buf, texts[i]); } strcat (buf, "\n\r"); free_string (*ch->desc->pString); *ch->desc->pString = str_dup (buf); return; } if (*argy == '.') { char arg1[SML_LENGTH]; char arg2[SML_LENGTH]; char arg3[SML_LENGTH]; argy = one_argy (argy, arg1); argy = first_arg (argy, arg2, FALSE); argy = first_arg (argy, arg3, FALSE); if (!str_cmp (arg1, ".c")) { if (is_number (arg2)) { char texts[202][150]; int i = 0; char *t; int curline = -1; int linenum = atoi (arg2); buf[0] = '\0'; if (linenum < 1 || linenum > 199) { send_to_char ("Invalid line number!\n\r", ch); return; } for (t = *ch->desc->pString; *t != '\0'; t++) { if (*t == ':' || t == *ch->desc->pString) { for (; *(t + 1) != '\0' && *t != ' '; t++) { }; if (curline >= 0) texts[curline][i] = '\0'; curline++; i = 0; continue; } if (curline < 0) curline = 0; if (*t == '\r') continue; if (*t == '\n') continue; texts[curline][i] = *t; i++; } texts[curline][i] = '\0'; buf[0] = '\0'; for (i = linenum; i <= curline; i++) { strcpy (texts[i - 1], texts[i]); } texts[i][0] = '\0'; curline--; buf[0] = '\0'; for (i = 0; i <= curline; i++) { sprintf (buf + strlen (buf), ":%d ", i + 1); strcat (buf, texts[i]); } strcat (buf, "\n\r"); free_string (*ch->desc->pString); *ch->desc->pString = str_dup (buf); return; } send_to_char ("String cleared.\n\r", ch); free_string (*ch->desc->pString); *ch->desc->pString = str_dup (""); return; } if (!str_cmp (arg1, ".s")) { send_to_char ("String so far:\n\r", ch); send_edit_char (*ch->desc->pString, ch); return; } if (!str_cmp (arg1, ".r")) { if (arg2[0] == '\0') { send_to_char ("usage: .r \"old text\" \"new text\"\n\r", ch); return; } *ch->desc->pString = string_replace (*ch->desc->pString, arg2, arg3); sprintf (buf, "'%s' replaced with '%s'.\n\r", arg2, arg3); send_to_char (buf, ch); return; } if (!str_cmp (arg1, ".f")) { *ch->desc->pString = format_string (*ch->desc->pString); send_to_char ("String formatted.\n\r", ch); return; } if (!str_cmp (arg1, ".h")) { send_to_char ("Help (commands): \n\r", ch); send_to_char (".r 'old text' 'new text' - replace a string with a new string \n\r", ch); send_to_char (" (requires '' OR \"\" around the argys)\n\r", ch); send_to_char (".h - this info \n\r", ch); send_to_char (".s - show the string \n\r", ch); send_to_char (".f - format (word wrap/capitalize and space) string \n\r", ch); send_to_char (".c - clear the entire string! \n\r", ch); send_to_char ("@ - end string editor \n\r", ch); return; } send_to_char ("Command unrecognized.\n\r", ch); return; } if (*argy == '~' || *argy == '@') { ch->desc->pString = NULL; return; } if (LEVEL (ch) < 110 && *ch->desc->pString && strlen (*ch->desc->pString) > 5000) { send_to_char ("Edited text too long.\n\r", ch); free_string (*ch->desc->pString); *ch->desc->pString = &str_empty[0]; ch->desc->pString = NULL; return; } strcpy (buf, *ch->desc->pString); if (strlen(buf)>4096) { send_to_char ("String too long, truncating.\n\r", ch); free_string (*ch->desc->pString); *ch->desc->pString = str_dup(""); ch->desc->pString = NULL; return; } if (strlen (buf) + strlen (argy) >= (STD_LENGTH - 4)) { send_to_char ("String too long, truncating.\n\r", ch); free_string (*ch->desc->pString); *ch->desc->pString = str_dup(""); ch->desc->pString = NULL; return; } strcat (buf, argy); strcat (buf, "\n\r"); free_string (*ch->desc->pString); *ch->desc->pString = str_dup (buf); return; } char * format_string (char *oldstring) { char xbuf[40000]; char xbuf2[40000]; char *rdesc; char *t; int i = 0; bool cap = TRUE; xbuf[0] = xbuf2[0] = 0; i = 0; for (t = oldstring; *t; t++) { if (*t == ':' && *(t + 1) >= '0' && *(t + 1) <= '9') { xbuf[0] = '\0'; i = 0; for (t = oldstring; *t; t++) { if (*t == '\n' || *t == '\r') continue; xbuf[i] = *t; i++; } xbuf[i] = '\n'; xbuf[i + 1] = '\r'; xbuf[i + 2] = '\0'; free_string (oldstring); return (str_dup (xbuf)); } } for (rdesc = oldstring; *rdesc; rdesc++) { if (*rdesc == '\n') { if (xbuf[i - 1] != ' ') { xbuf[i] = ' '; i++; } } else if (*rdesc == '\r'); else if (*rdesc == ' ') { if (xbuf[i - 1] != ' ') { xbuf[i] = ' '; i++; } } else if (*rdesc == ')') { if (xbuf[i - 1] == ' ' && xbuf[i - 2] == ' ' && (xbuf[i - 3] == '.' || xbuf[i - 3] == '?' || xbuf[i - 3] == '!')) { xbuf[i - 2] = *rdesc; xbuf[i - 1] = ' '; xbuf[i] = ' '; i++; } else { xbuf[i] = *rdesc; i++; } } else if ((*rdesc == '.' && *(rdesc + 1) < '0' && *(rdesc + 1) > '9') || *rdesc == '?' || *rdesc == '!') { if (xbuf[i - 1] == ' ' && xbuf[i - 2] == ' ' && (xbuf[i - 3] == '.' || xbuf[i - 3] == '?' || xbuf[i - 3] == '!')) { xbuf[i - 2] = *rdesc; if (*(rdesc + 1) != '\"') { xbuf[i - 1] = ' '; xbuf[i] = ' '; i++; } else { xbuf[i - 1] = '\"'; xbuf[i] = ' '; xbuf[i + 1] = ' '; i += 2; rdesc++; } } else { xbuf[i] = *rdesc; if (*(rdesc + 1) != '\"') { xbuf[i + 1] = ' '; xbuf[i + 2] = ' '; i += 3; } else { xbuf[i + 1] = '\"'; xbuf[i + 2] = ' '; xbuf[i + 3] = ' '; i += 4; rdesc++; } } cap = TRUE; } else { xbuf[i] = *rdesc; if (cap) { cap = FALSE; xbuf[i] = UPPER (xbuf[i]); } i++; } } xbuf[i] = 0; strcpy (xbuf2, xbuf); rdesc = xbuf2; xbuf[0] = 0; for (;;) { for (i = 0; i < 77; i++) { if (!*(rdesc + i)) break; } if (i < 77) { break; } for (i = (xbuf[0] ? 76 : 73); i; i--) { if (*(rdesc + i) == ' ') break; } if (i) { *(rdesc + i) = 0; strcat (xbuf, rdesc); strcat (xbuf, "\n\r"); rdesc += i + 1; while (*rdesc == ' ') rdesc++; } else { bug ("No spaces", 0); *(rdesc + 75) = 0; strcat (xbuf, rdesc); strcat (xbuf, "-\n\r"); rdesc += 76; } } while (*(rdesc + i) && (*(rdesc + i) == ' ' || *(rdesc + i) == '\n' || *(rdesc + i) == '\r')) i--; *(rdesc + i + 1) = 0; strcat (xbuf, rdesc); if (xbuf[strlen (xbuf) - 2] != '\n') strcat (xbuf, "\n\r"); free_string (oldstring); return (str_dup (xbuf)); } /* * Replace a substring with a new substring, return the new version. * (make sure to str_dup() when needed) */ char * replace_string (char *orig, char *old, char *new) { char xbuf[STD_LENGTH]; int i; xbuf[0] = '\0'; strcpy (xbuf, orig); if (strstr (orig, old) != NULL) { i = strlen (orig) - strlen (strstr (orig, old)); xbuf[i] = '\0'; strcat (xbuf, new); strcat (xbuf, &orig[i + strlen (old)]); free_string (orig); } return (str_dup (xbuf)); } bool one_is_of_two (char *looking_for, char *line) { char arg[8000]; char *r; arg[0]='\0'; while (line[0] != '\0') { line = one_argy (line, arg); r = arg; if (!str_cmp (looking_for, r) || (strlen (looking_for) > 4 && !str_prefix (looking_for, r)) || (strlen (looking_for) > 4 && !str_prefix (r, looking_for)) || !str_infix (r, looking_for)) return TRUE; } return FALSE; } bool one_is_in_list_two (char *looking_for, char *line) { char arg[8000]; char *r; arg[0]='\0'; while (line[0] != '\0') { line = one_argy (line, arg); r = arg; if (!str_cmp (looking_for, r)) return TRUE; } return FALSE; }