Is there a way to clear all instances of a zone?

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

Post Reply
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Is there a way to clear all instances of a zone?

Post by sheamkennedy »

I was wondering if there is a way to clear every instance of zone #22 on a map without having to scan through every single (x,y) value on the map?

I realize I can check every single (x,y) on the map in a loop to check if zone #22 exists and then delete it but it seems inefficient.

Or alternatively is there a way to have a moveable zone (like somehow assign a zone to an NPC)? What I'm trying to do is destroy every instance of zone #22 and then place zone #22 at a given NPC position. If I can somehow have a moving zone then my original question isn't important.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

There's no default way to accomplish what you want, and there isn't much chance at avoiding the x,y zone read, either.

But, you can still do what you want pretty easily.

Assuming you are moving just one surface zone (in other words, you're just looking for zone #22 and nothing else), you could read the position of your NPC and the surrounding radius of tiles (however far from the center you define) and "write zone (22,x,y)" to whatever falls inside that bubble and "write zone (22,x,y,false) to whatever falls outside.

Unless your map is superhuge, I don't think you should worry about checking zone positions in a loop. In fact, if you implement a short timer (no more than 5 ticks per cycle), I don't think you'll notice so much as a hiccup.

Here's what I'd do (and probably have done somewhere at some point):

On a timer:

Code: Select all

script,repeat move zone,begin
move zone (22,1,5)
set timer (1,0,5,@repeat move zone)
end

script,move zone,which,who,range,begin
erase zone (which)
surround npc with zone (who,which,range)
end

script,erase zone,which,begin
variable (x,y)
for (x,0,map width (current map)) do(
 for (y,0,map height (current map)) do(
  write zone (which,x,y,false)
 )
)
end

script,surround npc with zone,who,which,range,begin
variable (x,y,f,g)
x := npc x (who)
y := npc y (who)
for (f,x,x+range) do(
 for (g,y,y+range) do(
  write zone (which,f,g)
 )
)
for (f,x,x--range,-1) do(
 for (g,y,y--range,-1) do(
  write zone (which,f,g)
 )
)
end
You may need to tweak the "surround npc with zone" script a little to ensure that it actually covers all spaces inside of the maximum ranges (I think this will draw a diamond perfectly, but my math is poor, so test it, or wait for TMC to chime in with a better solution). But, this should accomplish more or less what you want, and it should also be easily adaptable to other npcs if you add more steps to the first script. You may also want to consider fine-tuning it more to check for npc reference.

But yeah, it doesn't need anything fancy. Hope that helps.
Last edited by Pepsi Ranger on Sat Dec 30, 2017 5:14 pm, edited 1 time in total.
Place Obligatory Signature Here
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

I'll play around with that.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1457
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

I just realized two seconds ago that this doesn't account for specific maps. You'll want to add some conditionals to check for current map and break the timer if it doesn't match.
Place Obligatory Signature Here
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

Pepsi Ranger wrote:I just realized two seconds ago that this doesn't account for specific maps.
I realized that. It's not a problem I'll fix it up.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

Pepsi Ranger wrote:...and it should also be easily adaptable to other npcs if you add more steps to the first script.
For the most part I believe this is working (with one NPC) but I thought of a potential issue. What if I have 2 NPCs who I wish to do this to. If the NPCs are side by side the last NPC to update will destroy it's neighbouring NPCs zone won't it?
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
Foxley
Metal Slime
Posts: 832
Joined: Sat Nov 09, 2013 5:54 pm

Post by Foxley »

I don't know how inefficient checking every X/Y on the map is in terms of the engine and everything in the backend, but coding it is absurdly simple and I used it a lot in my Zelda clone.

Code: Select all

plotscript, map zone check, begin
	variable (x tile, y tile)
	
	for (x tile, 0, map width--1) do (	## Go across each X tile...
		for (y tile, 0, map height--1) do (	## ...and check all Y tiles below it.
			if (read zone (22, x tile, y tile)) then (
				## Do a thing to Zone 22
			)
			if (read zone (23, x tile, y tile)) then (
				## Do something else to Zone 23
			)
			elseif (read zone (24, x tile, y tile)) then (
				## Do something to 24 if Zone 23 isn't present
			)
			else (
				## Do something else if none of the above zones are present
			)
		)
	)
end


Thanks go to Feenicks for showing this method a while back.
Last edited by Foxley on Sat Dec 30, 2017 6:14 pm, edited 1 time in total.
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

@PepsiRanger

Haha! I decided to visually debug your script. The tiles in red are where the zone #22 are being drawn. I'll have to look into fixing the math. I almost laughed out loud when I saw it and it's a good thing I didn't, I'm at an airport at 3:15am and the majority of people nearby are sleeping.
Attachments
Screen Shot 2017-12-31 at 3.11.41 AM.png
Screen Shot 2017-12-31 at 3.11.41 AM.png (28.58 KiB) Viewed 1228 times
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

Foxley wrote:I don't know how inefficient checking every X/Y on the map is in terms of the engine and everything in the backend, but coding it is absurdly simple and I used it a lot in my Zelda clone.
Thanks, maybe I should just try it and see if it's optimal enough for what I'm doing. I've been hesitating on trying this because I have to call the script every tick and I'm almost certain it'll bog things down and maybe not get to completion before the next tick (because I also have another taxing LOS script running). But I guess I should just give it a try before abandoning it especially now that you've provided me it and I don't have to write it myself.
Last edited by sheamkennedy on Sat Dec 30, 2017 6:24 pm, edited 1 time in total.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Re: Is there a way to clear all instances of a zone?

Post by TMC »

sheamkennedy wrote:I was wondering if there is a way to clear every instance of zone #22 on a map without having to scan through every single (x,y) value on the map?
Kind of, by calling "load map state" or "reset map state". But that will load/reset all zones. Also, because it's doing so much more work, including a lot of file I/O, I don't know whether it would actually be faster than using a script.

Time it and see how long it actually takes it is.

Code: Select all

variable(time)
time := microseconds
#... whatever you want to time
time := microseconds -- time
show string(string sprintf(0, $0="Done in %d microseconds", time))
Hint: at 60fps one frame is 16700 microseconds, and at 18.3fps, it's 55000us. So if the time is way under that, its not a problem.

Alternatively, don't use a zone. For checking whether any npc is within X tiles of a certain tile, creating a temporary zone is indirect, slow, and requires more code than just checking it directly. It doesn't really make sense unless you're going to be doing this test hundreds of times per tick.

But clearly we need some more script commands for dealing with zones, like drawing a rectangle, clearing, or copying one to another. And all those could apply to tilemaps too.
Last edited by TMC on Sat Dec 30, 2017 11:27 pm, edited 4 times in total.
Post Reply