/*
* command.c
*
* Command a living to do stuff
*
* (C) Frank Schmidt, Jesus@NorseMUD
*
*/
/* current command for this_player1() genuine (typed in) or not? */
static int genuine_command() {
return GLOBAL->query_genuine_command();
}
#ifndef MUDOS_COMMAND
/* prototype for the mudlib "do_command"-function */
static void __DO_COMMAND_DEF(string str);
/* command a living to do a command */
static varargs int command(string str, object ob) {
if (!ob) {
/* command this object */
int exec, genuine;
object oldply;
/* store exec-cost left before command takes place */
exec = status()[ST_TICKS];
/* store if previous command was a genuine command, and
* nullify genuine command if this isn't one
*/
if (genuine=genuine_command()) {
if (previous_function() != "__command" || previous_program(1) != USER)
GLOBAL->set_genuine_command(0);
}
/* set this_object() as this_player() and save old */
if ((oldply=this_player()) != this_object())
GLOBAL->set_this_player(this_object());
if (str) {
/* command us! */
#if INFORM_DRIVER >= 20
DRIVER->send("INPUT (DGD): "+str);
#endif
if (genuine) {
catch(__DO_COMMAND_DEF(str));
}
}
/* reset old this_player() */
if ((oldply) != this_object())
GLOBAL->set_this_player(oldply);
/* reset genuinity */
if (genuine)
GLOBAL->set_genuine_command(genuine);
/* return execution cycles used */
return exec - status()[ST_TICKS];
}
else
/* command another sucker (object) */
return call_other(ob, "__command", str);
/* something went VERY wrong */
return 0;
}
#else /* MUDOS_COMMAND */
/* command a living to do a command */
static varargs int command(string str, object ob) {
if (!ob) {
/*if (living(this_object()))*/ {
int exec, genuine;
string *words;
object oldply;
/* store exec-cost left before command takes place */
exec = status()[ST_TICKS];
/* store if previous command was a genuine command, and
* nullify genuine command if this isn't one
*/
if (genuine=genuine_command()) {
if (previous_function() != "__command" || previous_program(1) != USER)
GLOBAL->set_genuine_command(0);
}
/* set this_object() as this_player() and save old */
if ((oldply=this_player()) != this_object())
GLOBAL->set_this_player(this_object());
/* explode into words */
words = explode(str, " ");
#if 0
/* get rid of nasty spaces in front of each word */
words -= ({ "" });
str = implode(words, " ");
#endif
if (str) {
/* we got a command to process */
string oldverb, verb, rest;
#ifdef MUDOS_NOTIFY_FAIL
string oldnf;
#endif
#ifdef MUDOS_NOTIFY_FAIL
/* set default notify fail message */
oldnf=query_notify_fail();
notify_fail(DEFAULT_NOTIFY_FAIL);
#endif
/* set current verb as word #1 */
oldverb = query_verb();
if (::sizeof(words))
GLOBAL->set_verb(verb=words[0]);
else
GLOBAL->set_verb(verb="");
#if INFORM_DRIVER >= 20
DRIVER->send("INPUT: "+str);
DRIVER->send("VERB: "+verb);
DRIVER->send("REST: "+rest);
#endif
{
int i;
object env;
mixed *obs;
/* scan through inventory, inventory of environment and environment */
obs = ({ });
if (env=environment()) {
obs += ({ env });
obs += all_inventory(env) - ({ this_object() });
}
obs += all_inventory();
obs += ({ this_object() });
/* do the actual search for our verb */
for (i=::sizeof(obs); --i >= 0; ) {
function *triggs;
int e;
if (arrayp(triggs=obs[i]->query_triggers(verb))) {
for (e=::sizeof(triggs); --e >= 0; )
/* call the functions for the trigger with rest-string */
mixed ret;
catch(ret=call_fp(triggs[e], rest));
if (ret)
/* found a matching trigger! */
break;
}
}
#ifdef MUDOS_NOTIFY_FAIL
/* We didn't type correctly? */
if (i < 0)
/* show notify fail message */
__CATCH_TELL_DEF(query_notify_fail());
#endif
}
/* reset old verb */
GLOBAL->set_verb(oldverb);
#ifdef MUDOS_NOTIFY_FAIL
/* reset notify fail msg */
notify_fail(oldnf);
#endif
}
/* reset old this_player() */
if ((oldply) != this_object())
GLOBAL->set_this_player(oldply);
/* reset genuinity */
if (genuine)
GLOBAL->set_genuine_command(genuine);
/* return execution cycles used */
return exec - status()[ST_TICKS];
}
}
else
/* command another sucker */
return call_other(ob, "__command", str);
/* return failure */
return 0;
}
/* return an array of ({ verb, flag, ob, func }) elements */
static mixed **commands() {
int i;
object env;
mixed *obs, **cmds;
/* scan through inventory, inventory of environment and environment */
cmds = ({ });
obs = ({ });
if (env=environment()) {
obs += ({ env });
obs += all_inventory(env) - ({ this_object() });
}
obs += all_inventory();
/* scan through all possible triggers */
for (i=::sizeof(obs); --i >= 0; ) {
mapping triggs;
string *verbs;
int e;
for (e=::sizeof(verbs=map_indices(triggs=obs[i]->query_triggers())); --e >= 0; ) {
int k;
function *funcs;
for (k=::sizeof(funcs=triggs[verbs[e]]); --k >= 0; ) {
/* add a command to the list over local ones? */
if (functionp(funcs[k]))
cmds += ({ verbs[e], 0, _OB(funcs[k]), _FUNC(funcs[k]) });
}
}
}
/* return result */
return cmds;
}
#endif /* MUDOS_COMMAND */
/* accessible command(str) from DriverLib */
nomask int __command(string str) {
if (!DRIVER_PRIV()) {
/* Illegal call! */
illegal();
return 0;
}
return command(str);
}