/* Do not remove the headers from this file! see /USAGE for more info. */
/*
** smartmove.c
**
** A smarter movement system for some objects. It handles movement from
** room to room.
*/
#include <move.h>
#include <playerflags.h>
#include <hooks.h>
#include <size.h>
#include <classes.h>
inherit CLASS_MOVE;
varargs mixed call_hooks(string, mixed, mixed);
varargs mixed move(mixed dest, string where);
string query_msg(string which);
int test_flag(int which);
void simple_action(string s,array obs... );
varargs string *action(object *who, mixed msg, array obs...);
varargs string compose_message(object forwhom, string msg, object *who,
array obs...);
object query_target();
private nomask int move_me_there(class move_data data)
{
object last_loc = environment();
object env;
object d;
mixed r;
mixed txt;
string m;
if ( (r = move(data->destination,data->relation)) != MOVE_OK) {
if(!stringp(r)) {
if(r == MOVE_NO_ERROR)
return 1;
write("You remain where you are.\n");
return 0;
}
switch(r) {
case MOVE_NO_DEST:
write("Construction blocks your path.\n");
return 0;
case MOVE_NO_ROOM:
d = load_object(data->destination);
if(d->query_max_capacity()-d->query_capacity()-VERY_LARGE < 0) {
if(sizeof(filter(all_inventory(d),(:$1->is_living():)))) {
write("You might be able to fit if there weren't "
"something moving around there already.\n");
}
else {
write("You're unable to fit.\n");
}
}
else {
write("You aren't able to fit with the load you're "
"carrying.\n");
}
return 0;
default:
write("You remain where you are.\n");
return 0;
}
}
/* Make sure that there is some type of direction for the exit */
if ( !data->exit_dir ) {
data->exit_dir= "somewhere";
}
/* Also ensure that there is a valid object being moved */
if ( !data->who ) {
data->who = this_body();
}
env = environment();
/* Exit Messages */
txt = data->exit_messages;
/* If there is no exit message for the exit, use the default for that body.
* The default message is not one that should be processed any further.*/
if ( !txt )
txt = query_msg("leave");
/* Display the message */
if(data->source)
tell_from_inside(last_loc,action(({data->who}),txt,data->source)[1]);
else
tell_from_inside(last_loc,action(({data->who}),txt,data->exit_dir)[1]);
/* Entrance messages */
txt = data->enter_messages;
/* If there is no enter message for the exit, use the default for that body.
* The default message is not one that should be processed any further.*/
if ( !txt )
txt = query_msg("enter");
/* Display the message */
if(data->through)
simple_action(txt,data->through);
else if(data->source)
simple_action(txt,data->source);
else
simple_action(txt);
return r == MOVE_OK;
}
//:FUNCTION notify_move
//Basically do a this_body()->force_look().
//Seperated out so vehicles could change this
//without having to override the move_to() function.
void notify_move()
{
this_object()->force_look(0);
}
//:FUNCTION move_to
//Move the object to a new location. Returns 1 if the move was successful,
//0 otherwise. The first arg is a filename, the second is the direction
//that caused the movement to that destination.
//:HOOK person_left
//Called when a person successfully leaves a room in a certain direction
//(called by the room). The return value is ignored. The person moving
//is given by this_body(). The direction is passed as an argument.
//:HOOK person_arrived
//Called when a person successfully enters a room from a direction.
//The return value is ignored. The person moving is given by this_body().
//The direction is passed as an argument.
//varargs int move_to(string dest, mixed dir, mixed exit, mixed enter)
varargs int move_to(class move_data data)
{
object where = environment();
if (move_me_there(data))
{
where->call_hooks("person_left", HOOK_IGNORE, 0, data->exit_dir);
environment()->call_hooks("person_arrived", HOOK_IGNORE, 0, data->exit_dir);
call_hooks("interrupt", HOOK_IGNORE);
}
if ( where != environment() )
{
this_object()->notify_move();
return 1;
}
return 0;
}