Jump to content
Sign in to follow this  
Followers 4
Ranger Fox

ZoneMover

Recommended Posts

Wherigo's zones have static positions. This is usually fine because most zones are tied to specific geographic areas. However, there are times when zones and characters need to be on the move. Almost all the examples I can think about involve catching something:

 

Cops and Robbers - A robber is in his getaway vehicle. You have to catch the vehicle before the robbers get away.

Indiana Jones - Remember that scene with the boulder? You're on the trail (you must keep on the trail or you lose) and a boulder comes after you.

FTF competition - Someone is already on his/her way to a cache. You have to get to the cache before that other person. While you can use a timer on this, it's fun to see where the other person is, talk with him/her at any time, and affect that person's progress.

Metal Gear - A game famous for its protagonist sneaking around guards and infiltration missions. You need to have your enemies moving around for the player to know when to time his/her action--and you don't know when the player will move or how many repetitions it will take.

Finding Someone - You might need to find someone walking around a busy park.

 

I have been thinking about this for a while: how can I make some zones imitate real life? I wanted to create a class and structure that would enable anyone to copy my code without knowing how it works and use it in their cartridge. You'd still have to know a little code in order to kick it off, but you most assuredly wouldn't have to know how it works.

 

I have created a first version of what I call the ZoneMover class. Yes, it's as close to OOP lua as I can get, though you have to use a factory method to create an instance. Once copied into a cartridge, all you have to do to get your zone moving is to add something like the following code to your cartridge:

--Array of ZoneMovers, if you want more than one going:
zoneMovers = { nil }

--A list of coordinates to move the zone:
pointsToMove = { CreateZMPoint(ZonePoint(36.07674,-79.80593), 1, 1),
 CreateZMPoint(ZonePoint(36.07670,-79.80473), 10, 1), 
 CreateZMPoint(ZonePoint(36.07764,-79.80464), 10, 1), 
 CreateZMPoint(ZonePoint(36.07751,-79.80224), 20, 1), 
 CreateZMPoint(ZonePoint(36.07408,-79.80254), 10, 1) 
}

--Create the ZoneMover:
zoneMovers[0] = CreateZoneMover(zoneMyZone, pointsToMove)

--Run it:
zoneMovers[0]:Run()

The first section creates an array. I added that to this example just to mention you can have an array of ZoneMovers at your beck and call. As many as you want, running for your entertainment.

 

The second section creates an array of ZMPoint objects (Zone Mover Points). This tells the ZoneMover how and where to move the zone. The arguments are as follows: a ZonePoint for the zone's final location, the number of seconds it will take to move the zone to that location, and the number of seconds the ZoneMover should pause before starting to move the zone to the next location. I'm using a shortcut in lua to make an array of ZMPoint objects. You'll also notice I'm using a method call to create the actual ZMPoint object. This is due to how objects have to be created; I'm saving you some steps by having a factory method like this.

 

The third section of the above code shows you how to instantiate a ZoneMover class. Just as with the ZMPoint object, I'm using a method to create the ZoneMover object. The first argument is the zone I want moved and the other is the array of ZMPoints.

 

The final section tells the ZoneMover to start moving the zone. It's possible to pause and resume the ZoneMover at any time. You can also attach events to each ZMPoint so something could happen when the ZoneMover finishes moving the zone to that point. There's even an event you can have executed when the ZoneMover finishes its work. For instance:

zoneMovers[0].ZMPoints[4].OnComplete = function()
Wherigo.MessageBox{Text=[[I am halfway there!]],}
end

zoneMovers[0].OnComplete = function()
Wherigo.MessageBox{Text=[[Done!]],}
end

 

 

The ZoneMover and Oregons

You'll see a problem if you have a ZoneMover active on an Oregon and your player wants to talk to an NPC. The cartridge will slow to a crawl. Because of this, I don't advise using the ZoneMover if your player will be interacting with characters. You can pause the ZoneMover before the player interacts with a character and it should be fine, though.

 

 

Giving the ZoneMover New Coordinates

Once the ZoneMover has been in operation, I've had odd problems with reissuing it a new array of ZMPoints. I have not had time to look into this. The same goes for a problem when telling the ZoneMover to reverse course after it completes all its moves.

 

 

Implemented Version

I implemented the ZoneMover in the cartridge Sadie's BiG Adventure. I open-sourced it so anyone can see the final version.

 

 

The attachment

There are lots of goodies inside the zip file: you'll find lua code, documentation, versions, a demo, and a Windows application I made. All this was created towards the beginning of February, so I don't know what all else is in there (in fact, I wrote the above post on Feb. 3rd and have been waiting to post it).

 

The GeoJones lua script is a demo. You can run and play around with it.

 

The MS Word document and the versions directory show you how I came up with all this. The document was made as I was creating the ZoneMover and explains what I was trying to do in each version and what I was thinking. I did not clean it up.

 

