#! perl # optional # optional plug-in to speed up worldmap rendering by dynamically # generating it out of an image # - saves loading time (less data to read) # - saves temporary space (only overlay stuff needs to be saved) # - might get reused as a generic tiled map cf::map->register (qr{^/world/world_(\d\d\d)_(\d\d\d)$}, 100); use Coro::Handle; use Coro::AIO; my $TILE_W = 50; my $TILE_H = 50; my $GRID_W = 30; my $GRID_H = 30; our $ARCH; our $REGN; sub reload() { cf::trace "loading world+100+100 table.\n"; $ARCH = cf::decode_storable cf::unlzf cf::load_file "$DATADIR/world+100+100.arch"; $REGN = cf::decode_storable cf::unlzf cf::load_file "$DATADIR/world+100+100.regn"; cf::trace "loaded world+100+100 table.\n"; } { my $guard = cf::lock_acquire "ext::world_gridmap"; cf::post_init { cf::async_ext { $Coro::current->{desc} = "worldmap loader"; reload; undef $guard; }; }; } sub wxwy { $_[0]->path =~ m{/world/world_(\d\d\d)_(\d\d\d)$} ? ($1, $2) : (0, 0) } sub load_header_orig { my ($self) = @_; my ($x, $y) = $self->wxwy; my $guard = cf::lock_acquire "ext::world_gridmap"; $self->width ($TILE_W); $self->height ($TILE_H); $self->name ("'The World' at +$x+$y"); $self->msg ("worldmap dynamically created by map-world extension"); $self->outdoor (1); $self->default_region (cf::region::find "wilderness"); $self->tile_path (0, sprintf "/world/world_%03d_%03d", $x, $y - 1) if $y > 0; $self->tile_path (1, sprintf "/world/world_%03d_%03d", $x + 1, $y) if $x < 999; $self->tile_path (2, sprintf "/world/world_%03d_%03d", $x, $y + 1) if $y < 999; $self->tile_path (3, sprintf "/world/world_%03d_%03d", $x - 1, $y) if $x > 0; my $overlay = sprintf "%s/world/world_%03d_%03d.map", $cf::MAPDIR, $x, $y; $self->{load_path} = $overlay unless Coro::AIO::aio_stat $overlay; $self->{need_create_treasure} = 1; 1 } sub fill { my ($self) = @_; $self->add_underlay ("\x00" x ($TILE_W * $TILE_H), 0, $TILE_W, $ARCH->{plt}); $self->default_region (cf::region::find $REGN->{plt}[0]); } sub load { my ($self) = @_; if ($self->{load_path}) { $self->SUPER::load; } else { $self->alloc; $self->fill; $self->in_memory (cf::MAP_ACTIVE); $self->activate; } } sub post_load { my ($self) = @_; { my $guard = cf::lock_acquire "ext::world_gridmap"; my ($x, $y) = $self->wxwy; if ($x >= 100 && $x <= 129 && $y >= 100 && $y <= 129) { my $stride = $GRID_W * $TILE_W; my $top = ($y - 100) * $TILE_H * $stride + ($x - 100) * $TILE_W; $self->add_underlay ($ARCH->{tbl}, $top, $stride, $ARCH->{plt}); $self->set_regiondata ($REGN->{tbl}, $top, $stride, $REGN->{plt}); } else { $self->fill; } } $self->create_region_treasure if delete $self->{need_create_treasure}; }