1414import com .bobsgame .puzzle .Piece ;
1515import com .bobsgame .puzzle .PieceType ;
1616
17+ import java .io .ByteArrayInputStream ;
18+ import java .io .ByteArrayOutputStream ;
19+ import java .io .ObjectInputStream ;
20+ import java .io .ObjectOutputStream ;
21+
1722public class CustomGameEditor extends Scene2DPanel {
1823 private final Table mainTable ;
24+ private final TextButton saveSlot1Btn ;
25+ private final TextButton loadSlot1Btn ;
26+ private final TextButton saveSlot2Btn ;
27+ private final TextButton loadSlot2Btn ;
28+ private final TextButton saveSlot3Btn ;
29+ private final TextButton loadSlot3Btn ;
1930 private final TextButton addPieceBtn ;
2031 private final TextButton duplicatePieceBtn ;
2132 private final TextButton removePieceBtn ;
@@ -50,7 +61,8 @@ public class CustomGameEditor extends Scene2DPanel {
5061 private final CheckBox flip180Checkbox ;
5162 private final CheckBox floorKickCheckbox ;
5263
53- private final GameType currentGameType = new GameType ();
64+ private GameType currentGameType = new GameType ();
65+ private final GameType [] presetSlots = new GameType [3 ];
5466 private int selectedPieceIndex = -1 ;
5567 private int selectedRotationIndex = 0 ;
5668
@@ -89,6 +101,12 @@ public CustomGameEditor(Engine engine) {
89101 hintLabel .setWrap (true );
90102 summaryLabel .setWrap (true );
91103
104+ saveSlot1Btn = new TextButton ("Save Slot 1" , skin );
105+ loadSlot1Btn = new TextButton ("Load Slot 1" , skin );
106+ saveSlot2Btn = new TextButton ("Save Slot 2" , skin );
107+ loadSlot2Btn = new TextButton ("Load Slot 2" , skin );
108+ saveSlot3Btn = new TextButton ("Save Slot 3" , skin );
109+ loadSlot3Btn = new TextButton ("Load Slot 3" , skin );
92110 addPieceBtn = new TextButton ("Add Piece Type" , skin );
93111 duplicatePieceBtn = new TextButton ("Duplicate Piece" , skin );
94112 removePieceBtn = new TextButton ("Remove Piece" , skin );
@@ -101,6 +119,15 @@ public CustomGameEditor(Engine engine) {
101119 nextRotationBtn = new TextButton ("Rot >" , skin );
102120 clearRotationBtn = new TextButton ("Clear Rotation" , skin );
103121
122+ Table presetRow = new Table ();
123+ presetRow .defaults ().pad (4 );
124+ presetRow .add (saveSlot1Btn );
125+ presetRow .add (loadSlot1Btn );
126+ presetRow .add (saveSlot2Btn );
127+ presetRow .add (loadSlot2Btn );
128+ presetRow .add (saveSlot3Btn );
129+ presetRow .add (loadSlot3Btn );
130+
104131 Table controlsRow1 = new Table ();
105132 controlsRow1 .defaults ().pad (4 );
106133 controlsRow1 .add (addPieceBtn );
@@ -155,6 +182,43 @@ public void clicked(InputEvent event, float x, float y) {
155182 gridTable .row ();
156183 }
157184
185+ saveSlot1Btn .addListener (new ClickListener () {
186+ @ Override
187+ public void clicked (InputEvent event , float x , float y ) {
188+ savePresetSlot (0 );
189+ }
190+ });
191+ loadSlot1Btn .addListener (new ClickListener () {
192+ @ Override
193+ public void clicked (InputEvent event , float x , float y ) {
194+ loadPresetSlot (0 );
195+ }
196+ });
197+ saveSlot2Btn .addListener (new ClickListener () {
198+ @ Override
199+ public void clicked (InputEvent event , float x , float y ) {
200+ savePresetSlot (1 );
201+ }
202+ });
203+ loadSlot2Btn .addListener (new ClickListener () {
204+ @ Override
205+ public void clicked (InputEvent event , float x , float y ) {
206+ loadPresetSlot (1 );
207+ }
208+ });
209+ saveSlot3Btn .addListener (new ClickListener () {
210+ @ Override
211+ public void clicked (InputEvent event , float x , float y ) {
212+ savePresetSlot (2 );
213+ }
214+ });
215+ loadSlot3Btn .addListener (new ClickListener () {
216+ @ Override
217+ public void clicked (InputEvent event , float x , float y ) {
218+ loadPresetSlot (2 );
219+ }
220+ });
221+
158222 addPieceBtn .addListener (new ClickListener () {
159223 @ Override
160224 public void clicked (InputEvent event , float x , float y ) {
@@ -258,6 +322,7 @@ public void clicked(InputEvent event, float x, float y) {
258322 mainTable .defaults ().left ().padBottom (8 );
259323 mainTable .add (titleLabel ).left ().row ();
260324 mainTable .add (hintLabel ).width (520 ).left ().row ();
325+ mainTable .add (presetRow ).left ().row ();
261326 mainTable .add (controlsRow1 ).left ().row ();
262327 mainTable .add (controlsRow2 ).left ().row ();
263328 mainTable .add (advancedRulesTable ).left ().row ();
@@ -294,6 +359,36 @@ private void addRotation() {
294359 refreshEditorState ();
295360 }
296361
362+ private GameType deepCloneGameType (GameType source ) {
363+ try {
364+ ByteArrayOutputStream bos = new ByteArrayOutputStream ();
365+ ObjectOutputStream out = new ObjectOutputStream (bos );
366+ out .writeObject (source );
367+ out .flush ();
368+ ObjectInputStream in = new ObjectInputStream (new ByteArrayInputStream (bos .toByteArray ()));
369+ return (GameType ) in .readObject ();
370+ } catch (Exception e ) {
371+ throw new RuntimeException ("Failed to clone GameType preset" , e );
372+ }
373+ }
374+
375+ private void savePresetSlot (int slotIndex ) {
376+ applyRuleCheckboxes ();
377+ presetSlots [slotIndex ] = deepCloneGameType (currentGameType );
378+ summaryLabel .setText ("Saved current ruleset to preset slot " + (slotIndex + 1 ));
379+ }
380+
381+ private void loadPresetSlot (int slotIndex ) {
382+ if (presetSlots [slotIndex ] == null ) {
383+ summaryLabel .setText ("Preset slot " + (slotIndex + 1 ) + " is empty." );
384+ return ;
385+ }
386+ currentGameType = deepCloneGameType (presetSlots [slotIndex ]);
387+ selectedPieceIndex = currentGameType .pieceTypes .isEmpty () ? -1 : 0 ;
388+ selectedRotationIndex = 0 ;
389+ refreshEditorState ();
390+ }
391+
297392 private Piece .Rotation cloneRotation (Piece .Rotation source ) {
298393 Piece .Rotation clone = new Piece .Rotation ();
299394 for (Piece .BlockOffset offset : source .blockOffsets ) {
0 commit comments