#! perl # handle the nimbus map and other stuff my @STATS = qw( Str Dex Con Wis Cha Int Pow wc ac hp maxhp sp maxsp grace maxgrace food dam luck ); sub stats_get($) { my ($stats, $save) = @_; for my $stat (@STATS) { $save->{$stat} = $stats->$stat; } $save } sub stats_set($$) { my ($stats, $save) = @_; for my $stat (@STATS) { $stats->$stat ($save->{$stat}); } $stats->hp ($stats->maxhp); $stats->grace ($stats->maxgrace); $stats->food (999); } sub skills_get($) { my ($ob) = @_; +{ "" => $ob->stats->exp, map +($_->skill => $_->stats->exp), grep $_->type == cf::SKILL, $ob->inv } } sub skills_set($$) { my ($ob, $skill) = @_; my $cur = skills_get $ob; while (my ($name, $exp) = each %$skill) { if ($cur->{$name} < $exp) { length $name ? $ob->change_skill ($exp - $cur->{$name}, $name) : $ob->change_skill ($exp - $cur->{$name}); } } } # called when the player will likely die (modulo explore mode) # but before any stats/exp is changed sub on_player_death { my ($event) = @_; my $ob = $event->{who}; my $pl = $ob->contr; # save player stats and experience to restore it later my $save = { stats => stats_get $ob->stats, orig_stats => stats_get $pl->orig_stats, savebed => [$pl->get_savebed], skill_exp => skills_get $ob, }; $ob->{in_nimbus} ||= $save; my $path = sprintf "%s/%s/%s/%s", cf::localdir, cf::playerdir, $ob->name, "nimbus"; my $nimbus = cf::map::get_map "/schmorp/nimbus"; $nimbus->set_path ($path); $nimbus->set_unique (1); $pl->set_savebed ($path, 24, 12); $pl->message ("\n"); $pl->message ("You start to feel dizzy.\n"); $pl->message ("The world around you blurs.\n"); $pl->message ("\n"); 0 } sub on_trigger { my ($event) = @_; my $options = $event->{options}; my $ob = $event->{activator}; my $pl = $ob->contr; my @savebed; warn "trigger $options $ob->{nimbus_save}\n";#d# warn $ob->name; if (my $save = delete $ob->{in_nimbus}) { @savebed = @{$save->{savebed}}; if ($options eq "restore" || 1) { stats_set $ob->stats, $save->{stats}; stats_set $pl->orig_stats, $save->{orig_stats}; skills_set $ob, $save->{skill_exp}; } } else { @savebed = ("/scorn/taverns/inn", 10, 5); } $pl->set_savebed (@savebed); my $map = $ob->map; $ob->teleport (cf::map::get_map $savebed[0], $savebed[1], $savebed[2]); $map->delete_map; $pl->message ("You feel as if you woke up from a dream.\n"); $pl->message ("You have a headache.\n"); $pl->message ("Maybe you should have a drink.\n"); 1 }