Proximity-specific behaviour

This is something I’ve often wrestled with, but I’d like to hear how other people handle it.

Situation: a toolbar button results in various pieces all across specific areas on the board doing a thing, unless one type of piece is “on” a specific piece.

Normal solution: the specific piece changes a global property in its CurrentZone and OldZone when moved, every zone the piece could move to has this global property. The various pieces check the global property to determine whether they trigger doing the thing when the toolbar button is pressed.

Complication: the specific piece is larger than the zones it covers, in this case a rectangle that covers two squares.

Potential solution(?): the specific piece calculates Zones to change the global property in, maybe based on CurrentXY and OldXY of specific piece.

Does this work? Will the fact that the specific piece already has a map trigger sendto trait that forces it to always snap into position between two squares confuse the OldX OldY values? Any better/easier solutions?

Just realised you can’t(?) target zones to change global properties in, unless you have trigger pieces in those zones to bounce off from.
Is that how I have to do it? A trigger piece in every zone to change that zone’s GP?

Or different numbered global properties for every zone stored at map level instead of zone level. The XY of the specific piece determines which map-level GPs are changed, and the other pieces would have to check if $CurrentZone$ matched the $GP$ to see if they do the thing?

Just checked, and in 3.5.5, at least, you can target a Set Global Property at a Named Zone, if you want. Not sure why you think you can’t?

Edit: It appears you can’t add a Hotkey to change a Zone-level GP, unlike other GPs, if that was what you meant.

Yup, I just found the same thing. I write when I don’t have access to Vassal, not when I do (sorry).

Now can anyone tell me how to target a zone that is simply one integer greater than the value of CurrentZone?

I would assume either $CurrentZone$ + 1 or {CurrentZone + 1} should work, shouldn’t they?

I figured that would only work if $CurrentZone$ is an integer. Typically I use a capital letter and an integer, or a word and integer. I’ve tried some string commands, but can’t seem to get anything that doesn’t produce an error result.

Assuming CurrentZone is a letter plus an integer, I think {CurrentZone.substring(0,1) + (Integer.parseInt(CurrentZone.substring(1)) + 1)} will work. If CurrentZone is more than a single letter (but always the same number of letters), increase the 1 in both substring() commands to match. If the length of the alphabetical portion of CurrentZone varies, that’s a bit more complicated.

Thanks! I think I get it, but I thought that you need brackets around properties when you want to reference the value of the property?

That would make it:

{(CurrentZone).substring(0,1) + (Integer.parseInt((CurrentZone).substring(1)) + 1)}

I am sure you are right and my assumption is wrong, but I still don’t understand where and when I should be using brackets.

Say the letter is always R for this specific use, I assume I could simplify to:

{“R”+(Integer.parseInt(CurrentZone.substring(1)) + 1)}

Now I just need to figure out when I need +1 and when I need -1, add an if clause, and make another with OldZone, and hope it all hangs together…

I don’t think those extra parentheses are necessary, but they shouldn’t hurt, either–Brent would know for certain.

Bbrackets around a property name operated on by a beanshell function were once required, but no more since sometime in v3.4 releases if I recall correctly.

Thanks.

How can I put a Regular Expression as the “Name of Zone containing property” for a Set Global Property trait?

What I’m trying to do is have the specific piece set a property in all Zones R1?[0-9] to false, before setting two targeted Zones to true. I’ve got the zone targeting down, but not the resetting. I know I can easily just make 36 Set Global Property traits, but I’m sure there must be a more concise way to do it.

The extra parentheses (CurrentZone).substring(0,1) where originally required, by I made a change in 3.4 that allowed java String functions to be used directly on property names CurrentZone.substring(0,1)

Message to self: Read rest of thread before replying.

Not possible. Set Global Property is only designed to set one property at a time.

Thanks. Saved me some time. So I have to create 36 Set Global Property traits?

Less than ideal, but probably yes. I would try and add them to an intermediary control piece that is used for nothing else and avoid adding them to your ‘general play pieces’.

You are getting to the point where you are trying to implement full-blown scripts via the supplied tools. Anything you do is going to be clunky. As a design rule, I would try and pull as much of the clunkiness as possible out into intermediary control pieces that you send messages to via GKC to do the actual work. This will keep your work-a-day pieces as slim as possible.

Gotcha. It’s only one piece, so in this particular case no need for a control.

Should (theoretically) be possible to do it with a single Set Global Property encased in a pair of loops (one for the letter, one for the number). I can probably throw the necessary code together in a few minutes, if you want.

Thanks, but it’s done now, and works fine with +36 traits =)