/************************************************************************
Realms of Aurealis James Rhone aka Vall of RoA
RoA RoomProc code version 1.0 Beta
roomproc.c Realms of Aurealis RoomProc code, specifically written
for RoA with OLCable RoomProcs in mind... note this is
completely ORIGINAL code, as you can tell by its crude
form.
******** 100% completely original code ********
*** BE AWARE OF ALL RIGHTS AND RESERVATIONS ***
******** 100% completely original code ********
All rights reserved henceforth.
Please note that no guarantees are associated with any code from
Realms of Aurealis. All code which has been released to the general
public has been done so with an 'as is' pretense. RoA is based on both
Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well
as the RoA license. *** Read, Learn, Understand, Improve ***
*************************************************************************/
#include "conf.h"
#include "sysdep.h"
#include "structures.h"
#include "utils.h"
#include "db.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "magic.h"
#include "roomproc.h"
#include "acmd.h"
#include "quest.h"
#include "lists.h"
#include "htown.h"
#include "clicomm.h"
#include "fight.h"
#include "nature.h"
#include "global.h"
/* external vars */
extern int rev_dir[];
extern char *comm_dirs[];
extern char *genders[];
extern struct htown_data htowns[];
// external functions
extern struct rtrig_type *free_rtriggers(struct rtrig_type *head);
extern int check_room_affects(chdata *ch, int room);
// prototypes
int rproc_interpreter(rmdata *r, char *comm, chdata *ch, obdata *ob, BOOL reaction);
// local defines
#define MAX_ROOM_REACTIONS 10
#define MAX_ROOM_REACTION_LENGTH 1024
/* simple structure for corresponding roomproc calls... */
const struct rproc_type rproc_calls[] = {
{"rreset", do_rreset},
{"rstart", do_rstart},
{"rend", do_rend},
{"rpause", do_rpause},
{"rgoto", do_rgoto},
{"rtrigwait", do_rtrig_wait},
{"rtrigoff", do_rtrig_off},
{"rtrigon", do_rtrig_on},
{"rtrigwax", do_rtrig_wax},
{"rtrigadd", do_rtrig_add},
{"rtrigdelete", do_rtrig_delete},
{"recho", do_recho},
{"rechochar", do_rechochar},
{"rsoundsendchar", do_rsoundsendchar},
{"rsoundsendroom", do_rsoundsendroom},
{"rrandom", do_rrandom},
{"rexittoggle", do_rexittoggle},
{"rexitopen", do_rexitopen},
{"rexitclose", do_rexitclose},
{"rexitlock", do_rexitlock},
{"rexitunlock", do_rexitunlock},
{"rexitsecret", do_rexitsecret},
{"rexitvisible", do_rexitvisible},
{"rexitlead", do_rexitlead},
{"rteleport", do_rteleport},
{"rtransmob", do_rtransmob},
{"rtransobj", do_rtransobj},
{"rsetremote", do_rsetremote},
{"runsetremote", do_runsetremote},
{"rtag", do_rtag},
{"rtargetroom", do_rtarget},
{"rtargetzone", do_rtarget_zone},
{"rtargetset", do_rtarget_set},
{"rif", do_rif},
{"", NULL} /* last one used for check of end of defines */
};
// what RIF checks are available?
char *rif_BOOLs[] = {
"tarcharset", "!tarcharset",
"tarobjset", "!tarobjset",
"tarcharroom", "!tarcharroom",
"tarobjroom", "!tarobjroom",
"tarcharzone", "!tarcharzone",
"tarobjzone", "!tarobjzone",
"tarcharpc", "!tarcharpc",
"tarcharcompquest", "!tarcharcompquest",
"tarcharlevel",
"npcinroom", "!npcinroom",
"objinroom", "!objinroom",
"transpresent", "!transpresent",
"tarcharonquest", "!tarcharonquest",
"tarcharrace", "!tarcharrace",
"tarcharclass", "!tarcharclass",
"tarchargender", "!tarchargender",
"\n"
};
// let imms shut off triggers while they work...
// 6/13/98 -jtrhone
ACMD(do_rpcom)
{
char *argu = argument;
if (IS_NPC(ch) || INVALID_ROOM(ch->in_room))
return;
skip_spaces(&argu);
if (!*argu)
{
send_to_char("Usage: rpcom <reset | end>.\n\r",ch);
return;
}
if (is_abbrev(argu, "reset"))
{
do_rreset(&world[ch->in_room], "");
do_rtrig_on(&world[ch->in_room], "");
return;
}
else
if (is_abbrev(argu, "end"))
{
do_rend(&world[ch->in_room], "");
do_rtrig_off(&world[ch->in_room], "");
return;
}
else
{
send_to_char("Usage: rpcom <reset | end>.\n\r",ch);
return;
}
}
// for debugging rprocs... 6/6/98 -jtrhone
void S2IMM(char *messg, rmdata *r)
{
chdata *ch;
char mesg[MAX_STRING_LENGTH -10];
str_cpy(mesg, messg, MAX_STRING_LENGTH-10, "send_to_room_not_busy");
str_cat(mesg, "\n\r", MAX_STRING_LENGTH-10, "send_to_room_not_busy");
for (ch = r->people; ch; ch = ch->next_in_room)
if (AWAKE(ch) && SEND_OK(ch) && IS_IMMORTAL(ch) && PLR_FLAGGED(ch, PLR_LOGALL))
send_to_char(mesg, ch);
}
// let immortal see all roomproc commands available
ACMD(do_roomproc_show)
{
int i,j;
one_argument(argument, arg);
if (is_abbrev(arg, "rcommands"))
{
strcpy(buf, "%B%6RoomProc Commands%0:\n\r");
for (i=j=0; *rproc_calls[i].arg; i++)
{
sprintf(buf+strlen(buf), "%%5%%B%-19.19s%%0", rproc_calls[i].arg);
if (!(++j % 4))
strcat(buf, "\n\r");
}
if ((j%4))
strcat(buf, "\n\r");
page_string(ch->desc, buf, 1);
}
else
if (is_abbrev(arg, "rifs"))
{
strcpy(buf, "%B%6RoomProc RIF Args%0:\n\r");
for (i=j=0; *rif_BOOLs[i] != '\n'; i++)
{
sprintf(buf+strlen(buf), "%%5%%B%-19.19s%%0", rif_BOOLs[i]);
if (!(++j % 4))
strcat(buf, "\n\r");
}
if ((j%4))
strcat(buf, "\n\r");
page_string(ch->desc, buf, 1);
}
else
send_to_char("Usage: rprocshow < rcommands | rifs >.\n\r",ch);
}
// pause a roomproc, 1 per 5 seconds for DTIME rooms
// 1 per 10 seconds for normal roomprocs
int do_rpause(rmdata *r, char *argument)
{
int num = 0;
one_argument(argument, arg);
if (!is_number(arg))
return RP_NORMAL;
num = atoi(arg);
num = MAX(0, MIN(num, 99));
RPROC_WAIT(r) = num;
sprintf(buf, "Rproc pausing %d.", num);
S2IMM(buf, r);
return RP_NORMAL;
}
/* simply start from where th proc last ended */
/* only if actually RENDED that is */
/* if no rproc_cur, then restart */
int do_rstart(rmdata *r, char *argument)
{
if (RPROC_WAIT(r) >= 0)
return RP_NORMAL;
RPROC_WAIT(r) = 0;
/* ok, begin processing of commands with this roomproc */
if (!RPROC_CUR(r)) /* only jump to start if not pting to a comm */
RPROC_CUR(r) = RPROC_BEG(r);
S2IMM("Rproc started.", r);
return RP_NORMAL;
}
/* wipes out all waits, sets cur back to beginning */
/* does it regardless if in a proc or not */
int do_rreset(rmdata *r, char *argument)
{
RPROC_WAIT(r) = 0;
RPROC_CUR(r) = RPROC_BEG(r);
RTRIG_WAITING(r) = FALSE;
S2IMM("Rproc reset.", r);
return RP_NORMAL;
}
/* ends the processing of a roomproc, sets roomwait to -1 */
int do_rend(rmdata *r, char *argument)
{
if (RPROC_WAIT(r) < 0)
return RP_NORMAL; /* already ended */
RPROC_WAIT(r) = -1;
S2IMM("Rproc ended.", r);
return RP_NORMAL;
}
// sets room waiting for a trigger to go off 6.5.98 -jtrhone
int do_rtrig_wait(rmdata *r, char *argument)
{
if (RTRIG_WAITING(r)) // already awaiting trigger
return RP_NORMAL;
if (!RTRIGS(r)) // no trigs? aint gonna wait
return RP_NORMAL;
RTRIG_WAITING(r) = TRUE;
S2IMM("Rproc waiting for trigs.", r);
return RP_NORMAL;
}
// room will ignore triggers after this call
int do_rtrig_off(rmdata *r, char *argument)
{
if (RTRIG_IGNORE(r)) // already ignoring triggers
return RP_RTRIG;
if (!RTRIGS(r)) // no trigs? aint gonna ignore
return RP_RTRIG;
RTRIG_IGNORE(r) = TRUE;
S2IMM("Rproc ignoring trigs.", r);
return RP_RTRIG;
}
// room will NOT ignore triggers after this call
int do_rtrig_on(rmdata *r, char *argument)
{
if (!RTRIG_IGNORE(r)) // already listening to triggers
return RP_RTRIG;
if (!RTRIGS(r)) // no trigs? why bother
return RP_RTRIG;
RTRIG_IGNORE(r) = FALSE;
S2IMM("Rproc no longer ignoring trigs.", r);
return RP_RTRIG;
}
// add an rtrigger to rooms list of trigs -jtr
int add_rtrigger(rmdata *r, char *trigger, char *reaction)
{
rtrig *rt = NULL;
if (!trigger || !reaction)
{
sprintf(buf, "SYSERR: Missing trig or react to room #%d.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RTRIG;
}
// if adding existing trigger, replace reaction and return
for (rt = RTRIGS(r); rt; rt=rt->next)
if (!str_cmp(rt->trigger, trigger))
{
FREENULL(rt->reaction);
rt->reaction = STR_DUP(reaction);
S2IMM("Rproc replacing existing rtrig.", r);
return RP_RTRIG;
}
// ok new one, create and insert to front
CREATE(rt, rtrig, 1);
rt->trigger = STR_DUP(trigger);
rt->reaction = STR_DUP(reaction);
rt->next = RTRIGS(r);
RTRIGS(r) = rt;
sprintf(buf, "Rproc added rtrig: %s\n\rWith reaction: %s", rt->trigger, rt->reaction);
S2IMM(buf, r);
return RP_RTRIG;
}
// rtrigadd utilizes blocks of commands
// rtrigadd <trigger> {block of reactions} adds rtrig_type to rooms trigs list
int do_rtrig_add(rmdata *r, char *trigger)
{
char *pt; // our placeholder in the mproc list
int i;
char reaction[MAX_ROOM_REACTION_LENGTH];
if (!trigger)
{
sprintf(buf, "SYSERR: #%d fatal roomproc error. No trig to rtrigadd.", r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
do_rend(r, trigger); // end roomproc
return RP_RTRIG;
}
// must be a start block!
pt = RPROC_CUR(r);
skip_spaces(&pt);
if (!pt || !*pt || *pt != '{')
{
sprintf(buf, "SYSERR: #%d fatal roomproc error. No block after rtrigadd.", r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
do_rend(r, trigger); // end roomproc
return RP_RTRIG;
}
// yep, all the chars minus the two brackets
i = chars_in_block(pt);
if (i <= 0)
{
sprintf(buf, "SYSERR: #%d fatal roomproc error. Reaction block empty.", r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
do_rend(r, trigger); // end roomproc
return RP_RTRIG;
}
if (i >= MAX_ROOM_REACTION_LENGTH - 2)
{
sprintf(buf, "SYSERR: #%d fatal roomproc error. Reaction block too long.", r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
do_rend(r, trigger); // end roomproc
return RP_RTRIG;
}
strncpy(reaction, pt+1, i+1); // add one for newline...
reaction[i] = '\0';
add_rtrigger(r, trigger, reaction);
// OOOOkkk just skip the block...
RPROC_CUR(r) = skip_block(pt);
if (!RPROC_CUR(r) || !*RPROC_CUR(r))
RPROC_CUR(r) = RPROC_BEG(r);
return RP_RTRIG;
}
// remove an rtrigger from rooms list of trigs -jtr
int do_rtrig_delete(rmdata *r, char *trigger)
{
rtrig *rt = NULL, *next_rt, *temp;
if (!trigger)
{
sprintf(buf, "SYSERR: Missing trig to room #%d (remove_rtrig).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RTRIG;
}
if (!RTRIGS(r))
return RP_RTRIG;
for (rt = RTRIGS(r); rt; rt=next_rt)
{
next_rt = rt->next;
if (!str_cmp(rt->trigger, trigger))
{
REMOVE_FROM_LIST(rt, RTRIGS(r), next);
if (rt->trigger)
{
sprintf(buf, "Rproc removed rtrig: %s", rt->trigger);
S2IMM(buf, r);
free_log(rt->trigger, "do_rtrig_delete 1");
}
if (rt->reaction)
free_log(rt->reaction, "do_rtrig_delete 2");
free_log(rt, "do_rtrig_delete 3");
}
}
return RP_RTRIG;
}
// wax entire trigger list by roomproc command
int do_rtrig_wax(rmdata *r, char *argument)
{
if (!RTRIGS(r))
return RP_RTRIG;
RTRIGS(r) = free_rtriggers(RTRIGS(r));
RTRIG_WAITING(r) = FALSE; // cant be waiting if no list eh? -jtr
S2IMM("Rproc waxed all rtriggers.",r);
return RP_RTRIG;
}
// execute rproc_interpreter on reaction block with all EXCEPT
// some mtrig commands, and any block commands...
void perform_rtrig_reaction(rmdata *r, char *str, chdata *ch, obdata *ob)
{
int i;
char comm[MAX_ROOM_REACTION_LENGTH];
char *tmp;
if (!str || !*str) return;
/* parse the string using * as pseudo EOL along with ISNEWL */
for (tmp = str, i=0; tmp && *tmp; tmp++)
if (*tmp && !ISNEWL(*tmp))
comm[i++] = *tmp;
else
{
comm[i] = '\0';
if (*comm)
rproc_interpreter(r, comm, ch, ob, TRUE);
*comm = '\0';
i = 0;
}
comm[i] = '\0';
if (*comm)
rproc_interpreter(r, comm, ch, ob, TRUE);
}
// is string a subset of this trigger
int in_rtrig(char *trigger, char *string)
{
char *trig;
int num, i;
char comm[MAX_ROOM_REACTION_LENGTH];
extern int match(char *str, char *str2);
if (!string || !trigger || !*trigger || !*string ) return FALSE;
else num = 1;
for (trig = trigger; *trig; trig++)
if (*trig == '\n' || *trig == '*')
num++; /* count the subcommands in string */
if ((num > MAX_ROOM_REACTIONS) || (strlen(trig) > MAX_ROOM_REACTION_LENGTH))
{
sprintf(buf, "SYSUPD: rtrigger failed - %d trigs, length %d", num, strlen(trig));
mudlog(buf, BUG, LEV_IMM, TRUE);
return FALSE;
}
/* parse the trigger using * as pseudo EOL character */
for (trig = trigger, i = 0; *trig; trig++)
if (*trig && !ISNEWL(*trig) && *trig != '*')
{
comm[i] = *trig;
i++;
}
else
{
comm[i] = '\0';
if (*comm && *comm != '\n')
{
if (*comm == '#') // the pound indicates a SUBSTRING match(strstr)
{
if (*(comm + 1) && match((comm + 1), string))
return TRUE;
}
else
if (!str_cmp(comm, string))
return TRUE;
}
*comm = '\0';
i = 0;
}
/* now last subtrigger check */
comm[i] = '\0';
if (*comm && *comm != '\n')
{
if (*comm == '#') // the pound indicates a SUBSTRING match (strstr)
{
if (*(comm + 1) && match((comm + 1), string))
return TRUE;
}
else
if (!str_cmp(comm, string))
return TRUE;
}
return FALSE; /* we didnt find any matches */
}
/* does character's command trigger a rproc command? if so do it */
int check_rtrigs(chdata *ch, char *str)
{
char tmp[MAX_INPUT_LENGTH];
char *ptr;
rtrig *rt;
rmdata *r;
if (INVALID_ROOM(ch->in_room))
return FALSE;
if (!ROOM_FLAGGED(ch->in_room, RPROC) || !str || !*str)
return FALSE; /* sorry pal, try again next time */
r = &world[ch->in_room];
// lower case entire string arg, cpy to temp buf first
strcpy(tmp, str);
for (ptr = tmp; *ptr; ptr++)
if (isalpha(*ptr))
*ptr = LOWER(*ptr);
// rproc rtrigger list capabilities
if (!RTRIG_IGNORE(r))
for (rt = RTRIGS(r); rt; rt = rt->next)
if (in_rtrig(rt->trigger, tmp))
{
// set new char target to the one who triggered us
FREENULL(RTARGET_CHAR(r));
RTARGET_CHAR(r) = STR_DUP(GET_NAME(ch));
// now go perform the commands...
perform_rtrig_reaction(r, rt->reaction, ch, NULL);
RTRIG_WAITING(r) = FALSE;
S2IMM("Rtrig reaction triggered. Rtrigwait removed.", r);
return TRUE;
}
return FALSE;
}
// echo a string to room... (not busy)
// add support for possible remotes 6/13/98 -jtrhone
int do_recho(rmdata *r, char *comm)
{
char *arg = comm;
rmdata *tr;
skip_spaces(&arg);
if (!*arg)
{
sprintf(buf, "SYSERR: No arg to recho, room #%d.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
// else, send the argument...
send_to_room_not_busy(arg, real_room(tr->number));
return RP_NORMAL;
}
// rechochar <char name> <txt>
int do_rechochar(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
chdata *vict;
rmdata *tr;
half_chop(comm, arg1, arg2);
if (!*arg1 || !*arg2)
{
sprintf(buf, "SYSERR: Invalid arguments sent to rechochar (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
if (!(vict = get_char_room(arg1, real_room(tr->number))))
{
S2IMM("rechochar target not found...", r);
return RP_NORMAL;
}
send_to_char(arg2, vict);
send_to_char("\n\r", vict);
return RP_NORMAL;
}
/* return the number of commands in a rooms rproc (for gotos) */
int rproc_length(rmdata *r)
{
char *tmp;
int count;
if (!ROOM_FLAGGED(real_room(r->number), RPROC) || !*RPROC_BEG(r))
return 0;
for (count = 0, tmp = RPROC_BEG(r); *tmp; tmp++)
if (*tmp == '\n') count++;
return count;
}
// do nothing but set tag placeholder for rgotos
// 6/14/98 -jtrhone
int do_rtag(rmdata *r, char *argument)
{
if (!*argument)
{
sprintf(buf, "SYSERR: Undefined rtag tag (#%d).",r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RTAG;
}
return RP_RTAG;
}
// scan a rproc for rtag <tname>
char *get_rtag(char *proc, char *tname)
{
char *str = proc;
char arg1[MAX_STRING_LENGTH];
char arg2[MAX_STRING_LENGTH];
skip_spaces(&str);
while (*str)
{
half_chop(str, arg1, arg2);
if (!str_cmp(arg1, "rtag") && is_abbrev(tname, arg2))
return str;
str = scan_past_eol(str);
skip_spaces(&str);
if (!str || !*str)
break;
}
return NULL;
}
// goto a particular line of the room proc
// updated for use with rtags 6/14/98 -jtrhone
int do_rgoto(rmdata *r, char *argument)
{
int line, ctr;
char *tmp;
char arg1[MAX_INPUT_LENGTH];
one_argument(argument, arg1);
if (!*arg1)
{
sprintf(buf, "SYSERR: Missing arg to rgoto (#%d).",r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// lookin for rtag...
if (!is_number(arg1))
{
tmp = get_rtag(RPROC_BEG(r), arg1);
if (!tmp)
{
sprintf(buf, "SYSERR: Unable to locate rtag (%s) in rgoto (#%d).",arg1,r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// juuuust to make sure
if (tmp < RPROC_BEG(r))
{
sprintf(buf, "SYSERR: Lower bounds failure in rgoto (#%d).",r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
RPROC_CUR(r) = tmp;
sprintf(buf, "Rproc jumped to tag %s.",arg1);
S2IMM(buf, r);
return RP_NORMAL;
}
line = atoi(arg1);
if (line > rproc_length(r) || line < 1)
{
sprintf(buf, "SYSERR: Invalid line # to rgoto (#%d)",r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
sprintf(buf, "Rproc jumped to line %d.",line);
S2IMM(buf, r);
if (line == 1)
{
RPROC_CUR(r) = RPROC_BEG(r);
return RP_NORMAL;
}
tmp = RPROC_BEG(r);
ctr = 1;
while (ctr != line)
{
tmp = scan_past_eol(tmp);
ctr++;
}
RPROC_CUR(r) = tmp;
return RP_NORMAL;
}
// rsoundsendchar <char name> <soundfile name>
// char must have client connection
// add support for possible remotes 6/13/98 -jtrhone
int do_rsoundsendchar(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
chdata *vict;
rmdata *tr;
half_chop(comm, arg1, arg2);
if (!*arg1 || !*arg2)
{
sprintf(buf, "SYSERR: Invalid arguments sent to rsoundsendchar (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
if (!(vict = get_char_room(arg1, real_room(tr->number))))
{
S2IMM("rsoundsendchar target not found...", r);
return RP_NORMAL;
}
if (IS_PC(vict) && vict->desc && HAS_CLIENT(vict->desc))
send_soundfile_to_client(vict->desc, arg2);
return RP_NORMAL;
}
// rsoundsendroom <soundfile name>
// chars in room must have client connection
// add support for possible remotes 6/13/98 -jtrhone
int do_rsoundsendroom(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
chdata *vict;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1)
{
sprintf(buf, "SYSERR: Invalid arguments sent to rsoundsendroom (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
for (vict = tr->people; vict; vict=vict->next_in_room)
if (IS_PC(vict) && vict->desc && HAS_CLIENT(vict->desc))
send_soundfile_to_client(vict->desc, arg1);
return RP_NORMAL;
}
// rrandom followed by a block of randoms, chooses one and does command
// BLOCK COMMAND, not to be used in other block commands...
int do_rrandom(rmdata *r, char *argument)
{
char *pt; // our placeholder in the mproc list
char *tmp, *tmp2;
int count = 0, pick, i;
char comm[MAX_INPUT_LENGTH];
// must be a start block!
pt = RPROC_CUR(r);
skip_spaces(&pt);
if (!pt || !*pt || *pt != '{')
{
sprintf(buf, "SYSERR: Room #%d fatal rproc error. No block after rrandom.", r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
do_rend(r, argument); // end rproc
}
// now count commands in the block
for (tmp = pt, count = 0; *tmp && *tmp != '}'; tmp++)
{
tmp = scan_past_eol(tmp);
skip_spaces(&tmp);
if (!tmp || !*tmp || *tmp == '}')
break;
else
count++;
}
if (!tmp || !*tmp)
{
sprintf(buf, "SYSERR: Room #%d fatal rproc error. Rrandom blk never ended.", r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
do_rend(r, argument); // end rproc
}
// skip past closing bracket
tmp = scan_past_eol(tmp); // this is where we wanna point after we done
if (!count)
{
sprintf(buf, "SYSERR: Room #%d fatal rproc error. No randoms in rrandom blk.", r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
do_rend(r, argument); // end rproc
}
if (count > 1)
pick = number(1, count);
else
pick = 1;
// now go thru block and pick the pickth one
pt = scan_past_eol(pt);
for (count = 1, *comm = '\0'; count < pick; count++)
pt = scan_past_eol(pt);
skip_spaces(&pt);
/* get length of next command */
for (i=0, tmp2 = pt; *tmp2 && !ISNEWL(*tmp2) && (i < MAX_INPUT_LENGTH);
tmp2++, i++)
;
/* copy this command line into comm */
strncpy(comm, pt, i);
comm[i] = '\0';
/* show the imms in the room with logal on */
S2IMM(comm, r);
if (*comm != '&') // process only if not our ignore character
rproc_interpreter(r, comm, NULL, NULL, TRUE);
RPROC_CUR(r) = tmp;
return RP_RRANDOM;
}
// 6/11/98 - jtrhone
// add support for possible remotes 6/13/98 -jtrhone
int do_rexitopen(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
int dir, rroom, room;
rmdirdata *d;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1)
{
sprintf(buf, "SYSERR: Invalid argument sent to rexitopen (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// they are lookin at a direction
dir = search_block(arg1, comm_dirs, FALSE);
if (dir < 0 || dir > NUM_OF_DIRS)
{
sprintf(buf, "SYSERR: Invalid direction arg sent to rexitopen (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
rroom = real_room(tr->number);
if (!(d = DIR(rroom, dir)))
{
sprintf(buf, "SYSERR: rexitiopen (#%d), direction DNE.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (!EXIT_ISDOOR(d))
{
sprintf(buf, "SYSERR: rexitopen (#%d), direction cannot be opened.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (EXIT_CLOSED(d))
{
UNFLAG_EXIT(d, EX_CLOSED);
for (room = 0; room < top_of_world; room++)
if (DIR(room, rev_dir[dir]) && EXIT_ISDOOR(DIR(room, rev_dir[dir])) &&
EXIT_CLOSED(DIR(room, rev_dir[dir])) && DIR(room, rev_dir[dir])->to_room_virtual == tr->number)
{
UNFLAG_EXIT(DIR(room, rev_dir[dir]), EX_CLOSED);
}
}
return RP_NORMAL;
}
// 6/11/98 - jtrhone
// add support for possible remotes 6/13/98 -jtrhone
int do_rexitclose(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
int dir, rroom, room;
rmdirdata *d;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1)
{
sprintf(buf, "SYSERR: Invalid argument sent to rexitclose (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// they are lookin at a direction
dir = search_block(arg1, comm_dirs, FALSE);
if (dir < 0 || dir > NUM_OF_DIRS)
{
sprintf(buf, "SYSERR: Invalid direction arg sent to rexitclose (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
rroom = real_room(tr->number);
if (!(d = DIR(rroom, dir)))
{
sprintf(buf, "SYSERR: rexiticlose (#%d), direction DNE.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (!EXIT_ISDOOR(d))
{
sprintf(buf, "SYSERR: rexitclose (#%d), direction cannot be closed.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (EXIT_OPEN(d))
{
FLAG_EXIT(d, EX_CLOSED);
for (room = 0; room < top_of_world; room++)
if (DIR(room, rev_dir[dir]) && EXIT_ISDOOR(DIR(room, rev_dir[dir])) &&
EXIT_OPEN(DIR(room, rev_dir[dir])) && DIR(room, rev_dir[dir])->to_room_virtual == tr->number)
{
FLAG_EXIT(DIR(room, rev_dir[dir]), EX_CLOSED);
}
}
return RP_NORMAL;
}
// 6/11/98 - jtrhone
// add support for possible remotes 6/13/98 -jtrhone
int do_rexitlock(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
int dir, rroom, room;
rmdirdata *d;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1)
{
sprintf(buf, "SYSERR: Invalid argument sent to rexitlock (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// they are lookin at a direction
dir = search_block(arg1, comm_dirs, FALSE);
if (dir < 0 || dir > NUM_OF_DIRS)
{
sprintf(buf, "SYSERR: Invalid direction arg sent to rexitlock (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
rroom = real_room(tr->number);
if (!(d = DIR(rroom, dir)))
{
sprintf(buf, "SYSERR: rexitlock (#%d), direction DNE.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (!EXIT_ISDOOR(d))
{
sprintf(buf, "SYSERR: rexitlock (#%d), direction cannot be locked.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (EXIT_UNLOCKED(d))
{
FLAG_EXIT(d, EX_LOCKED);
for (room = 0; room < top_of_world; room++)
if (DIR(room, rev_dir[dir]) && EXIT_ISDOOR(DIR(room, rev_dir[dir])) &&
EXIT_UNLOCKED(DIR(room, rev_dir[dir])) && DIR(room, rev_dir[dir])->to_room_virtual == tr->number)
{
FLAG_EXIT(DIR(room, rev_dir[dir]), EX_LOCKED);
}
}
return RP_NORMAL;
}
// 6/11/98 - jtrhone
// add support for possible remotes 6/13/98 -jtrhone
int do_rexitunlock(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
int dir, rroom, room;
rmdirdata *d;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1)
{
sprintf(buf, "SYSERR: Invalid argument sent to rexitunlock (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// they are lookin at a direction
dir = search_block(arg1, comm_dirs, FALSE);
if (dir < 0 || dir > NUM_OF_DIRS)
{
sprintf(buf, "SYSERR: Invalid direction arg sent to rexitunlock (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
rroom = real_room(tr->number);
if (!(d = DIR(rroom, dir)))
{
sprintf(buf, "SYSERR: rexitunlock (#%d), direction DNE.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (!EXIT_ISDOOR(d))
{
sprintf(buf, "SYSERR: rexitunlock (#%d), direction cannot be unlocked.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (EXIT_LOCKED(d))
{
UNFLAG_EXIT(d, EX_LOCKED);
for (room = 0; room < top_of_world; room++)
if (DIR(room, rev_dir[dir]) && EXIT_ISDOOR(DIR(room, rev_dir[dir])) &&
EXIT_LOCKED(DIR(room, rev_dir[dir])) && DIR(room, rev_dir[dir])->to_room_virtual == tr->number)
{
UNFLAG_EXIT(DIR(room, rev_dir[dir]), EX_LOCKED);
}
}
return RP_NORMAL;
}
// 6/14/98 - jtrhone
int do_rexitvisible(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
int dir, rroom;
rmdirdata *d;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1)
{
sprintf(buf, "SYSERR: Invalid argument sent to rexitvisible (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// they are lookin at a direction
dir = search_block(arg1, comm_dirs, FALSE);
if (dir < 0 || dir > NUM_OF_DIRS)
{
sprintf(buf, "SYSERR: Invalid direction arg sent to rexitvisible (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
rroom = real_room(tr->number);
if (!(d = DIR(rroom, dir)))
{
sprintf(buf, "SYSERR: rexitvisible (#%d), direction DNE.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
UNFLAG_EXIT(d, EX_SECRET);
return RP_NORMAL;
}
// 6/14/98 - jtrhone
int do_rexitsecret(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
int dir, rroom;
rmdirdata *d;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1)
{
sprintf(buf, "SYSERR: Invalid argument sent to rexitsecret (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// they are lookin at a direction
dir = search_block(arg1, comm_dirs, FALSE);
if (dir < 0 || dir > NUM_OF_DIRS)
{
sprintf(buf, "SYSERR: Invalid direction arg sent to rexitsecret (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
rroom = real_room(tr->number);
if (!(d = DIR(rroom, dir)))
{
sprintf(buf, "SYSERR: rexitsecret (#%d), direction DNE.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
FLAG_EXIT(d, EX_SECRET);
return RP_NORMAL;
}
// 6/14/98 - jtrhone
int do_rexitlead(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int dir, rroom, rvnum, trroom;
rmdirdata *d;
rmdata *tr;
half_chop(comm, arg1, arg2);
if (!*arg1 || !*arg2)
{
sprintf(buf, "SYSERR: Invalid arguments sent to rexitlead (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// they are lookin at a direction
dir = search_block(arg1, comm_dirs, FALSE);
if (dir < 0 || dir > NUM_OF_DIRS)
{
sprintf(buf, "SYSERR: Invalid direction arg sent to rexitlead (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
rroom = real_room(tr->number);
if (!(d = DIR(rroom, dir)))
{
sprintf(buf, "SYSERR: rexitlead (#%d), direction DNE.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (!is_number(arg2) || (rvnum = atoi(arg2)) <= 0)
{
sprintf(buf, "SYSERR: rexitlead (#%d), target room invalid.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if ((trroom = real_room(rvnum)) <= 0)
{
sprintf(buf, "SYSERR: rexitlead (#%d), target room invalid.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
d->to_room_virtual = rvnum;
d->to_room = trroom;
return RP_NORMAL;
}
// 6/11/98 - jtrhone
// toggle exit states
// oc - open close, lu - lock unlock, vs - vis secret
// rexittog n oc (toggles northern exit as open or closed)
// add support for possible remotes 6/13/98 -jtrhone
int do_rexittoggle(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int dir, rroom;
rmdirdata *d;
rmdata *tr;
half_chop(comm, arg1, arg2);
if (!*arg1 || !*arg2)
{
sprintf(buf, "SYSERR: Invalid arguments sent to rexittoggle (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// they are lookin at a direction
dir = search_block(arg1, comm_dirs, FALSE);
if (dir < 0 || dir > NUM_OF_DIRS)
{
sprintf(buf, "SYSERR: Invalid direction arg sent to rexittoggle (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
rroom = real_room(tr->number);
if (!(d = DIR(rroom, dir)))
{
sprintf(buf, "SYSERR: rexittoggle (#%d), direction DNE.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (!str_cmp(arg2, "oc"))
{
if (!EXIT_ISDOOR(d))
{
sprintf(buf, "SYSERR: rexittoggle (#%d), direction cannot be OC.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// WELL, we should check if locked / jammed, but nah
if (EXIT_CLOSED(d))
UNFLAG_EXIT(d, EX_CLOSED);
else
FLAG_EXIT(d, EX_CLOSED);
}
else
if (!str_cmp(arg2, "lu"))
{
if (!EXIT_ISDOOR(d))
{
sprintf(buf, "SYSERR: rexittoggle (#%d), direction cannot be LU.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
// WELL, we should check if locked / jammed, but nah
if (EXIT_LOCKED(d))
UNFLAG_EXIT(d, EX_LOCKED);
else
FLAG_EXIT(d, EX_LOCKED);
}
else
if (!str_cmp(arg2, "vs"))
{
if (EXIT_SECRET(d))
UNFLAG_EXIT(d, EX_SECRET);
else
FLAG_EXIT(d, EX_SECRET);
}
else
{
sprintf(buf, "SYSERR: rexittoggle (#%d), toggle must be oc, lu, or vs.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
return RP_NORMAL;
}
// teleport entire room or char to vnum
// rteleport <char | room> <vnum>
// 6/11/98 -jtrhone
// add support for possible remotes 6/13/98 -jtrhone
int do_rteleport(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char arg4[MAX_INPUT_LENGTH];
chdata *vict, *tmp_vict;
int room;
rmdata *tr;
half_chop(comm, arg1, arg2);
if (!*arg1 || !*arg2)
{
sprintf(buf, "SYSERR: Invalid arguments sent to rteleport (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
if (is_abbrev(arg1, "char"))
{
half_chop(arg2, arg3, arg4);
if (!*arg3 || !*arg4)
{
sprintf(buf, "SYSERR: Invalid arguments sent to rteleport (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if (!(vict = get_char_room(arg3, real_room(tr->number))))
return RP_NORMAL;
if (!is_number(arg4) || INVALID_ROOM((room = real_room(atoi(arg4)))))
{
sprintf(buf, "SYSERR: Invalid destination sent to rteleport (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
char_from_room(vict);
char_to_room(vict, room);
do_look_at_room(vict, 0, 0);
if (check_room_affects(vict, vict->in_room) == CHAR_DIED)
return RP_NORMAL;
if (check_death_trap(vict, NULL))
return RP_NORMAL;
}
else
if (is_abbrev(arg1, "room"))
{
if (!tr->people)
return RP_NORMAL;
if (!is_number(arg2) || INVALID_ROOM((room = real_room(atoi(arg2)))))
{
sprintf(buf, "SYSERR: Invalid destination sent to rteleport (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
for (vict = tr->people; vict; vict = tmp_vict)
{
tmp_vict = vict->next_in_room;
char_from_room(vict);
char_to_room(vict, room);
do_look_at_room(vict, 0, 0);
if (check_room_affects(vict, vict->in_room) == CHAR_DIED)
continue;
if (check_death_trap(vict, NULL))
continue;
}
return RP_NORMAL;
}
else
{
sprintf(buf, "SYSERR: Invalid arguments sent to rteleport (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
return RP_NORMAL;
}
// trans a mob of vnum in this zone to this room (not from this room)
// rtransmob 10123
// 6/13/98 -jtrhone
// add support for possible remotes 6/13/98 -jtrhone
int do_rtransmob(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
chdata *mob;
int vnum = 0, i;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1 || !is_number(arg1))
{
sprintf(buf, "SYSERR: Invalid arguments sent to rtransmob (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
vnum = atoi(arg1);
if (real_mobile(vnum) <= 0)
{
sprintf(buf, "SYSERR: Invalid mob vnum sent to rtransmob (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
for (i = 0; i < top_of_world; i++)
if (world[i].zone == tr->zone && &world[i] != tr && world[i].people)
for (mob = world[i].people; mob; mob=mob->next_in_room)
if (IS_NPC(mob) && GET_MOB_VNUM(mob) == vnum)
{
S2IMM("rtransmob: Found mob, transing.", r);
char_from_room(mob);
char_to_room(mob, real_room(tr->number));
return RP_NORMAL;
}
return RP_NORMAL;
}
// trans an obj of vnum in this zone to this room (not from this room)
// rtransobj 10123
// 6/13/98 -jtrhone
// add support for possible remotes 6/13/98 -jtrhone
int do_rtransobj(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
obdata *obj;
int vnum = 0, i;
rmdata *tr;
one_argument(comm, arg1);
if (!*arg1 || !is_number(arg1))
{
sprintf(buf, "SYSERR: Invalid arguments sent to rtransobj (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
vnum = atoi(arg1);
if (real_object(vnum) <= 0)
{
sprintf(buf, "SYSERR: Invalid obj vnum sent to rtransobj (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
tr = REMOTE(r) ? REMOTE(r) : r;
for (i = 0; i < top_of_world; i++)
if (world[i].zone == tr->zone && &world[i] != tr && world[i].contents)
for (obj = world[i].contents; obj; obj=obj->next_content)
if (GET_OBJ_VNUM(obj) == vnum)
{
S2IMM("rtransobj: Found obj, transing.", r);
obj_from_room(obj);
float_sink_object(obj, real_room(tr->number));
return RP_NORMAL;
}
return RP_NORMAL;
}
// set room's remote room (so this proc can do things in other rooms)
// rsetremote 3001
// 6/13/98 -jtrhone
int do_rsetremote(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
rmdata *rm;
int vnum = 0, rroom;
one_argument(comm, arg1);
if (!*arg1 || !is_number(arg1))
{
sprintf(buf, "SYSERR: Invalid argument sent to rsetremote (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RREMOTE;
}
vnum = atoi(arg1);
if ((rroom = real_room(vnum)) <= 0)
{
sprintf(buf, "SYSERR: Invalid room vnum sent to rsetremote (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RREMOTE;
}
rm = &world[rroom];
if (rm == r)
{
sprintf(buf, "SYSERR: Room sent to rsetremote matches source room (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RREMOTE;
}
REMOTE(r) = rm;
sprintf(buf, "rsetremote: remote set to %d.", vnum);
S2IMM(buf, r);
return RP_RREMOTE;
}
// unset room's remote room
// runsetremote
// 6/13/98 -jtrhone
int do_runsetremote(rmdata *r, char *comm)
{
REMOTE(r) = NULL;
S2IMM("runsetremote: remote unset.", r);
return RP_RREMOTE;
}
// RTARGET UTILITY FUNCTIONS (6/14/98 -jtrhone)
// count number of objects in the room
int r_num_obj_room(rmdata *r)
{
int i;
obdata *obj = r->contents;
for (i=0; obj; obj=obj->next_content, i++)
;
return i;
}
// return ptr to the numTH item in room
obdata *r_get_obj_room(rmdata *r, int num)
{
int i;
obdata *obj = r->contents;
for (i = 0; i < num && obj; obj=obj->next_content, i++)
if (i == num) break;
return obj;
}
// return ptr to the numTH object in zone
obdata* r_get_obj_zone(rmdata *r, int num)
{
int i;
obdata *obj = object_list;
for (i=0; obj && i < num; obj=obj->next)
{
if (INVALID_ROOM(obj->in_room)) continue;
if (world[obj->in_room].zone == r->zone)
i++;
if (i == num) return obj;
}
return NULL;
}
// return how many objects are in ROOMS in zone
int r_num_obj_zone(rmdata *r)
{
int i;
obdata *obj = object_list;
for (i=0; obj; obj=obj->next)
{
if (INVALID_ROOM(obj->in_room)) continue;
if (world[obj->in_room].zone == r->zone)
i++;
}
return i;
}
// target counters for ROOMS
int r_num_pc_room(rmdata *r)
{
int i;
chdata *vict = r->people;
for (i=0; vict; vict = vict->next_in_room)
if (IS_PC(vict)) i++;
return i;
}
int r_num_npc_room(rmdata *r)
{
int i;
chdata *vict = r->people;
for (i=0; vict; vict = vict->next_in_room)
if (IS_NPC(vict)) i++;
return i;
}
int r_num_any_room(rmdata *r)
{
int i;
chdata *vict = r->people;
for (i=0; vict; vict = vict->next_in_room)
i++;
return i;
}
// target counters for ZONE
int r_num_any_zone(rmdata *r)
{
int i;
chdata *vict;
for (i=0, vict = character_list; vict; vict = vict->next)
if (world[vict->in_room].zone == r->zone)
i++;
return i;
}
int r_num_npc_zone(rmdata *r)
{
int i;
chdata *vict;
for (i=0, vict = character_list; vict; vict = vict->next)
if (IS_NPC(vict) && world[vict->in_room].zone == r->zone)
i++;
return i;
}
int r_num_pc_zone(rmdata *r)
{
int i;
chdata *vict;
for (i=0, vict = character_list; vict; vict = vict->next)
if (IS_PC(vict) && world[vict->in_room].zone == r->zone)
i++;
return i;
}
// targetting functions for ROOM
chdata *r_get_any_room(rmdata *r, int num)
{
int i;
chdata *vict = r->people;
for (i = 0; i < num && vict; vict = vict->next_in_room)
if (++i == num) break;
return vict;
}
chdata *r_get_pc_room(rmdata *r, int num)
{
int i;
chdata *vict = r->people;
for (i = 0; i < num && vict; vict = vict->next_in_room)
{
if (IS_PC(vict)) i++;
if (i == num) break;
}
return vict;
}
chdata *r_get_npc_room(rmdata *r, int num)
{
int i;
chdata *vict = r->people;
for (i = 0; i < num && vict; vict = vict->next_in_room)
{
if (IS_NPC(vict)) i++;
if (i == num) break;
}
return vict;
}
// targetting functions for ZONE
chdata *r_get_any_zone(rmdata *r, int num)
{
int i;
chdata *vict;
for (i = 0, vict = character_list; vict && i < num; vict = vict->next)
{
if (INVALID_ROOM(vict->in_room)) continue;
if (world[vict->in_room].zone == r->zone)
i++;
if (i == num) return vict;
}
return NULL;
}
chdata *r_get_pc_zone(rmdata *r, int num)
{
int i;
chdata *vict;
for (i = 0, vict = character_list; vict && i < num; vict = vict->next)
{
if (INVALID_ROOM(vict->in_room)) continue;
if (world[vict->in_room].zone == r->zone && IS_PC(vict))
i++;
if (i == num) return vict;
}
return NULL;
}
chdata *r_get_npc_zone(rmdata *r, int num)
{
int i;
chdata *vict;
for (i = 0, vict = character_list; vict && i < num; vict = vict->next)
{
if (INVALID_ROOM(vict->in_room)) continue;
if (world[vict->in_room].zone == r->zone && IS_NPC(vict))
i++;
if (i == num) return vict;
}
return NULL;
}
/* set a room's target character/object (in room) */
int do_rtarget(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int num, pick;
chdata *vict = NULL;
obdata *obj = NULL;
BOOL pc, npc;
pc = npc = FALSE;
half_chop(comm, arg1, arg2);
if (!str_cmp(arg1, "char"))
{
if (RTARGET_CHAR(r))
free_log(RTARGET_CHAR(r), "do_mtarget");
RTARGET_CHAR(r) = NULL;
half_chop(arg2, arg1, arg2);
if (!*arg1)
{
sprintf(buf, "SYSERR: Undefined char type (pc | npc | any) to rtarget (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
else
if (!str_cmp(arg1, "pc")) pc = TRUE;
else
if (!str_cmp(arg1, "npc")) npc = TRUE;
else
if (!str_cmp(arg1, "any"))
{
npc = pc = TRUE;
}
else
{
sprintf(buf, "SYSERR: Undefined char type (pc | npc | any) to rtarget (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
half_chop(arg2, arg1, arg2);
if (!*arg1 || !is_number(arg1))
{
sprintf(buf, "SYSERR: Undefined character number to rtarget (#%d).",r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if ((num = atoi(arg1))) /* if a number besides 0 is wanted */
{
if ((!pc && (vict = r_get_npc_room(r, num))) ||
(!npc && (vict = r_get_pc_room(r, num))) ||
(pc && npc && (vict = r_get_any_room(r, num))) )
{
RTARGET_CHAR(r) = str_dup(fname(vict->player.name));
sprintf(buf, "SYSUPD: Room #%d setting char target to %s", r->number, fname(vict->player.name));
mudlog(buf, BUG, LEV_IMM, FALSE);
}
}
else
if (!num) /* this means pick a random character in the room */
{
pick = 0;
if (!pc && r_num_npc_room(r))
pick = number(1, r_num_npc_room(r));
else
if (!npc && r_num_pc_room(r))
pick = number(1, r_num_pc_room(r));
else
if (pc && npc && r_num_any_room(r))
pick = number(1, r_num_any_room(r));
if (pick)
{
if ((!pc && (vict = r_get_npc_room(r, pick))) ||
(!npc && (vict = r_get_pc_room(r, pick))) ||
(pc && npc && (vict = r_get_any_room(r, pick))) )
{
RTARGET_CHAR(r) = str_dup(fname(vict->player.name));
sprintf(buf, "SYSUPD: Rproc #%d setting char target to %s", r->number, fname(vict->player.name));
mudlog(buf, BUG, LEV_IMM, FALSE);
}
}
}
}
else
if (!str_cmp(arg1, "obj"))
{
if (RTARGET_OBJ(r))
free_log(RTARGET_OBJ(r), "do_rtarget 2");
RTARGET_OBJ(r) = NULL;
half_chop(arg2, arg1, arg2);
if (!*arg1 || !is_number(arg1))
{
sprintf(buf, "SYSERR: Undefined object number to rtarget (#%d).",r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if ((num = atoi(arg1))) /* if a number besides 0 is wanted */
{
num--;
if ((obj = r_get_obj_room(r, num)))
{
sprintf(buf, "SYSUPD: Rproc #%d setting obj target to %s", r->number, fname(obj->name));
mudlog(buf, BUG, LEV_IMM, FALSE);
RTARGET_OBJ(r) = str_dup(fname(obj->name));
}
}
else
if (!num && r_num_obj_room(r) && (obj = r_get_obj_room(r, number(0, (r_num_obj_room(r)-1)))))
{
sprintf(buf, "SYSUPD: Rproc #%d setting obj target to %s", r->number, fname(obj->name));
mudlog(buf, BUG, LEV_IMM, FALSE);
RTARGET_OBJ(r) = str_dup(fname(obj->name));
}
}
else
{
sprintf(buf, "SYSERR: Undefined arg (%s) to rtarget (#%d).", arg1, r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
return RP_RTARGET;
}
/* set a rooms's target character/object (in zone) */
int do_rtarget_zone(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int num, pick;
chdata *vict = NULL;
obdata *obj = NULL;
BOOL pc, npc;
pc = npc = FALSE;
half_chop(comm, arg1, arg2);
if (!str_cmp(arg1, "char"))
{
if (RTARGET_CHAR(r))
free_log(RTARGET_CHAR(r), "do_rtarget_zone");
RTARGET_CHAR(r) = NULL;
half_chop(arg2, arg1, arg2);
if (!*arg1)
{
sprintf(buf, "SYSERR: Undefined char type (pc | npc | any) to rtargetzone (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
else
if (!str_cmp(arg1, "pc")) pc = TRUE;
else
if (!str_cmp(arg1, "npc")) npc = TRUE;
else
if (!str_cmp(arg1, "any"))
{
npc = pc = TRUE;
}
else
{
sprintf(buf, "SYSERR: Undefined char type (pc | npc | any) to mtargetzone (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
half_chop(arg2, arg1, arg2);
if (!*arg1 || !is_number(arg1))
{
sprintf(buf, "SYSERR: Undefined character number to rtargetzone (#%d).", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if ((num = atoi(arg1))) /* if a number besides 0 is wanted */
{
if ((!pc && (vict = r_get_npc_zone(r, num))) || (!npc && (vict = r_get_pc_zone(r, num))) ||
(pc && npc && (vict = r_get_any_zone(r, num))) )
{
if (MOB2_FLAGGED(vict, MOB2_NO_MTARGET))
return RP_RTARGET;
RTARGET_CHAR(r) = str_dup(fname(vict->player.name));
sprintf(buf, "SYSUPD: Rproc #%d setting char target to %s", r->number, fname(vict->player.name));
mudlog(buf, BUG, LEV_IMM, FALSE);
}
}
else
if (!num) /* this means pick a random character in the zone */
{
pick = 0;
if (!pc && r_num_npc_zone(r))
pick = number(1, r_num_npc_zone(r));
else
if (!npc && r_num_pc_zone(r))
pick = number(1, r_num_pc_zone(r));
else
if (pc && npc && r_num_any_zone(r))
pick = number(1, r_num_any_zone(r));
if (pick)
{
if ((!pc && (vict = r_get_npc_zone(r, pick))) || (!npc && (vict = r_get_pc_zone(r, pick))) ||
(pc && npc && (vict = r_get_any_zone(r, pick))) )
{
if (MOB2_FLAGGED(vict, MOB2_NO_MTARGET))
return RP_RTARGET;
RTARGET_CHAR(r) = str_dup(fname(vict->player.name));
sprintf(buf, "SYSUPD: Rproc #%d setting char target to %s", r->number, fname(vict->player.name));
mudlog(buf, BUG, LEV_IMM, FALSE);
}
}
}
}
else
if (!str_cmp(arg1, "obj"))
{
if (RTARGET_OBJ(r))
free_log(RTARGET_OBJ(r), "do_rtarget_zone 2");
RTARGET_OBJ(r) = NULL;
half_chop(arg2, arg1, arg2);
if (!*arg1 || !is_number(arg1))
{
sprintf(buf, "SYSERR: Undefined object number to rtargetzone (#%d).",r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
if ((num = atoi(arg1))) /* if a number besides 0 is wanted */
{
num--;
if ((obj = r_get_obj_zone(r, num)))
{
sprintf(buf, "SYSUPD: #%d setting obj target to %s", r->number, fname(obj->name));
mudlog(buf, BUG, LEV_IMM, FALSE);
RTARGET_OBJ(r) = str_dup(fname(obj->name));
}
}
else
if (!num && r_num_obj_zone(r) && (obj = r_get_obj_zone(r, number(0, (r_num_obj_zone(r)-1)))))
{
sprintf(buf, "SYSUPD: #%d setting obj target to %s", r->number, fname(obj->name));
mudlog(buf, BUG, LEV_IMM, FALSE);
RTARGET_OBJ(r) = str_dup(fname(obj->name));
}
}
else
{
sprintf(buf, "SYSERR: Undefined arg (%s) to rtargetzone (#%d).", arg1, r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
return RP_RTARGET;
}
/* manually set the room's target strings */
int do_rtarget_set(rmdata *r, char *comm)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
half_chop(comm, arg1, arg2);
if (is_abbrev(arg1, "char") && *arg2)
{
if (RTARGET_CHAR(r))
free_log(RTARGET_CHAR(r), "do_rtargetset 1");
RTARGET_CHAR(r) = str_dup(arg2);
}
else
if (is_abbrev(arg1, "obj") && *arg2)
{
if (RTARGET_OBJ(r))
free_log(RTARGET_OBJ(r), "do_mtargetset 2");
RTARGET_OBJ(r) = str_dup(arg2);
}
else
{
sprintf(buf, "SYSERR: Rproc (#%d) invalid rtargetset command.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_NORMAL;
}
return RP_RTARGET;
}
// skip a command goto next or jump to beginning if none left
// must add ability to skip rcommand blocks!, if the command structure
// uses them, such as rrandom... rrandom uses a block structure
// if we are pointing at a block, skip it! (rifs mostly)
void goto_next_rcom(rmdata *r)
{
char arg1[MAX_INPUT_LENGTH];
char *tmp = RPROC_CUR(r);
one_argument(tmp, arg1);
// jump to the top...
if (!*tmp)
{
RPROC_CUR(r) = RPROC_BEG(r);
return;
}
// lets check the command we're skippin to see if it is a block command
if (*arg1 == '{')
{
tmp = skip_block(tmp);
if (!*tmp)
tmp = RPROC_BEG(r);
RPROC_CUR(r) = tmp;
return;
}
else
if (is_abbrev(arg1, "rrandom") || is_abbrev(arg1, "rtrigadd"))
{
tmp = scan_past_eol(tmp);
tmp = skip_block(tmp);
if (!*tmp)
tmp = RPROC_BEG(r);
RPROC_CUR(r) = tmp;
return;
}
// else do the normal one line skip
tmp = scan_past_eol(tmp);
if (!*tmp)
tmp = RPROC_BEG(r);
RPROC_CUR(r) = tmp;
}
// see do_mif in mobproc.c, very similar here
// added, modified 6/14/98 -jtrhone
int do_rif(rmdata *r, char *argument)
{
static char rif_comp[MAX_INPUT_LENGTH];
static char comp_args[MAX_INPUT_LENGTH];
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int vroom, rroom;
chdata *ch;
obdata *obj;
BOOL found;
int i, cmd;
int get_race_by_name(char *arg); // races.c, 8/22/98 -jtrhone
half_chop(argument, rif_comp, comp_args);
if ((cmd = search_block(rif_comp, rif_BOOLs, FALSE)) < 0)
{
sprintf(buf, "SYSUPD: Undefined rproc RIF argument. #%d",r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
sprintf(buf, "SYSUPD: Undefined RIF arg: %s", rif_comp);
mudlog(buf, BUG, LEV_IMM, FALSE);
goto_next_rcom(r);
}
// add a little flexibility to these... 1/22/98 -jtrhone
while (*RPROC_CUR(r) && *RPROC_CUR(r) != '{')
RPROC_CUR(r)++;
if (*RPROC_CUR(r) != '{')
{
sprintf(buf, "SYSUPD: RIF with no following block. #%d",r->number);
mudlog(buf, BUG, LEV_IMM, FALSE);
do_rend(r, "");
}
switch (cmd) {
case 0: //tarcharset
if (!RTARGET_CHAR(r))
goto_next_rcom(r);
break;
case 1: //!tarcharset
if (RTARGET_CHAR(r))
goto_next_rcom(r);
break;
case 2: //tarobjset
if (!RTARGET_OBJ(r))
goto_next_rcom(r);
break;
case 3: //!tarobjset
if (RTARGET_OBJ(r))
goto_next_rcom(r);
break;
case 4: //tarcharroom
if (!RTARGET_CHAR(r) || !get_char_room(RTARGET_CHAR(r), real_room(r->number)))
goto_next_rcom(r);
break;
case 5: //!tarcharroom
if (RTARGET_CHAR(r) && get_char_room(RTARGET_CHAR(r), real_room(r->number)))
goto_next_rcom(r);
break;
case 6: //tarobjroom
if (!RTARGET_OBJ(r) || !get_obj_in_list(RTARGET_OBJ(r), r->contents))
goto_next_rcom(r);
break;
case 7: //!tarobjroom
if (RTARGET_OBJ(r) && get_obj_in_list(RTARGET_OBJ(r), r->contents))
goto_next_rcom(r);
break;
case 8: //tarcharzone
if (!RTARGET_CHAR(r) || !get_char_zone(r->zone, RTARGET_CHAR(r)))
goto_next_rcom(r);
break;
case 9: //!tarcharzone
if (RTARGET_CHAR(r) && get_char_zone(r->zone, RTARGET_CHAR(r)))
goto_next_rcom(r);
break;
case 10: //tarobjzone
if (!RTARGET_OBJ(r) || !get_object_zone(r->zone, RTARGET_OBJ(r)))
goto_next_rcom(r);
break;
case 11: //!tarobjzone
if (RTARGET_OBJ(r) && get_object_zone(r->zone, RTARGET_OBJ(r)))
goto_next_rcom(r);
break;
case 12: //tarcharpc
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
break;
case 13: //!tarcharpc
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || IS_PC(ch))
goto_next_rcom(r);
break;
case 14: //tarcharcompquest
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1) || (!(vroom = atoi(arg1))) || !VALID_QUEST(vroom))
{
sprintf(buf, "SYSERR: rproc #%d invalid quest# check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt pc, or hasnt completed quest, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (!COMPLETED_QUEST(ch, vroom))
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 15: //!tarcharcompquest
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1) || (!(vroom = atoi(arg1))) || !VALID_QUEST(vroom))
{
sprintf(buf, "SYSERR: rproc #%d invalid quest# check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or has completed quest, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (COMPLETED_QUEST(ch, vroom))
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 16: //tarcharlevel
ch = NULL;
if (RTARGET_CHAR(r))
{
if (!(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))))
if (!(ch = get_char_zone(r->zone, RTARGET_CHAR(r))))
if (!(ch = get_char(RTARGET_CHAR(r))))
{
goto_next_rcom(r);
return RP_RIF;
}
}
else
{
goto_next_rcom(r);
return RP_RIF;
}
half_chop(comp_args, arg1, arg2);
if (!*arg1 || !*arg2)
{
sprintf(buf, "SYSERR: rproc #%d unknown tarcharlevel args.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
if (!is_number(arg2) || (i = atoi(arg2)) > LEV_IMPL || i <= 0)
{
sprintf(buf, "SYSERR: rproc #%d tarcharlevel invalid level arg.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
found = FALSE;
switch (*arg1) {
case '=': // is equal to
found = (GET_LEVEL(ch) == i);
break;
case '!': // is != to
found = (GET_LEVEL(ch) != i);
break;
case '<': // is less than equal to, or is less than
if (*(arg1+1) == '=')
found = (GET_LEVEL(ch) <= i);
else
found = (GET_LEVEL(ch) < i);
break;
case '>': // is greater than equal to, or is greater than
if (*(arg1+1) == '=')
found = (GET_LEVEL(ch) > i);
else
found = (GET_LEVEL(ch) >= i);
break;
default:
sprintf(buf, "SYSERR: Unknown rproc comparison, #%d.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
if (!found)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 17: //npcinroom
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1) || (!(vroom = atoi(arg1))) || ((rroom = real_mobile(vroom)) <= 0))
{
sprintf(buf, "SYSERR: rproc #%d invalid npcinroom arg.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
for (found = FALSE, ch = r->people; ch && !found; ch = ch->next_in_room)
if (IS_NPC(ch) && GET_MOB_VNUM(ch) == vroom)
found = TRUE;
if (!found)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 18: //!npcinroom
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1) || (!(vroom = atoi(arg1))) || ((rroom = real_mobile(vroom)) <= 0))
{
sprintf(buf, "SYSERR: rproc #%d invalid npcinroom arg.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
for (found = FALSE, ch = r->people; ch && !found; ch = ch->next_in_room)
if (IS_NPC(ch) && GET_MOB_VNUM(ch) == vroom)
found = TRUE;
if (found)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 19: //objinroom
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1) || (!(vroom = atoi(arg1))) || ((rroom = real_object(vroom)) <= 0))
{
sprintf(buf, "SYSERR: rproc #%d invalid objinroom arg.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
for (found = FALSE, obj = r->contents; obj && !found; obj = obj->next_content)
if (GET_OBJ_VNUM(obj) == vroom)
found = TRUE;
if (!found)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 20: //!objinroom
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1) || (!(vroom = atoi(arg1))) || ((rroom = real_object(vroom)) <= 0))
{
sprintf(buf, "SYSERR: rproc #%d invalid objinroom arg.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
for (found = FALSE, obj = r->contents; obj && !found; obj = obj->next_content)
if (GET_OBJ_VNUM(obj) == vroom)
found = TRUE;
if (found)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 21: //transpresent
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1))
{
sprintf(buf, "SYSERR: rproc #%d invalid trans arg (%s).", r->number, arg1);
mudlog(buf, BRF, LEV_IMM, FALSE);
goto_next_rcom(r);
return RP_RIF;
}
if (r->trans_present != atoi(arg1))
goto_next_rcom(r);
break;
case 22: //!transpresent
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1))
{
sprintf(buf, "SYSERR: rproc #%d invalid trans arg (%s).", r->number, arg1);
mudlog(buf, BRF, LEV_IMM, FALSE);
goto_next_rcom(r);
return RP_RIF;
}
if (r->trans_present == atoi(arg1))
goto_next_rcom(r);
break;
case 23: //tarcharonquest
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1) || (!(vroom = atoi(arg1))) || !VALID_QUEST(vroom))
{
sprintf(buf, "SYSERR: rproc #%d invalid quest# check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or isnt doing quest, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (ONQUEST(ch) != vroom)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 24: //!tarcharonquest
half_chop(comp_args, arg1, arg2);
if (!is_number(arg1) || (!(vroom = atoi(arg1))) || !VALID_QUEST(vroom))
{
sprintf(buf, "SYSERR: rproc #%d invalid quest# check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or doing quest, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (ONQUEST(ch) == vroom)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 25: //tarcharrace <>
half_chop(comp_args, arg1, arg2);
if (!*arg1 || (vroom = get_race_by_name(arg1)) <= 0)
{
sprintf(buf, "SYSERR: rproc #%d invalid race check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or not race, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (GET_RACE(ch) != vroom)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 26: //!tarcharrace <>
half_chop(comp_args, arg1, arg2);
if (!*arg1 || (vroom = get_race_by_name(arg1)) <= 0)
{
sprintf(buf, "SYSERR: rproc #%d invalid race check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or not race, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (GET_RACE(ch) == vroom)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 27: //tarcharclass <>
half_chop(comp_args, arg1, arg2);
if (!*arg1 || (vroom = get_class_num(arg1)) <= 0)
{
sprintf(buf, "SYSERR: rproc #%d invalid class check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or not class, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (GET_CLASS(ch) != vroom)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 28: //!tarcharclass <>
half_chop(comp_args, arg1, arg2);
if (!*arg1 || (vroom = get_class_num(arg1)) <= 0)
{
sprintf(buf, "SYSERR: rproc #%d invalid class check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or not class, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (GET_CLASS(ch) == vroom)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 29: //tarchargender <>
half_chop(comp_args, arg1, arg2);
if (!*arg1 || (vroom = search_block(arg1, genders, FALSE)) <= 0)
{
sprintf(buf, "SYSERR: rproc #%d invalid gender check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or not class, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (GET_SEX(ch) != vroom)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
case 30: //!tarchargender <>
half_chop(comp_args, arg1, arg2);
if (!*arg1 || (vroom = search_block(arg1, genders, FALSE)) <= 0)
{
sprintf(buf, "SYSERR: rproc #%d invalid gender check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return RP_RIF;
}
// if is no target, or isnt visible, or isnt pc, or not class, skip block
if (!RTARGET_CHAR(r) || !(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))) || !IS_PC(ch))
goto_next_rcom(r);
else
if (GET_SEX(ch) == vroom)
goto_next_rcom(r);
else
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
default:
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
break;
}
return RP_RIF;
}
//////////////////////////////////////
// lets do some bounds checking just to make sure -jtrhone
BOOL check_rproc_bounds(rmdata *r)
{
if (RPROC_CUR(r) < RPROC_BEG(r))
{
sprintf(buf, "SYSERR: rproc on room #%d %%B%%1FAILED%%0 lower bounds check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return FALSE;
}
if (RPROC_CUR(r) > (RPROC_BEG(r) + strlen(RPROC_BEG(r))))
{
sprintf(buf, "SYSERR: rproc on room #%d %%B%%1FAILED%%0 upper bounds check.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return FALSE;
}
return TRUE;
}
// if ch, use ch for subs, else use TARGET_CHAR
// if ob, use ob for subs, else use TARGET_OBJ
BOOL do_rproc_subs(rmdata *r, char *comm, chdata *ch, obdata *ob)
{
char newcomm[MAX_INPUT_LENGTH];
int i, j;
if (!strchr(comm, '+'))
return FALSE;
// if ch wasnt passed, try to get a chdata ptr from target char
if (!ch)
if (RTARGET_CHAR(r))
if (!(ch = get_char_room(RTARGET_CHAR(r), real_room(r->number))))
if (!(ch = get_char(RTARGET_CHAR(r))))
;
for (i=0, j=0; comm[i]; i++)
{
newcomm[j] = '\0';
if (comm[i] != '+')
{
newcomm[j] = comm[i];
j++;
continue;
}
else
if (comm[i+1])
{
i++;
switch (comm[i])
{
case '+': /* double (++) means sub in one + */
newcomm[j] = comm[i];
j++; i++;
break;
case 'C': /* sub SHORT (NPC alias, PC normal) name of char target */
if (ch)
{
if (IS_PC(ch))
strcat(newcomm + j, GET_NAME(ch));
else
strcat(newcomm + j, fname(ch->player.name));
j = strlen(newcomm);
}
else
if (RTARGET_CHAR(r))
{
strcat(newcomm + j, RTARGET_CHAR(r));
j = strlen(newcomm);
}
break;
case 'N': case 'n': // normal name for pc, short desc for npc
if (ch)
{
strcat(newcomm + j, GET_NAME(ch));
j = strlen(newcomm);
}
else
if (RTARGET_CHAR(r))
{
strcat(newcomm + j, RTARGET_CHAR(r));
j = strlen(newcomm);
}
/* if no sub there, ok, its as if we processed */
break;
case 'R': case 'r':
if (ch)
{
strcat(newcomm + j, rcarray[GET_RACE(ch)].race_name);
j = strlen(newcomm);
}
break;
case 'L': case 'l':
if (ch)
{
strcat(newcomm + j, gskill_names[SPEAKING(ch)]);
j = strlen(newcomm);
}
break;
case 'H': case 'h':
if (ch && htowns[GET_HTOWN(ch)].name)
{
strcat(newcomm + j, htowns[GET_HTOWN(ch)].name);
j = strlen(newcomm);
}
break;
case 'c': /* class, if incog sub race instead */
if (ch)
{
if (PRF_FLAGGED(ch, PRF_INCOGNITO))
strcat(newcomm + j, rcarray[GET_RACE(ch)].race_name);
else
strcat(newcomm + j, clarray[(int)GET_CLASS(ch)].class_name);
j = strlen(newcomm);
}
break;
case 'O': case 'o': /* sub name of obj target */
if (ob)
{
strcat(newcomm + j, ob->shdesc);
j = strlen(newcomm);
}
else
if (RTARGET_OBJ(r))
{
strcat(newcomm + j, RTARGET_OBJ(r));
j = strlen(newcomm);
}
/* if no sub there, ok, its as if we processed */
break;
default:
sprintf(buf, "SYSERR: Undefined +(%c) to rproc #%d.",comm[i+1], r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return FALSE;
break;
}
}
else
{
sprintf(buf, "SYSERR: Undefined +sub to rproc #%d.", r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return FALSE;
}
}
newcomm[j] = '\0';
strncpy(comm, newcomm, MAX_INPUT_LENGTH - 1);
return TRUE;
}
// execute and return true if comm is a rproc command
// if reaction, do not execute some mtrig commands or block commands
int rproc_interpreter(rmdata *r, char *comm, chdata *ch, obdata *ob, BOOL reaction)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int i;
if (!ROOM_FLAGGED(real_room(r->number), RPROC))
return RP_NORMAL;
half_chop(comm, arg1, arg2);
for (i = 0; *rproc_calls[i].arg; i++)
if (is_abbrev(arg1, rproc_calls[i].arg))
{
if (reaction)
if (is_abbrev(arg1, "rtridadd") || is_abbrev(arg1, "rtrigdel") || is_abbrev(arg1, "rtrigwax") ||
is_abbrev(arg1, "rrandom"))
{
sprintf(buf, "SYSERR: %s found in rtrig reaction/random, not parsed (room #%d).", arg1, r->number);
mudlog(buf, BRF, LEV_IMM, TRUE);
continue;
}
do_rproc_subs(r, arg2, ch, ob);
// ok, call appropriate function with this command
return ((*rproc_calls[i].rproc_fn) (r, arg2));
}
return RP_NORMAL;
}
// Main rproc interface begins here
// this is called from roomact.c in room_activity()
void do_room_rproc(rmdata *r)
{
int i;
int current_command, command_count;
char *tmp;
char comm[MAX_INPUT_LENGTH+2];
if (!RPROC_BEG(r) || !*RPROC_BEG(r))
{
sprintf(buf, "SYSERR: room #%d rproc missing instruction set.",r->number);
mudlog(buf, BRF, LEV_IMM, FALSE);
return;
}
/* check wait states, to see if loop or waiting or finished */
if (RPROC_WAIT(r) <= -1) return; /* finished */
else
if (RPROC_WAIT(r) > 0)
{
RPROC_WAIT(r)--;
return; /* waiting for now, see ya */
}
else
if (RTRIGS(r) && RTRIG_WAITING(r)) // waiting for trigger
return;
current_command = RP_RIF;
command_count = 1;
while ((current_command == RP_RIF || current_command == RP_RTARGET ||
current_command == RP_RREMOTE || current_command == RP_RTAG ||
current_command == RP_RTRIG) && command_count < 5)
{
if (!check_rproc_bounds(r))
return;
// skip leading white space, allow for nifty look rproc code
skip_spaces(&RPROC_CUR(r));
// if we're pointing at close brackets, just skip em
while ( *RPROC_CUR(r) && *RPROC_CUR(r) == '}' )
RPROC_CUR(r) = scan_past_eol(RPROC_CUR(r));
// if null, reset to beginning
if (!RPROC_CUR(r) || !*RPROC_CUR(r))
RPROC_CUR(r) = RPROC_BEG(r);
// get length of next command
for (i=0, tmp = RPROC_CUR(r); *tmp && !ISNEWL(*tmp) && (i < MAX_INPUT_LENGTH); tmp++, i++)
;
/* copy this command line into comm */
strncpy(comm, RPROC_CUR(r), i);
comm[i] = '\0';
while (*tmp && ISNEWL(*tmp))
tmp++;
// reset back to beginning to mproc command list
if (!*tmp)
tmp = RPROC_BEG(r);
RPROC_CUR(r) = tmp;
// show the room what they typing
S2IMM(comm,r);
// send it onto rproc processing
current_command = rproc_interpreter(r, comm, NULL, NULL, FALSE);
// prevent infinity -roa
command_count++;
}
}