Is the Attachment Trait the answer?

I have a single cavalry unit that when dismounted is represented by two units. I am using the Replace with Other trait to put the first counter on the map and then a Place Marker trait to place the second counter when the dismount command is sent. This works well.

In order for the dismounted units to remount they must be in the same hex. There doesn’t seem to be an easy way to test for this. Essentially I want to test if dismount1 is in the same hex as dismount2 and if they are not then disable the mount menu command.

I am wondering if the Attachment trait might be the answer here but I am unsure how to implement it. If I can work out the same hex test I think I can use a Trigger Action to run a Replace with Other trait on dismount1 then a delete command to remove dismount2.

Any help will be greatly appreciated.

Mike

The Attachment trait could indeed help you here, and might be the most efficent way to do this. You make sure that dismount1 and dismount2 have the same Attachment name - say the name of the mounted unit - say mounted.

To check if the two attached pieces are in the same location (hex), you can use the comparison

LocationName == mounted_LocationName

You can also use the Range(attachment) BeanShell function to check that the distance between the two dismountX units is zero, as in

Range("mounted")==0

If you detect, say in a Trigger Action trait that the two dismountX units are in the same location, then you can use a Global Key Command with Current Attachments Location filter to remove the other counter, or similar. You can also use the Property filter with

LocationName == "$LocationName$"

and then you probably do not need the Trigger Action trait at all. Note, you need the quotes around $LocationName$, because $...$ properties in BeanShell expressions are textually replaced before the expression is evaluated. So if the sending piece has the location A1, then the above expression becomes

LocationName == "A1"

Without the quotes, it would be

LocationName == A1

which would be a comparison between the values of the properties LocationName and A1 in the destination piece. Note also, if you LocationName properties are strictly numerical, and never has leading 0s, then you probably do not need the quotes. If LocationName is numerical, but with leading ‘0’, then you may need to do

GetString("LocationName") == "$LocationName$"

to coerce the destination LocationName to be evaluated as a string.

In fact, you can avoid the Attachment trait all together by a similar idiom. Suppose both dismountX have the same property - say Mounted (f.ex. defined via a Marker trait), and they both have the same value for that property - say "mounted". Then you can use a Global Key Command with a Location filter of

{"$LocationName$"}

and a property filter of

Mounted == "$Mounted$"

and possibly a restricted range of 0.

However, there might be a performance difference between the two options (using an Attachment trait with a Global Key Command trait, versus just using a Global Key Command trait). Attachments are stored in memory by Vassal, meaning when a piece sends commands or queries its attachements, then Vassal does not need to go look for the attached pieces - its there directly. Without the attachment, then Vassal would need to query all pieces on the map to see if they fulfill the requirements.

That said, I would recommend that you test the different approaches and see what works best for you. The second approach can be more attractive if you want to define this behaviour in a Prototype. The Attachment trait would have to be defined for each individual piece. On the other hand, Attachment traits allow you to send commands between the pieces in an effective fashion.

Sometimes it is really helpful if you can provide a link to the module in question, so that others may see for themselves what it is you are doing and want in the proper context.

Remember to mark the solution to your problem - which isn’t necessarily this one :smile:. It really helps others find the solution to their problems. Only you, @sfcmikej, as OP can do that.

Yours,
Christian

Christian,

Thank you for your thoughtful reply. Your post led me to the Property Functions Page that had the solution.

Working through this I realized there was a unit that had three dismounted units instead of just two. This made it a bit more complicated. I created a Trigger Action and used the GetAttachProperty(attach, prop, index) function to test both pieces against the location of the initiating piece. Here is the expression I used: {$LocationName$ == GetAttachProperty("1Cherokeeb","LocationName",1) && $LocationName$ == GetAttachProperty("1Cherokeeb","LocationName",2)}

This is all done at the individual piece level and not in a Prototype as there are only four pieces that have this behavior.

If all three units are in the same hex then the Mount command works, otherwise it is grayed out. I did use a Global Key Command using the Fast Match to limit the effect by location to the Current Attachments.

The Trigger Action runs the Global Key Command that deletes the attached pieces then runs the Replace With Other command to swap the initiating piece for the mounted piece.

Some interesting notes; I found that the Index starts at 1 and not 0 as I first expected, and if the Index is not found then there is no out if bounds error.

As I have it now there are some limitations. On the 3 dismount units, my logic fails if one of the 3 has been eliminated. It also doesn’t take into consideration ammo, out of command, or disordered status when recombining. It also does not take into account any reduced strength of the parent mounted unit or the dismounted units when dismounting or mounting. The first issue, where one of the three has been eliminated can be solved with a few more Trigger Actions using the AttachCount property to determine how many attachments are present and set the Index accordingly. The other issues I think may be more difficult.

One of the difficulties I faced when trying to figure this out are the syntax variations. When do I use quotes, dollar signs, curly braces and parenthesis. This is an experience issue and I am wondering if there may be a reference that I have missed that outlines these differences. I find it frustrating when my logic should work but a lack of some symbol stops it from executing correctly.

Thanks again Christian for the help.

Mike