#! perl # this module implements the town portal spell: # casting it creates a magic portal to the nearest town portal (regions) # using the magic portal brings you to the town portal and remembers your magic portal # using the town portal brings you back to the magic portla if it still exists cf::object->attach ( type => cf::SPELL, subtype => cf::SP_TOWN_PORTAL, on_cast_spell => sub { my ($spell, $who, $caster, $dir, $arg) = @_; my $region = $who->region or return cf::override 0; my ($map, $x, $y); while () { ($map, $x, $y) = ($region->portalmap, $region->portalx, $region->portaly); last if $map; $region = $region->parent or return cf::override 0; } my $portal = $spell->other_arch->instantiate; $portal->name ("Magic Portal to nearest Town"); $portal->slaying ($map); $portal->stats->hp ($x); $portal->stats->sp ($y); #$portal->stats->food (40); # handy for debugging $portal->insert_at ($who, $who, cf::INS_ABOVE_FLOOR_ONLY); $who->reply (undef, "A shimmering portal opens.", cf::NDI_NAVY); cf::override 1; }, ); cf::object::attachment town_portal => on_apply => sub { my ($self, $who) = @_; $who->{town_portal} = [$who->map, $who->x, $who->y, $self->uuid]; }, ; cf::object::attachment town_portal_return => on_apply => sub { my ($self, $who) = @_; if ($who->{town_portal}) { my ($map, $x, $y, $uuid) = @{ $who->{town_portal} }; $who->goto ($map, $x, $y, sub { my ($map) = @_; if (grep $_->uuid eq $uuid, $map->at ($x, $y)) { $who->reply (undef, "The town portal weaves its magic... and after a short moment, you return to the magic portal.", cf::NDI_NAVY); delete $who->{town_portal}; return $map; } else { $who->reply (undef, "The town portal weaves its magic... but the magic link to your portal is too weak. " . "[The town portal you used to come here might be gone.]", cf::NDI_NAVY); } () }); } else { $who->reply (undef, "The town portal weaves its magic... but nothing happens. " . "[You must arrive through this portal to be able to return.]", cf::NDI_NAVY); } cf::override 1; }, ;