/* * An effect to put someone to sleep. * * This effect takes one argument: * (int) time: the time until the person will wake up. * * If the person is already asleep, <time> is added to the * length of time remaining until he wakes. * * NB: the value of the "passed out" indicates an object's * current state thus: * 0 = not asleep, not unconscious * 1 = not asleep, unconscious (OUT_COLD) * 2 = asleep, not unconscious (ASLEEP) * 3 = asleep, unconscious (OUT_COLD + ASLEEP) * * The purpose of this effect is to modify the above states * accordingly when a player falls asleep or wakes up. * * * This effect is classified as "asleep" * This effect has a shadow associated with it. * */ #include <effect.h> #include <living.h> #define CLASS "asleep" #define SHADOW "/std/shadows/other/asleep" /** @ignore yes */ string query_classification() { return CLASS; } /** @ignore yes */ string query_shadow_ob() { return SHADOW; } /** @ignore yes */ int beginning( object player, int time ) { /* Determine the player's current state */ int state = player->query_property( PASSED_OUT ); /* If his state == 0, ie he is alert, give him a message * warning him that he's fallen asleep. */ if( !state ) tell_object( player, "You fall asleep.\n" ); /* If he currently alert or is unconscious but not asleep, * put him to sleep now. NB: If he's both asleep and * unconscious, this will put him over the top but the next * step will sort out his states */ if( state != ASLEEP ) state += ASLEEP; /* If he's beyond recognizable values, set him back to the * max value */ if( state > ASLEEP + OUT_COLD ) state = ASLEEP + OUT_COLD; /* Now we know what his new value for the "passed out" property * should be. Add that and continue on with making him appear * to be asleep. */ player->add_property( PASSED_OUT, state ); player->set_position( "lying" ); player->add_extra_look( this_object() ); /* Don't put him to sleep for negative time */ if( time < 0 ) time = 0; player->submit_ee( 0, time, EE_REMOVE ); return time; } /* beginning() */ /** @ignore yes */ int merge_effect( object player, int old_time, int new_time ) { /* We already know he's asleep. Just add (or subtract) * the new time from the remaining duration of the old effect * and let it continue */ new_time += player->expected_tt( 1, player->effects_matching( CLASS )[0] ); /* Still don't put him to sleep for a negative time */ if( new_time < 0 ) new_time = 0; player->submit_ee( 0, new_time, EE_REMOVE ); return new_time; } /* merge_effect() */ /** @ignore yes */ void end( object player ) { /* We must determine what state he's in and therefore what state * to leave him in when he wakes up. Ie: is he also unconscious? */ int state = player->query_property( PASSED_OUT ); /* If he was both asleep and unconscious, this will make him * only unconscious. If he was only asleep, this will remove * the property. If he was only unconscious but not asleep, * something has gone awry. */ state -= ASLEEP; if( state < 0 ) // shouldn't happen state = 0; if( state == ASLEEP ) // this shouldn't happen either state = 0; /* If he's fully alert now, remove the property and tell him * he's woken up. If he's still unconscious, don't give him a * message and reset his "passed out" value. */ if( !state ) { player->remove_property( PASSED_OUT ); tell_object( player, "You wake up.\n" ); player->new_parser( "yawn" ); player->new_parser( "stretch sleepily" ); } else player->add_property( PASSED_OUT, state ); player->remove_extra_look( this_object() ); } /* end() */ /** @ignore yes */ string extra_look( object player ) { if( !sizeof( player->effects_matching( CLASS ) ) ) return ""; return sprintf( "%s is asleep.\n", capitalize( player->query_pronoun() ) ); } /* extra_look() */