/* * An effect to knock someone out. * * This effect takes one argument: * (int) time: the time until the person will regain * consciousness. * * If the person is already unconscious, <time> is added to the * length of time remaining until he regains consciousness. * * 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 loses or regains consciousness. * * This effect is classified as "unconscious" * This effect has no shadow associated with it. * */ #include <effect.h> #include <living.h> #define CLASS "unconscious" /** @ignore yes */ string query_classification() { return CLASS; } /** @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 lost consciousness. */ if( !state ) tell_object( player, "You lose consciousness.\n" ); /* If he currently alert or is asleep but not unconscious, * make him unconscious 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 != OUT_COLD ) state += OUT_COLD; /* If he's beyond recognizable values, set him back to the * max value */ if( state > OUT_COLD + ASLEEP ) state = OUT_COLD + ASLEEP; /* 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 unconscious. */ player->add_property( PASSED_OUT, state ); player->set_position( "lying" ); player->add_extra_look( this_object() ); /* Make sure we knock him out 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 unconscious. 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 knock him out for 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 regains consciousness. Ie: is he also * asleep? */ int state = player->query_property( PASSED_OUT ); /* If he was both asleep and unconscious, this will make him * only asleep. If he was only unconscious, this will remove * the property. If he was only asleep but not unconscious, * something has gone awry. */ state -= OUT_COLD; if( state < 0 ) // shouldn't happen state = 0; if( state == OUT_COLD ) // this shouldn't happen either state = 0; /* If he's fully alert now, tell him so. Don't tell sleeping * players. */ if( !state ) { player->remove_property( PASSED_OUT ); tell_object( player, "You regain consciousness.\n" ); player->new_parser( "groan" ); } 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 unconscious.\n", capitalize( player->query_pronoun() ) ); } /* extra_look() */