Skip to content

Commit 0612745

Browse files
committed
MP fense ownership and resource monitor by server
1 parent 2084dd8 commit 0612745

10 files changed

Lines changed: 171 additions & 20 deletions

src/main/java/wagemaker/uk/fence/FenceBuildingManager.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,25 @@ public class FenceBuildingManager {
7777
/** Flag to disable direct mouse input when targeting system is handling input */
7878
private boolean disableDirectMouseInput = false;
7979

80+
/** Player reference for ownership tracking */
81+
private final wagemaker.uk.player.Player player;
82+
8083
/**
8184
* Creates a new FenceBuildingManager with the specified dependencies.
8285
*
8386
* @param structureManager Manager for fence structure data
8487
* @param validator Validator for placement operations
8588
* @param camera Camera for input coordinate conversion
89+
* @param player The player instance for ownership tracking
8690
*/
8791
public FenceBuildingManager(FenceStructureManager structureManager,
8892
FencePlacementValidator validator,
89-
OrthographicCamera camera) {
93+
OrthographicCamera camera,
94+
wagemaker.uk.player.Player player) {
9095
this.structureManager = structureManager;
9196
this.validator = validator;
9297
this.camera = camera;
98+
this.player = player;
9399
this.buildingModeActive = false;
94100
this.selectedMaterialType = FenceMaterialType.WOOD; // Default material
95101
this.lastProcessedGridPos = null;
@@ -109,6 +115,15 @@ public FenceBuildingManager(FenceStructureManager structureManager,
109115
// Visual effects manager will be set externally since it requires ShapeRenderer
110116
}
111117

118+
/**
119+
* Gets the player instance associated with this manager.
120+
*
121+
* @return The player instance
122+
*/
123+
public wagemaker.uk.player.Player getPlayer() {
124+
return player;
125+
}
126+
112127
/**
113128
* Updates the fence building manager, processing input and managing state.
114129
* Should be called every frame when the game is active.
@@ -373,9 +388,15 @@ private void processBuildingInput() {
373388
public boolean placeFenceSegment(int gridX, int gridY) {
374389
Point gridPos = new Point(gridX, gridY);
375390

391+
String playerId = player.getPlayerId();
392+
// Fallback for single player or during initialization
393+
if (playerId == null) {
394+
playerId = "local_player";
395+
}
396+
376397
// Validate placement with comprehensive error handling
377398
FencePlacementValidator.ValidationResult result =
378-
validator.validatePlacement(gridPos, selectedMaterialType, "local_player");
399+
validator.validatePlacement(gridPos, selectedMaterialType, playerId);
379400

380401
if (!result.isValid()) {
381402
// Provide detailed error feedback to the user
@@ -392,9 +413,9 @@ public boolean placeFenceSegment(int gridX, int gridY) {
392413
}
393414

394415
try {
395-
System.out.println("[FenceBuildingManager] Attempting to place fence at grid (" + gridPos.x + ", " + gridPos.y + ") with material " + selectedMaterialType);
416+
System.out.println("[FenceBuildingManager] Attempting to place fence at grid (" + gridPos.x + ", " + gridPos.y + ") with material " + selectedMaterialType + " for owner " + playerId);
396417
// Attempt to place the fence piece with automatic piece type selection
397-
FencePiece placedPiece = structureManager.addFencePiece(gridPos, selectedMaterialType);
418+
FencePiece placedPiece = structureManager.addFencePiece(gridPos, selectedMaterialType, playerId);
398419

399420
if (placedPiece != null) {
400421
System.out.println("[FenceBuildingManager] Fence piece created: " + placedPiece.getType() + " at world (" + placedPiece.getX() + ", " + placedPiece.getY() + ")");
@@ -492,9 +513,15 @@ private void displayPlacementSuccess(FencePiece placedPiece, Point gridPos) {
492513
public boolean removeFenceSegment(int gridX, int gridY) {
493514
Point gridPos = new Point(gridX, gridY);
494515

516+
String playerId = player.getPlayerId();
517+
// Fallback for single player or during initialization
518+
if (playerId == null) {
519+
playerId = "local_player";
520+
}
521+
495522
// Validate removal with comprehensive error handling
496523
FencePlacementValidator.ValidationResult result =
497-
validator.validateRemoval(gridPos, "local_player");
524+
validator.validateRemoval(gridPos, playerId);
498525

499526
if (!result.isValid()) {
500527
displayRemovalError(result.getErrorMessage(), gridPos);

src/main/java/wagemaker/uk/fence/FenceEnclosureData.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public FenceEnclosureData(Rectangle bounds, FenceMaterialType materialType,
5454

5555
// Convert fence pieces to serializable data
5656
for (FencePiece piece : pieces) {
57-
pieceData.add(new FencePieceData(piece.getX(), piece.getY(), piece.getType()));
57+
pieceData.add(new FencePieceData(piece.getX(), piece.getY(), piece.getType(), piece.getOwnerId()));
5858
}
5959
}
6060

@@ -68,7 +68,7 @@ public FenceEnclosure toFenceEnclosure() {
6868

6969
// Recreate fence pieces from data
7070
for (FencePieceData data : pieceData) {
71-
FencePiece piece = FencePieceFactory.createPiece(data.type, data.x, data.y);
71+
FencePiece piece = FencePieceFactory.createPiece(data.type, data.x, data.y, data.ownerId);
7272
pieces.add(piece);
7373
}
7474

@@ -121,6 +121,7 @@ public static class FencePieceData implements Serializable {
121121

122122
public float x, y;
123123
public FencePieceType type;
124+
public String ownerId;
124125

125126
/**
126127
* Default constructor for serialization.
@@ -135,9 +136,22 @@ public FencePieceData() {}
135136
* @param type Fence piece type
136137
*/
137138
public FencePieceData(float x, float y, FencePieceType type) {
139+
this(x, y, type, null);
140+
}
141+
142+
/**
143+
* Creates fence piece data with owner.
144+
*
145+
* @param x World X coordinate
146+
* @param y World Y coordinate
147+
* @param type Fence piece type
148+
* @param ownerId Owner ID
149+
*/
150+
public FencePieceData(float x, float y, FencePieceType type, String ownerId) {
138151
this.x = x;
139152
this.y = y;
140153
this.type = type;
154+
this.ownerId = ownerId;
141155
}
142156

143157
/**

src/main/java/wagemaker/uk/fence/FencePersistenceManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public static int deserializeFenceStructures(List<FenceEnclosureData> serialized
129129

130130
// Create and place the fence piece
131131
try {
132-
FencePiece piece = FencePieceFactory.createPiece(pieceData.type, pieceData.x, pieceData.y);
132+
FencePiece piece = FencePieceFactory.createPiece(pieceData.type, pieceData.x, pieceData.y, pieceData.ownerId);
133133

134134
// Create the fence piece and add it for restoration
135135
boolean added = structureManager.addFencePieceForRestore(gridPos, piece);

src/main/java/wagemaker/uk/fence/FencePiece.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,30 @@ public abstract class FencePiece {
1818
protected static final int PIECE_SIZE = 64; // 64x64 pixel pieces
1919
protected static final String TEXTURE_PATH = "textures/fense.png";
2020

21+
protected String ownerId;
22+
2123
/**
2224
* Creates a new fence piece at the specified position.
2325
* @param x World X coordinate
2426
* @param y World Y coordinate
2527
* @param type The type of fence piece
2628
*/
2729
public FencePiece(float x, float y, FencePieceType type) {
30+
this(x, y, type, null);
31+
}
32+
33+
/**
34+
* Creates a new fence piece at the specified position with ownership.
35+
* @param x World X coordinate
36+
* @param y World Y coordinate
37+
* @param type The type of fence piece
38+
* @param ownerId The ID of the owner of this fence piece
39+
*/
40+
public FencePiece(float x, float y, FencePieceType type, String ownerId) {
2841
this.x = x;
2942
this.y = y;
3043
this.type = type;
44+
this.ownerId = ownerId;
3145
loadTexture();
3246
}
3347

@@ -142,6 +156,22 @@ public Texture getTexture() {
142156
return texture;
143157
}
144158

159+
/**
160+
* Gets the owner ID of this fence piece.
161+
* @return Owner ID, or null if not set
162+
*/
163+
public String getOwnerId() {
164+
return ownerId;
165+
}
166+
167+
/**
168+
* Sets the owner ID of this fence piece.
169+
* @param ownerId New owner ID
170+
*/
171+
public void setOwnerId(String ownerId) {
172+
this.ownerId = ownerId;
173+
}
174+
145175
/**
146176
* Disposes of the texture resources used by this fence piece.
147177
* Should be called when the fence piece is no longer needed.

src/main/java/wagemaker/uk/fence/FencePieceFactory.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ public static FencePiece createPiece(FencePieceType type, float x, float y) {
4242
throw new IllegalArgumentException("Unknown fence piece type: " + type);
4343
}
4444
}
45+
46+
/**
47+
* Creates a fence piece of the specified type at the given position with ownership.
48+
* @param type The type of fence piece to create
49+
* @param x World X coordinate
50+
* @param y World Y coordinate
51+
* @param ownerId The ID of the owner
52+
* @return A new FencePiece instance of the specified type
53+
*/
54+
public static FencePiece createPiece(FencePieceType type, float x, float y, String ownerId) {
55+
FencePiece piece = createPiece(type, x, y);
56+
piece.setOwnerId(ownerId);
57+
return piece;
58+
}
4559

4660
/**
4761
* Gets the sequence of fence piece types needed for a rectangular enclosure.

src/main/java/wagemaker/uk/fence/FencePlacementValidator.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,17 @@ private ValidationResult validateRemovalOwnership(Point gridPos, String playerId
180180
}
181181

182182
// Check if the piece belongs to the player
183-
// For now, we'll allow all removals - in a full implementation,
184-
// we'd check the piece's owner against the playerId
185-
// This is a placeholder for future ownership tracking
183+
String pieceOwner = piece.getOwnerId();
184+
185+
// If piece has no owner, allow removal (or could be restricted based on game rules)
186+
if (pieceOwner == null) {
187+
return ValidationResult.valid();
188+
}
189+
190+
// Check if the requesting player is the owner
191+
if (!pieceOwner.equals(playerId)) {
192+
return ValidationResult.invalid("You cannot remove this fence because you do not own it");
193+
}
186194

187195
return ValidationResult.valid();
188196
}

src/main/java/wagemaker/uk/fence/FenceStructureManager.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ public FenceStructureManager(FenceGrid grid) {
5454
"manager_" + System.identityHashCode(this), this);
5555
}
5656

57+
/**
58+
* Adds a fence piece at the specified grid position.
59+
* Automatically determines the correct piece type based on adjacent pieces.
60+
* Updates connections with adjacent pieces.
61+
*
62+
* @param gridPos Grid position where to place the fence piece
63+
* @param materialType Type of material to use for the fence piece
64+
* @return The created FencePiece, or null if placement failed
65+
* @throws IllegalArgumentException if the position is already occupied
66+
*/
5767
/**
5868
* Adds a fence piece at the specified grid position.
5969
* Automatically determines the correct piece type based on adjacent pieces.
@@ -65,6 +75,21 @@ public FenceStructureManager(FenceGrid grid) {
6575
* @throws IllegalArgumentException if the position is already occupied
6676
*/
6777
public FencePiece addFencePiece(Point gridPos, FenceMaterialType materialType) {
78+
return addFencePiece(gridPos, materialType, null);
79+
}
80+
81+
/**
82+
* Adds a fence piece at the specified grid position with ownership.
83+
* Automatically determines the correct piece type based on adjacent pieces.
84+
* Updates connections with adjacent pieces.
85+
*
86+
* @param gridPos Grid position where to place the fence piece
87+
* @param materialType Type of material to use for the fence piece
88+
* @param ownerId ID of the player who owns this fence piece
89+
* @return The created FencePiece, or null if placement failed
90+
* @throws IllegalArgumentException if the position is already occupied
91+
*/
92+
public FencePiece addFencePiece(Point gridPos, FenceMaterialType materialType, String ownerId) {
6893
if (placedFences.containsKey(gridPos)) {
6994
throw new IllegalArgumentException("Position " + gridPos + " is already occupied");
7095
}
@@ -81,7 +106,7 @@ public FencePiece addFencePiece(Point gridPos, FenceMaterialType materialType) {
81106
com.badlogic.gdx.math.Vector2 worldPos = grid.gridToWorld(gridPos);
82107

83108
// Create the fence piece
84-
FencePiece piece = FencePieceFactory.createPiece(pieceType, worldPos.x, worldPos.y);
109+
FencePiece piece = FencePieceFactory.createPiece(pieceType, worldPos.x, worldPos.y, ownerId);
85110

86111
// Add to our data structures
87112
placedFences.put(new Point(gridPos.x, gridPos.y), piece);
@@ -291,9 +316,9 @@ private void replacePieceType(Point gridPos, FencePieceType newType) {
291316
return; // Nothing to replace
292317
}
293318

294-
// Create new piece with the same position
319+
// Create new piece with the same position and owner
295320
com.badlogic.gdx.math.Vector2 worldPos = grid.gridToWorld(gridPos);
296-
FencePiece newPiece = FencePieceFactory.createPiece(newType, worldPos.x, worldPos.y);
321+
FencePiece newPiece = FencePieceFactory.createPiece(newType, worldPos.x, worldPos.y, oldPiece.getOwnerId());
297322

298323
// Replace in the map
299324
placedFences.put(gridPos, newPiece);
@@ -427,7 +452,13 @@ private void createEnclosure(Set<Point> positions, Rectangle bounds) {
427452
}
428453
}
429454

430-
FenceEnclosure enclosure = new FenceEnclosure(bounds, pieces, FenceMaterialType.WOOD);
455+
String ownerId = null;
456+
if (!pieces.isEmpty()) {
457+
ownerId = pieces.get(0).getOwnerId();
458+
// Verify all pieces have the same owner? Optional but good practice.
459+
}
460+
461+
FenceEnclosure enclosure = new FenceEnclosure(bounds, pieces, FenceMaterialType.WOOD, ownerId);
431462
enclosures.add(enclosure);
432463
}
433464

src/main/java/wagemaker/uk/gdx/MyGdxGame.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ public void create() {
460460
FenceMaterialProvider fenceMaterialProvider = new InventoryFenceMaterialProvider(inventoryManager);
461461
FencePlacementValidator fencePlacementValidator = new FencePlacementValidator(fenceGrid, fenceMaterialProvider, fenceStructureManager);
462462

463-
fenceBuildingManager = new FenceBuildingManager(fenceStructureManager, fencePlacementValidator, camera);
463+
fenceBuildingManager = new FenceBuildingManager(fenceStructureManager, fencePlacementValidator, camera, player);
464464
fenceWorldIntegration = new FenceWorldIntegration();
465465
fenceWorldIntegration.setBuildingManager(fenceBuildingManager);
466466

@@ -2050,6 +2050,11 @@ public void startMultiplayerHost() throws Exception {
20502050
gameClient.setMessageHandler(new GameMessageHandler(this));
20512051
gameClient.connect("localhost", 25565);
20522052

2053+
// Enable fence ownership validation for multiplayer
2054+
if (fenceBuildingManager != null) {
2055+
fenceBuildingManager.getValidator().setOwnershipValidationEnabled(true);
2056+
}
2057+
20532058
// Set game mode to host
20542059
gameMode = GameMode.MULTIPLAYER_HOST;
20552060

@@ -2137,6 +2142,11 @@ public void joinMultiplayerServer(String serverAddress, int port) throws Excepti
21372142
gameClient.setMessageHandler(new GameMessageHandler(this));
21382143
gameClient.connect(serverAddress, port);
21392144

2145+
// Enable fence ownership validation for multiplayer
2146+
if (fenceBuildingManager != null) {
2147+
fenceBuildingManager.getValidator().setOwnershipValidationEnabled(true);
2148+
}
2149+
21402150
// Set game mode to client
21412151
gameMode = GameMode.MULTIPLAYER_CLIENT;
21422152

@@ -3244,8 +3254,13 @@ public void disconnectFromMultiplayer() {
32443254
inventoryManager.setMultiplayerMode(false);
32453255
}
32463256

3247-
// Reset world seed to 0 for singleplayer
3248-
worldSeed = 0;
3257+
// Disable fence ownership validation for single player
3258+
if (fenceBuildingManager != null) {
3259+
fenceBuildingManager.getValidator().setOwnershipValidationEnabled(false);
3260+
}
3261+
3262+
// Reset world seed to 0 for singleplayer
3263+
worldSeed = 0;
32493264

32503265
// Clear rain zones (dynamic rain manager will handle rain events)
32513266
if (rainSystem != null) {

src/main/java/wagemaker/uk/network/ClientConnection.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,9 @@ private void handleItemPickup(ItemPickupMessage message) {
955955
case FRONT_FENCE:
956956
playerState.setFrontFenceCount(playerState.getFrontFenceCount() + 1);
957957
break;
958+
case BACK_FENCE:
959+
playerState.setBackFenceCount(playerState.getBackFenceCount() + 1);
960+
break;
958961
}
959962

960963
// Update player state in world

src/main/java/wagemaker/uk/targeting/FenceTargetValidator.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,18 @@ public boolean isValidTarget(float targetX, float targetY) {
4747
// Get the selected material type
4848
FenceMaterialType materialType = fenceBuildingManager.getSelectedMaterialType();
4949

50-
// Validate the placement (use empty player ID for single player)
50+
// Get player ID for ownership validation
51+
String playerId = "local_player";
52+
if (fenceBuildingManager.getPlayer() != null) {
53+
String id = fenceBuildingManager.getPlayer().getPlayerId();
54+
if (id != null) {
55+
playerId = id;
56+
}
57+
}
58+
59+
// Validate the placement
5160
FencePlacementValidator.ValidationResult result =
52-
validator.validatePlacement(gridPos, materialType, "");
61+
validator.validatePlacement(gridPos, materialType, playerId);
5362

5463
return result.isValid();
5564
}

0 commit comments

Comments
 (0)