#define SWIMMING_SKILL "general.swimming" #define SHADOW "/std/shadows/misc/water" #define WET_EFFECT "/std/effects/object/wet" #define WET_EFFECT_MATCH "object.wet" #include <tasks.h> #include <position.h> int surface = 1; string up_dir = "up", down_dir = "down", f_in_mess = "$N float$s in from $F.", f_out_mess = "$N float$s $T.", s_in_mess = "$N sink$s in from $F.", s_out_mess = "$N sink$s $T.", c_in_mess = "$N get$s dragged in from $F.", c_out_mess = "$N get$s dragged away $T.", on_bottom = "lying on the bottom", non_float = "drifting nearby", floating = "floating nearby"; int clarity = 100, salinity = 0; int recheck_delay = -1; mapping flows = ([ ]), delays = ([ ]); int attempt_exit( string dir, object ob ); /** * This method masks the standard one, to give messages more in-line * with wet areas. See the general documentation for more details. * @see query_default_position() */ mixed *query_default_position(object ob) { return ({ SWIMMING, "You start to swim.\n", capitalize(ob->the_short()) + " starts to swim.\n" }); } /* query_default_position() */ /** * This method masks the standard one, to handle liquid-based positions. * See the general documentation for more details. * @see is_allowed_position() */ int is_allowed_position(string poss) { switch (poss) { case SWIMMING : return 1; default : return 0; } } /* is_allowed_position() */ /** * This method sets the delay before an object is swept downstream. * @param dir the direction the object is swept * @param delay the amount of time to wait */ void set_min_sweep_delay( string dir, int delay ) { delays[ dir ] = delay; return; } /* set_min_sweep_delay() */ /** * This method returns the sweep delay for the given direction. * @param dir the exit direction * @return the sweep delay for the given direction */ int query_min_sweep_delay( string dir ) { return delays[ dir ]; } /** * This method returns the sweep delays for all exits as a mapping. * @return a mapping of all exits and their sweep delays */ mapping query_min_sweep_delays() { return delays; } /** * Documentation TBD */ void set_recheck_delay( int time_out ) { recheck_delay = time_out; INV( TO )->update_recheck( time_out ); return; } /* set_recheck_delay() */ /** * Documentation TBD */ int query_recheck_delay() { return recheck_delay; } void set_bottom_mess( string mess ) { on_bottom = mess; return; } string query_bottom_mess() { return on_bottom; } void set_nonfloat_mess( string mess ) { non_float = mess; return; } string query_nonfloat_mess() { return non_float; } void set_float_mess( string mess ) { floating = mess; return; } string query_float_mess() { return floating; } void set_sink_in_mess( string mess ) { s_in_mess = mess; return; } string query_sink_in_mess() { return s_in_mess; } void set_sink_out_mess( string mess ) { s_out_mess = mess; return; } string query_sink_out_mess() { return s_out_mess; } void set_float_in_mess( string mess ) { f_in_mess = mess; return; } string query_float_in_mess() { return f_in_mess; } void set_float_out_mess( string mess ) { f_out_mess = mess; return; } string query_float_out_mess() { return f_out_mess; } void set_sweep_in_mess( string mess ) { c_in_mess = mess; return; } string query_sweep_in_mess() { return c_in_mess; } void set_sweep_out_mess( string mess ) { c_out_mess = mess; return; } string query_sweep_out_mess() { return c_out_mess; } void set_surface( int on_top ) { surface = on_top; return; } /* set_surface() */ int query_water() { return 1; } int query_surface() { return surface; } int query_bottom() { return ( member_array( down_dir, (string *)TO->query_exits() ) == -1 ); } void add_flow( string dir, mixed rate ) { if ( intp( rate ) || functionp( rate ) ) { flows[ dir ] = rate; } return; } /* add_flow() */ void delete_flow( string dir ) { map_delete( flows, dir ); return; } /* delete_flow() */ int query_flow(string dir) { return evaluate( flows[dir] ); } mapping query_flows() { string dir; mapping ret_flows; ret_flows = ([ ]); foreach ( dir in keys( flows ) ) { ret_flows[ dir ] = evaluate( flows[ dir ] ); } return ret_flows; } /* query_flows() */ void set_clarity( int how_clear ) { if ( how_clear < 0 ) clarity = 0; else if ( how_clear > 100 ) clarity = 100; else clarity = how_clear; return; } /* set_clarity() */ int query_clarity() { return clarity; } void set_salinity( int how_salty ) { if ( how_salty < 0 ) salinity = 0; else if ( how_salty > 100 ) salinity = 100; else salinity = how_salty; return; } /* set_salinity() */ int query_salinity() { return salinity; } void set_up_dir( string dir ) { up_dir = dir; return; } string query_up_dir() { return up_dir; } void set_down_dir( string dir ) { down_dir = dir; return; } string query_down_dir() { return down_dir; } void event_enter( object ob, string, object from ) { object *cntnrs, jar, h2o, *stuff; if ( !ob->query_property( "dead" ) ) { if ( !ob->find_water_shadow() ) clone_object( SHADOW )->setup_shadow(ob); else if ( surface && from && !from->query_surface() && living( ob ) && !ob->query_property( "gills" ) ) { tell_object( ob, "You break the surface and take a deep breath.\n" ); tell_room( TO, (string)ob->one_short() + " breaks the " "surface and takes a deep breath.\n", ({ ob }) ); } ob->test_float(); ob->test_sweep(); if ( living( ob ) ) { ob->test_drown(); ob->do_soak(); } if ( !ob->query_dry_cargo() ) { cntnrs = filter_array( stuff = INV( ob ), "find_containers", TO ); foreach ( jar in cntnrs ) { h2o = clone_object( WATER_OBJ ); h2o->set_amount( (int)jar->query_max_volume() - (int)jar->query_volume() ); h2o->move( jar ); } cntnrs = filter_array( stuff, "find_towels", TO ); foreach ( jar in cntnrs ) jar->add_effect( WET_EFFECT, 200 * (int)jar->query_weight() ); } ob->update_recheck( recheck_delay ); } return; } /* event_enter() */ void event_exit( object ob, string mess, object to ) { if ( to && !to->query_water() ) ob->dest_water_shadow(); else ob->cancel_sweep(); } /* event_exit() */ int attempt_exit( string dir, object ob ) { int outcome, diff, flow_rate; outcome = SUCCEED; flow_rate = evaluate( flows[ dir ] ); if ( dir == up_dir && ( diff = (int)ob->query_buoyancy() + flow_rate ) < 0 && !surface ) { outcome = (int)TASKER->attempt_task( -diff, (int)ob->query_swim_bonus(), 100, -diff ); if ( outcome == FAIL ) { tell_room( TO, (string)ob->query_short() + " struggles " "to leave " + up_dir + ", but can't make any headway.\n", ob ); tell_object( ob, "You struggle to leave " + up_dir + " but, with " "load you're carrying, you can't make any headway.\n" ); return 0; } } else if ( dir == down_dir && ( diff = (int)ob->query_buoyancy() - flow_rate ) > (int)ob->query_swim_bonus() ) { outcome = (int)TASKER->attempt_task( diff, (int)ob->query_swim_bonus(), 100, diff ); if ( outcome == FAIL ) { tell_room( TO, (string)ob->query_short() + " struggles " "to leave " + down_dir + ", but can't make any " "headway.\n", ob ); tell_object( ob, "You struggle to leave " + down_dir + " but, with " "your buoyancy, you can't make any headway .\n" ); return 0; } } else if ( flow_rate < 0 ) { outcome = (int)TASKER->attempt_task( -flow_rate, (int)ob->query_swim_bonus(), 100, -flow_rate ); if ( outcome == FAIL ) { tell_room( TO, (string)ob->query_short() + " struggles " "against the " + dir + " current, but can't make any " "headway.\n", ob ); tell_object( ob, "You can't make any headway against the " "current.\n" ); return 0; } } if ( outcome == AWARD && ob->add_skill_level( SWIMMING_SKILL, 1 )) { tell_object( ob, ({ "%^YELLOW%^You move more surely as you glide " "through the water.\n%^RESET%^", "%^YELLOW%^You discover a more efficient " "stroke.\n%^RESET%^", "%^YELLOW%^You find a better way to streamline " "your body.\n%^RESET%^", "%^YELLOW%^You find a more efficient swimming " "rhythm.\n%^RESET%^", "%^YELLOW%^You begin to move more confidently " "through the water.\n%^RESET%^" })[ random(5) ] ); } return 1; } /* attempt_exit() */ int find_containers( object ob ) { return (int)ob->query_max_volume() && !(int)ob->query_closed(); } /* find_containers() */ int find_towels( object ob ) { int *effects; effects = (int *)ob->effects_matching( WET_EFFECT_MATCH ); return (int)ob->id( "towel" ) && ( !sizeof( effects ) || (int)ob->arg_of( effects[ 0 ] ) < 200 * (int)ob->query_weight() ); } /* find_towels() */ string query_name() { return "drowning"; } void init() { if ( TP ) { TP->add_command( "float", TO, "" ); TP->add_command( "swim", TO, "" ); } } int do_float() { return TP->do_float(); } int do_swim() { return TP->do_swim(); }