/* -*- LPC -*- */
/*
* $Locker: $
* $Id: climb.c,v 1.7 2002/10/24 14:08:22 danbala Exp $
*
*/
#include <tasks.h>
#define TP this_player()
// This is the default skill. Note that it's possible to set
// this with the move parameter in set_wall().
#define SKILL "other.movement.climbing.rock"
inherit "/cmds/base";
void fall_off( object place, int number ) {
if ( place->query_at_bottom() ) {
write( "You try to climb, but you can't seem to get anywhere.\n" );
say( (string)TP->one_short() + " tries to climb, but fails.\n" );
return;
}
if ( random( (int)TP->query_dex() ) < number / 20 ) {
write( "You begin to climb, but your fatigue makes you "+
"clumsily lose your grip.\n" );
say( (string)TP->one_short() +
" begins to climb but clumsily loses "+
(string)TP->query_possessive() +" grip.\n" );
place->fall_down( TP );
return;
}
write( "You begin to climb but wobble precariously and decide to "+
"stay put for the moment.\n" );
say( (string)TP->one_short() +
" begins to climb, but wobbles precariously and stops.\n" );
} /* fall_off() */
mixed cmd( string words ) {
int difficulty;
object place;
mixed ghost_action;
mixed *move;
string *move_descs = ({ "", "", "" }); // to player, from, to
string skill;
place = environment( TP );
if ( !place ) {
add_failed_mess( "You cannot climb anything: you're in limbo!\n" );
return 0;
}
move = (mixed *)place->query_move( words );
if ( !move ) {
// Give a hint that it's possible to climb in some direction.
if( sizeof( place->query_moves() ) )
add_failed_mess( "You cannot climb \""+ words +"\" from here.\n" );
else // They can stop trying
add_failed_mess( "There is nothing to climb here.\n" );
return 0;
}
// move[2] is either a string, containing the message given to the
// destination when the player climbs in, or an array of strings with
// the following contents:
// ({ message to player,
// message to room they are climbing from,
// message to destination room })
// If the old format, with just a destination string, is used,
// fill in the blanks.
if( stringp( move[2] ) ) {
move_descs[0] =
"You climb "+ words +".\n";
move_descs[1] =
"$N slowly climb$s "+ words +" and disappears from view.";
move_descs[2] =
copy( move[2] );
} else if( sizeof( move[2] ) == 3 ) {
// New and improved format - all is hoopy
move_descs = copy( move[2] );
move_descs[0] += "\n"; // Uses write rather than move_mess
} else {
// Unknown format
return 0;
}
/* Ghosts and climbing */
if ( TP->query_property( "dead" ) ) {
ghost_action = place->query_ghost_action( place );
/* no special action - no skill check for ghosts */
if ( ! ghost_action ) {
TP->move_with_look( move[ 1 ], move_descs[ 2 ], move_descs[ 1 ] );
add_succeeded_mess("");
return 1;
}
/* set ghost action - ghosts aren't allowed to climb at all */
else if ( intp( ghost_action ) && ghost_action == 1 ) {
add_failed_mess( "How can you climb anything? You're dead!\n");
return 0;
}
/* string - we move to this location with a default message */
else if ( stringp( ghost_action ) ) {
write( "As you move to climb the wall, your inherent wispiness gets "
"the better of you, and you fall through to the other side.\n" );
TP->move_with_look( ghost_action,
"$N wisps through the wall with some undue haste.",
"$N tries to climb the wall, but falls through it." );
add_succeeded_mess( "" );
return 1;
}
/* array - move to a location with specified move messages */
else if ( arrayp( ghost_action ) ) {
write( ghost_action[ 1 ][ 0 ] + "\n" );
TP->move_with_look( ghost_action[ 0 ],
ghost_action[ 1 ][ 1 ], ghost_action[ 1 ][ 2 ] );
add_succeeded_mess( "" );
return 1;
}
/* default action - move with no skill check */
else {
TP->move_with_look( move[ 1 ], move_descs[ 2 ], move_descs[ 1 ] );
add_succeeded_mess("");
return 1;
}
}
// In the "old style", the difficulty parameter is just an int. In that
// case, we'll use the default SKILL.
if( intp( move[0] ) ) {
difficulty = move[0] + (int)TP->query_loc_weight() / 10;
skill = SKILL;
} else if( arrayp( move[0] ) && sizeof( move[0] ) > 1 ) {
// In the "new style", the difficulty parameter is an array:
// ({ base difficulty, skill to test })
difficulty = move[0][0] + (int)TP->query_loc_weight() / 10;
skill = move[0][1];
debug_printf( "Base difficulty: %d, total difficulty: %d, skill: %s\n",
move[0][0], difficulty, move[0][1] );
}
if ( (int)TP->query_specific_gp( "other" ) < difficulty ) {
fall_off( place, difficulty );
add_succeeded_mess("");
return 1;
}
TP->adjust_gp( -difficulty / 2 );
switch ( (int)TASKER->perform_task(TP, skill, difficulty,
TM_COMMAND)) {
case AWARD :
call_out( "advance_notice", random( 60 ), TP );
case SUCCEED :
write( move_descs[ 0 ] );
TP->move_with_look( move[ 1 ], move_descs[ 2 ],
move_descs[ 1 ] );
return 1;
default :
break;
}
difficulty = random( difficulty );
if ( (int)TP->query_specific_gp( "other" ) < difficulty ) {
fall_off( place, difficulty );
add_succeeded_mess("");
return 1;
}
TP->adjust_gp( -difficulty );
switch ( (int)TASKER->perform_task(TP, skill, difficulty / 2,
TM_COMMAND)) {
case AWARD :
write( "%^YELLOW%^You manage not to fall off!%^RESET%^\n" );
case SUCCEED :
write( "You begin to climb but wobble precariously and decide to "+
"stay put for the moment.\n" );
say( (string)TP->one_short() +
" begins to climb, but wobbles precariously and stops.\n" );
break;
default :
fall_off( place, difficulty );
break;
}
add_succeeded_mess("");
return 1;
} /* cmd() */
void advance_notice( object thing ) {
if ( !thing )
return;
tell_object( thing, "%^YELLOW%^"+ ({
"In a flash of inspiration, you realise how to balance better "+
"when climbing.",
"Thinking about your climb, you realise something important.",
"You realise that you've been using better grips to climb.",
"You realise you've discovered how to find better places to "+
"support your feet.",
"You find you've worked out a more sensible way to distribute "+
"your weight as you climb.",
"With all your climbing, you discover you've found a better way "+
"to locate handholds."
})[ random( 6 ) ] +"%^RESET%^\n" );
} /* advance_notice() */
mixed *query_patterns() {
return ({ "<string'direction'>", (: cmd($4[0]) :) });
} /* query_patterns() */