Avoid portals like walls

Forum closed. All further discussion to be discussed at https://github.com/OpenKore/

Moderator: Moderators

Message
Author
EternalHarvest
Developers
Developers
Posts: 1798
Joined: 05 Dec 2008, 05:42
Noob?: Yes

Avoid portals like walls

#1 Post by EternalHarvest »

Unfinished (for example, needs to automatically rebuild .dist files on portal change and instances support), untested. I have no idea if it even does what intended, but at least it compiles and runs.

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;

Locked