Custom java class that deals with GamePieces

I finally got around to gearing up towards (using intellij) custom methods by reading the Vassal programming tutorial and doing a simple “hello world” thing using a java dialog box.

My short term goal is to automate the spawning of an arbitrarily large collection of GamePieces on the map, using a user-input of a script in text form. My method would analyze and decompose that large string and pull up the corresponding tokens in my module and neatly lay them out on the map window, without stacking anything.

I need some pointers as to which class I must use to access the module’s standing collection of pieces and to spawn and move them. I’ve poked around Vengine.jar a bit but couldn’t quickly find what I needed last night. Any help in that regard will help me to dramatically improve the X-Wing module and give us players the squad auto-spawn that we have been dreaming about. I suspect I have to load stuff using the gpid that are defined in the module’s build file? If all goes well, I could dive into straight up programming a rich dialog that could let you squad build what you want with dynamically accessed lists of pilots and upgrades that you need for a squad.

For example, let’s say I want to simply click a toolbar button (that, I can do, following the documentation’s zapwars programming tutorial on Vassal’s website) which would spawn this Piece (that I can’t do) somewhere on the map:

<VASSAL.build.widget.PieceSlot entryName=“Cassian Andor” gpid=“10941” height=“418” width=“300”>+/null/prototype;Observe prototype;Pilot Card\ obs;70,130;Pilot-Rebel_Back.jpg;Flip;P;Destroyed;player:;Peek\ piece;;;Pilot-Cassian_Andor.jpg;Cassian Andor/ \ null;\ null;0;0;10941</VASSAL.build.widget.PieceSlot>

Way #1: manually build a class from the GamePiece interface from scratch, implementing every method that needs it, and painstakingly load every trait, image links, etc that are associated with the GamePiece, execute a move to location command and call it a day

Way #2: use a class.method somewhere in Vengine.jar (where?) which can utilize my Piece’s gpid of value 10941 to clone a copy of it, and then issue a move to location command

Sadly, there is no one simple method to do this, Vassal was not designed with this in mind.

I would suggest looking at the code for a part of Vassal that does something similar - VASSAL.build.module.GameRefresher and VASSAL.build.GpIdChecker.

Rgds.

You’re telling me that we can’t have access to the same methods which are called upon, when a user drags a given piece from the “Pieces” panel and drops it on the map? Or to the ones which are called upon to sweep through the Pieces collection which is displayed when a user browses?

I’m kinda stunned.

Yes, you do have access to the same methods. I’m just saying there isn’t one simple method that does it everything you need in a simple easy call. To find out what those methods are and how to call them, I am suggesting you look at a piece of code that already does it.

The class that does the drag and drop from the Game Palette to the board is PieceMover, but it is hideously complex and I would not suggest starting there.

The two classes I suggested more or less do everything you need to do. GpIDChecker shows you how to locate all of the pieces in the GamePiece palette, how to find their GpId’s and how to create a new piece from a definition with all of the prototypes expanded.

Since you are only concerned about GamePiece palette entries (PieceSlot) and not piece definitions in Markers, you can simplify things. Once you have found the PieceSlot you need with the GpID you are after, you will need to do something like this:

PieceSlot slot = findSlot (gpid);
GamePiece piece = slot.getExpandedPiece();
Point pos = new Point (100, 100);
Command place = map.placeOrMerge(newPiece, pos);

then execute the command.

To find all PieceSlots in the module, use something like this:

PieceSlot findSlot (String myGpId) {
PieceSlot mySlot = null;
for (PieceSlot slot : GameModule.getGameModule().getAllDescendantComponentsOf(PieceSlot.class)) {
if (slot.getGpId().equals(myGpId)) {
mySlot = slot;
break;
}
}
return slot;
}

Hope this helps.
Rgds.

Thanks. It’s a first avenue of work.

I’m reading up on how to properly arrange a wrapper class in order to use your code, since getExpandedPiece() is a protected method in the PieceSlot class and can’t be used as is written in your example.

Failing:

Using the protected PieceSlot.getExpandedPiece() method, even with an empty derived class (I get null pointers unfortunately in my vassal crash report).

I made my own PieceSlotHack class that extends PieceSlot. It’s pretty much empty (not 100% that this is ok, do I have to implement stuff in it?). I made sure it used the same package (VASSAL.build.widget) as PieceSlot and was put in its properly named folder in my IDE. No compilation errors. I used your piece of code for findSlot, but using my PieceSlotHack instead of the default one.

Success:
Access a piece already manually placed on the map with and move it around to a new fixed position:

GamePiece pieces[] = Map.activeMap.getPieces();
pieces[0].setPosition(new Point(300,100));

(although it only refreshes if I click on the map. I’m guessing I’m missing some kind of refresh command)

New successes:

I can spawn stuff on the map! I’m using this piece of code but I’m not sure if I’m following best practices here:

[code]

String listOfPieceSlots = “”;
PieceSlot biggs = new PieceSlot();
GameModule mod = GameModule.getGameModule();

int counter = 1;
for(PieceSlot slot: GameModule.getGameModule().getAllDescendantComponentsOf(PieceSlot.class)) {
listOfPieceSlots += “#:” + Integer.toString(counter) + " gpuId:" +slot.getGpId() + " " + slot.getConfigureName() + “\n”;
if(slot.getGpId().equals(“15”)) {
Point pos = new Point (150, 153);
GamePiece biggsGP = slot.getPiece();

       List<Map> mapList = Map.getMapList();
       biggsGP.setMap(mapList.get(0)); //this will be less clunky in a final version
       biggsGP.setPosition(pos);

       JOptionPane.showMessageDialog(null,biggsGP.getName() + " "
                       + biggsGP.getPosition().toString() + " "
                        + biggsGP.getMap().getMapName(),  "Biggs checks",
               JOptionPane.PLAIN_MESSAGE);

       Command place = mapList.get(0).placeOrMerge(biggsGP,pos); //not sure if the earlier setPosition was enough or useless
       place.execute();
       mod.sendAndLog(place);

       break;
   }
   counter++;
   }

Command c = new
Chatter.DisplayText(mod.getChatter(),listOfPieceSlots); //wanted to see if the detection went well
c.execute();
mod.sendAndLog(c);[/code]

A MILLION THANKS. We did it!

my project has now reached success. With the help of a small group of people, we figured it out and can dynamically tie the X-Wing Vassal module to interpreting online squadron builder standard output (there’s a json standardized format out there that makes every app and websites that deal with squads talk to each other) and auto spawn a squad using the click of a button (and a URL paste).