There's good news for those of you thinking, "Geez, that's a lot of typing if I'm going to get a zone to move to a hundred places!" I'm just as lazy as you. That's why I created a ZoneMover Tracklog program. Load your tracklog into MapSource and copy that table of points into MS Excel and save the file. Run this application and click the button (it's your only choice). It will ask for the MS Excel sheet and it will output some lua code to a file. After that, just copy and paste it into your cartridge. I didn't localize the program, so I don't know how it will work for other date formats.

 

 

Contributions

Anyone is welcome to contribute. Currently, I have other projects that need my attention (and geocache logs to write), so I won't be able to come out with updates to requested features or reported bugs for a little while.

ZoneMover.zip

Share this post


Link to post

RESPECT!

 

I was trying to do something like this, but this is much better and very complex solution! I like Event handling very much.

Thank you for this usefull script!

Share this post


Link to post

OK, I know that this was posted here over 3 years ago, but has anyone got this working with Urwigo?

 

I have entered the main part of the code in to the 'Lua user functions' section (zoneMovers variable and all of the code from 'function CreateZoneMover(zoneToMove, pointsToMove)' to 'end --of ZoneMover:Run'.

 

For the purposes of my test the code to call the function has been placed in the cart's On Start with a bit of Lua code.

 

So when I go to test it I get the cart loading OK but when it starts - OOPS! An Error Occured.... attempt to index local 'zoneToMove' (a nil value)

 

The cart is simply the user being chased by a dragon, and will (if I get it working) be part of a larger cart.

 

I have tried putting the cart.onstart in the 'Lua user functions' but it would not even build, and seeing as I cannot get in to the .lua file to manually see what the cart or zones are referenced as I am not even sure that my zone is being called properly!

 

Am I pushing what Urwigo can do? This is only my 2nd cart and I wanted to try something other than the GS Builder.

 

Thanks in advance for any advice!

Share this post


Link to post

It would help to see your cartridge's code. From what you described, I'd have to wonder whether you are passing a valid reference to one of your zones. It could be Urwigo is naming your zone something different than what you're using to pass to get the Zone Mover started.

 

If you'd rather not share your code or would like to see if you can puzzle it out for your own, you can view and examine the cartridge I developed the Zone Mover for, Sadie's BiG Adventure. Most of my cartridges are open source. I tested it thoroughly with a Garmin Colorado, which was pretty much the only convenient device that played a Wherigo cartridge in those days. The Garmin Oregon, which we all agree is a little underpowered and/or unstable, came out at the same time I published the cartridge. I had a few other zones moving around in the cartridge, but the Oregon couldn't handle the frequency or quantity so I later had to step it down a notch (a lot of testing on site in the pouring rain). Since the GPSr was new, I hadn't had an opportunity to play around with it, nor did I expect a model later than the Colorado would have these problems (instead, I expected an improvement). Unfortunately, one of the locals bought an Oregon and was the first to play the cartridge. He encountered the Oregon's problems and insulted me in his online log. Anyway, the moral of this story is that, while moving zones are a great idea to reflect real life situations, be careful how you implement it and be aware it's rather impossible to test it on all devices up front. And for those playing cartridges, the moral is they should be kind to those spending this amount of time crafting an above-average experience (as opposed to all the park and grabs and power trails I've been finding and doing as of late).

 

October is my busy month, but I'll be around as much as I can to help.

Share this post


Link to post

Well here is the urwigo file (zipped) - I have no worries sharing code, and at this stage I just wanted to test the ZoneMover so there really is nothing in there except for the location.

Unfortunately you cannot output Lua code so I cannot see the name of the zone - which may well be the issue.

I have put a 5 second timer on the start of the cart and the code is fired on the ontick.

 

If the answer is 'use another builder' then let me know - that is a very valid answer!

 

If anyone who knows how Urwigo references zones could chime in it may help...

Dragon Chase Sequence.zip

Share this post


Link to post

Yeah, Urwigo loves to rename your objects. Yes, yes, cheat prevention and etc. I'll hack the mess out of the cartridge regardless--and then play it in the field.

 

Here's what you'll need to do to get this to work:

  1. Select your zone and, in its properties, enter "zoneDragonZone" for its identifier. This will tell Urwigo to use that name and not something else for the zone's name.
  2. In your cartridge's properties, enter "cartDragonChase" for your cartridge's identifier.
  3. Go into the lua user functions and find line 116, where I have the line "Cartridge = cartGeoJones". Change the right side to be your cartridge's identifier (unfortunately, creating a timer requires a reference to your cartridge object).

 

Note that, on the emulator, the zone's proximity event won't register unless David (the Lackey for whom the icon represents, if I remember correctly) is moving. This is true for most proximity events when playing on the emulator. This is typically a non-issue in the field because the GPSr is constantly updating the player's position.

 

I have attached to this post my adjusted version of your cartridge.

Dragon Chase Sequence.zip

Share this post


Link to post

Thank you so much! That just works amazingly well, and now I know how to force Urwigo to name zones correctly!

All hail the Guru of Wherigo!

I will let you know when the finished cart is available so you can see how it all ties in to the story.

Share this post


Link to post

Could do with a bit of coding advice here.

At the end of the zone mover sequence I want a variable to be incresed by one and a non-moving zone to be set to active and to be displayed. the game would also be saved at this point.

 

what needs to be added to the code to make this work?

Lets call the variable "Variableone" and the non-moving zone "VariableZone"

 

zoneMovers[0].OnComplete = function()
  Wherigo.MessageBox{Text=[[it got away ]],}
end
zoneMovers[0].reverseOnComplete = false
zoneMovers[0]:Run()

 

The idea behind it is that should the player fail to "catch" the zone then they must complete a simple forfit, which involves staying in a pre-defined zone for a set period of time.

 

Edit:

Figured the above out, just need to work out how to stop the zone move when in proximity.

 

Also, in the sequence What do the numbers I've highlighted represent? "CreateZMPoint(ZonePoint(53.761145,-0.808654), 2, 0)"

Edited by Ant89

Share this post


Link to post

The first number is the duration. This represents how long it will take the zone to go from one ZMPoint to the next. Thus, if you have two points 30 meters / 100 feet apart and the duration is 10, the ZoneMover will move your zone at a speed of 3m/10ft per second until the zone arrives at the next ZMPoint.

 

The second number is the pause value (also in seconds). Once a zone reaches a ZMPoint, you can tell the ZoneMover to keep the zone at that point for a specified amount of time. Once the time elapses, it will begin moving the zone to the next ZMPoint.

Share this post


Link to post

The first number is the duration. This represents how long it will take the zone to go from one ZMPoint to the next. Thus, if you have two points 30 meters / 100 feet apart and the duration is 10, the ZoneMover will move your zone at a speed of 3m/10ft per second until the zone arrives at the next ZMPoint.

 

The second number is the pause value (also in seconds). Once a zone reaches a ZMPoint, you can tell the ZoneMover to keep the zone at that point for a specified amount of time. Once the time elapses, it will begin moving the zone to the next ZMPoint.

Thanks! That makes things easier!

Share this post


Link to post

The first number is the duration. This represents how long it will take the zone to go from one ZMPoint to the next. Thus, if you have two points 30 meters / 100 feet apart and the duration is 10, the ZoneMover will move your zone at a speed of 3m/10ft per second until the zone arrives at the next ZMPoint.

 

The second number is the pause value (also in seconds). Once a zone reaches a ZMPoint, you can tell the ZoneMover to keep the zone at that point for a specified amount of time. Once the time elapses, it will begin moving the zone to the next ZMPoint.

Thanks! That makes things easier!

 

Well I tried it, got it working in the emulator but it kept crashing on device :( so, have opted for a very crude version which does work using multiple zones and timers.

Share this post


Link to post

Which device are you using to test the code? If it's anything but a Garmin Oregon, I might have to take a look at it to see if there's an incompatibility with that particular Wherigo Player.

Share this post


Link to post

I'm using the android whereyougo app. I can copy what the error message says here if that may be of use.

Share this post


Link to post

Please do. I have an iPhone, so it'll be problematic to test this. First and foremost, I have to figure out if it's a problem with the WhereYouGo or my script. If the former, I am entitled to a little grumbling and complaining off the forum, then I'll have to figure out how to get around the problem. If the latter, I just need to make sure the fix will still work in all Wherigo Players.

Share this post


Link to post

I've been trying to set the Zone Mover to work. With Indy's boulder I didn't get it (I'm 0(zero) with writing scripts) but wiht the Dragon was easy. I just changed the coordinates bit by bit, names bit by bit and managed to put the zones changing, pausing and even resuming!

 

Now I need to add some code at the end of the zone movement and I need help on how to do that. Once done I'll handle it within Urwigo.

When the zone ends the move I need to set active the other zone there's in the cartridge. Once I get that I can continue the program.

 

Another question:

If I need to add a second zone to move I only have to copy the "triggering Lua User code" (the pink thing) changing the zoneName or I have to add some identification to the ZoneMover command? Or something else?

 

Thanks in advance

Dalek002.zip

Share this post


Link to post

Just got my hands on an iPhone, and wanted to pick up a half-finished Wherigo project with moving zones. Unfortunately, the iOS Wherigo app doesn't seem to support the setmetatable statement. At least: it gives a popup saying 'setmetatable - Not implemented!'

 

Is there any way to circumvent this issue?

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
Followers 4

×