/* Do not remove the headers from this file! see /USAGE for more info. */
/*
** verb_ob.c
**
** This is a standard verb handler. It handles adding and removing
** verb rules (to/from the parser efuns).
*/
#include <verbs.h>
string verb = split_path(file_name())[1];
int flags = NEED_TO_SEE | NEED_TO_BE_ALIVE | NEED_TO_THINK;
protected varargs void add_rules(array rules, array syns)
{
parse_init();
foreach (string rule in rules)
{
parse_add_rule(verb, rule);
if (syns)
foreach (string syn in syns)
parse_add_synonym(syn, verb, rule);
}
}
protected void set_flags(int f){ flags = f; }
protected void add_flag(int f){ flags |= f; }
protected void clear_flag(int f){ flags &= ~f; }
string refer_to_object(object ob)
{
// In the future, this should be smarter. Ideally it would generate
// something unique like 'my first sword' or 'the third sword on the table'
return ob->query_primary_name();
}
mixed try_to_acquire(object ob)
{
/* for things that can be used in certain conditions without
* actually being in the player's inventory
*/
if (ob->always_usable())
return 1;
if (environment(ob) == this_body())
return 1;
write("(Taking " + ob->the_short());
if (!environment(ob))
{
write(" first)\n");
write("What a quaint idea.\n");
return 0;
}
if (environment(ob) != environment(this_body()))
write(" from " + environment(ob)->the_short());
write(" first)\n");
this_body()->do_game_command("get " + refer_to_object(ob));
return environment(ob) == this_body();
}
mixed check_ghost()
{
if (this_body()->query_ghost())
return "But you're a ghost!\n";
return 1;
}
mixed check_vision()
{
if (environment(this_body())->query_light())
return 1;
if (environment(this_body())->parent_environment_accessible())
if (environment(environment(this_body()))->query_light())
return 1;
return "You can't see a thing!\n";
}
mixed check_condition()
{
mixed tmp;
if (tmp = this_body()->check_condition(0))
return tmp;
return 1;
}
/* All (most) can_* functions should call this */
mixed default_checks()
{
mixed tmp;
if ((flags & NEED_TO_SEE) && (tmp = check_vision()) != 1)
return tmp;
if ((flags & NEED_TO_BE_ALIVE) && (tmp = check_ghost()) != 1)
return tmp;
// This checks stunned, asleep
if ((flags & NEED_TO_THINK))
return check_condition();
return 1;
}
void handle_obs(array info, function callback, mixed extra...)
{
foreach (mixed ob in info)
{
if (stringp(ob))
write(ob);
else
{
// write(ob->short() + ": ");
evaluate(callback, ob, extra...);
}
}
}
/* we defined the rule, so assume by default we allow it */
mixed can_verb_rule(string verb, string rule)
{
return default_checks();
}
int do_verb_one(string verb, object ob)
{
if ((flags & TRY_TO_ACQUIRE) && !try_to_acquire(ob))
{
// write("You can't get " + ob->the_short() +
// " in order to " + verb + " it.\n");
return 0;
}
if(function_exists("do_" + verb, ob))
{
call_other(ob, "do_" + verb);
return 1;
} else {
// Safety net in case the object has no do_ function
write("Trying to " + verb + " " + ob->the_short() + " has no effect.\n");
return 0;
}
}
/* default behavior for OBJ rules */
void do_verb_obj(string verb, object ob)
{
if(do_verb_one(verb, ob))
this_body()->simple_action("$N $v" + verb + " the $o.", ob);
}
/* default behavior for OBS rules */
void do_verb_obs(string verb, object * obs)
{
object * success = ({});
foreach(mixed ob in obs)
if(objectp(ob))
if(do_verb_one(verb, ob))
success += ({ ob });
if(sizeof(success))
this_body()->simple_action("$N $v" + verb + " the $o.", success);
}
// default behaviour for "" rules
// Use this where you want to prompt player to use an object with verb
void do_verb(string verb)
{
write(sprintf("You can't just %s - you need to %s something.\n",
verb, verb));
}