Code: Select all
Index: src/Field.pm
===================================================================
--- src/Field.pm (revision 8005)
+++ src/Field.pm (working copy)
@@ -45,7 +45,7 @@
use Compress::Zlib;
use File::Spec;
-use Globals qw($masterServer %mapAlias_lut %maps_lut %cities_lut);
+use Globals qw($masterServer %mapAlias_lut %maps_lut %cities_lut %portals_lut);
use Modules 'register';
use Settings;
use FastUtils;
@@ -292,7 +292,12 @@
if (!-f $distFile || !$self->loadDistanceMap($distFile, $width, $height)) {
# (Re)create the distance map.
my $f;
- $self->{dstMap} = Utils::makeDistMap($fieldData, $width, $height);
+ # TODO aliases, instances
+ my @avoidPos = map {{x => $_->{source}{x}, y => $_->{source}{y}}}
+ grep { !$_->{steps} && $_->{source}.'.dist' eq $distFile }
+ values %portals_lut;
+
+ $self->{dstMap} = Utils::makeDistMap($fieldData, $width, $height, \@avoidPos);
if (open($f, ">", $distFile)) {
binmode $f;
print $f pack("a2 v1", 'V#', 3);
Index: src/auto/XSTools/misc/fastutils.xs
===================================================================
--- src/auto/XSTools/misc/fastutils.xs (revision 8005)
+++ src/auto/XSTools/misc/fastutils.xs (working copy)
@@ -6,6 +6,7 @@
#include "perl.h"
#include "XSUB.h"
typedef double (*NVtime_t) ();
static void *NVtime = NULL;
@@ -205,16 +206,20 @@
SV *
-makeDistMap(rawMap, width, height)
+makeDistMap(rawMap, width, height, avoid = NO_INIT)
SV *rawMap
int width
int height
+ SV *avoid
INIT:
STRLEN len;
- int i, x, y;
- int dist, val;
+ int i, j, x, y;
+ int dist, val, size;
unsigned char *c_rawMap, *data;
bool done;
+ AV *array_avoid;
+ HV *avoid_item;
+ SV **valSV;
CODE:
if (!SvOK (rawMap))
XSRETURN_UNDEF;
@@ -223,6 +228,10 @@
if ((int) len != width * height)
XSRETURN_UNDEF;
+ array_avoid = (AV *) SvRV (avoid);
+ if (!array_avoid)
+ croak("The 'avoid' parameter must be a valid arrayref.\n");
+
/* Simplify the raw map data. Each byte in the raw map data
represents a block on the field, but only some bytes are
interesting to pathfinding. */
@@ -241,6 +250,19 @@
}
}
+ size = av_len (array_avoid);
+ for (j = 0; j < size; j++) {
+ valSV = av_fetch (array_avoid, j, 0);
+ if (!valSV)
+ continue;
+ avoid_item = (HV *) SvRV (*valSV);
+ x = SvIV (*hv_fetch (avoid_item, "x", 1, 0));
+ y = SvIV (*hv_fetch (avoid_item, "y", 1, 0));
+ i = y * width + x;
+ if (data[i] == 255)
+ data[i] = 1;
+ }
+
done = false;
while (!done) {
done = true;