--- deliantra/server/ext/map-random.ext 2008/04/11 21:09:53 1.20 +++ deliantra/server/ext/map-random.ext 2008/05/06 16:39:28 1.28 @@ -1,5 +1,7 @@ #! perl # mandatory +use Coro::AIO; + cf::map->register (qr{^\?random/([0-9a-f]{32})}); sub init { @@ -75,6 +77,69 @@ } } +# called by the random map generator +sub find_style_; +sub find_style_($$) { + my ($path, $difficulty) = @_; + + my $map; + + $map = cf::map::find $path + unless aio_stat "$cf::MAPDIR/$path.map"; + + unless ($map) { + # search files and/or dirs + if (my ($dirs, $nondirs) = aio_scandir "$cf::MAPDIR/$path/", 1) { + my @entries = sort grep s/\.map$//, @$nondirs; + + if ($difficulty < 0) { + # pick a fully random map, but only a map, do not recurse + $map = cf::map::find "$path/$entries[cf::rmg_rndm scalar @entries]" + if @entries; + } else { + # pick a map with nearest difficulty value ("mapname_.map") + @entries = sort @$dirs + unless @entries; + + my $min_diff = 1e99; + + for my $name (@entries) { + if ($name =~ /_(\d+)$/) { + my $diff = abs $difficulty - $1 + 0.5; # prefer the more difficult version + ($map, $min_diff) = ($name, $diff) if $diff < $min_diff; + } + } + + unless ($map) { + # no map with given pattern found, choose a random map + $map = $entries[cf::rmg_rndm scalar @entries]; + } + + $map = find_style_ "$path/$map", $difficulty + if $map; + } + } + } + + $map +} + +sub find_style($$$) { + my ($dir, $name, $difficulty) = @_; + + cf::cede_to_tick; + + my $map = find_style_ $name ? "$dir/$name" : $dir, $difficulty; + + if ($map) { + $map->load; + $map->deactivate; + } + + #warn "return $dir,$name,$difficulty => $map\n" if $difficulty >= 0;#d# + $map +} + # clean up old temp maps regularly our $CLEAN_RANDOM_MAPS = cf::periodic 3600, Coro::unblock_sub { clean_random_maps; @@ -97,6 +162,19 @@ } }; } + +# prefetch test, load some ocean-maps +if (0) { + cf::async { + # 0.58 + Coro::Timer::sleep 2; + for my $x (200..219) { + for my $y (200..219) { + (cf::map::find "/world/world_$x\_$y")->load; + } + } + }; +} 1