Skip to content

Commit 96dd1aa

Browse files
committed
fense creation continuos with additional bugs
1 parent 18c2977 commit 96dd1aa

12 files changed

Lines changed: 348 additions & 69 deletions

ISSUES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- unable to create more than 1 closed fense
2+
- collision detection on the inside now very good
3+
- "c" clear not only the fence in the visable space from the place it clear everything
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== BIOME DISTRIBUTION MEASUREMENT ===
2+
Sample size: 50000
3+
Current thresholds:
4+
- WATER_NOISE_THRESHOLD: 0.53
5+
- Sand threshold (hardcoded): 0.50
6+
7+
=== RESULTS ===
8+
Grass: 39671 (79.34%)
9+
Sand: 5135 (10.27%)
10+
Water: 5194 (10.39%)
11+
12+
=== DEVIATION FROM TARGET ===
13+
Grass: +29.34%
14+
Sand: -24.73%
15+
Water: -4.61%

docs/fence_texture_grid_analysis.md

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,106 @@ Texture Grid Layout (192x192):
1616
├─────────────┼─────────────┼─────────────┤
1717
│ (0,64) │ (64,64) │ (128,64) │
1818
│ 64x64 │ 64x64 │ 64x64 │
19-
BOTTOM-LEFT │ EMPTY? │ RIGHT-EDGE │
20-
│ Index 3 │ - │ Index 6
19+
LEFT-EDGE │ EMPTY? │ RIGHT-EDGE │
20+
│ Index 3 │ - │ Index 4
2121
├─────────────┼─────────────┼─────────────┤
2222
│ (0,128) │ (64,128) │ (128,128) │
2323
│ 64x64 │ 64x64 │ 64x64 │
24-
LEFT-EDGE │BOTTOM-MIDDLE│BOTTOM-RIGHT │
25-
│ Index 4 │ Index 5 │ Index 7 │
24+
BOTTOM-LEFT │BOTTOM-MIDDLE│BOTTOM-RIGHT │
25+
│ Index 5 │ Index 6 │ Index 7 │
2626
└─────────────┴─────────────┴─────────────┘
2727
```
2828

29-
## FINAL WORKING FencePieceType Mapping:
30-
- Index 0: FENCE_BACK_LEFT → (0, 0) → "Top-left corner piece" ✅ WORKING
31-
- Index 1: FENCE_BACK → (64, 0) → "Top edge piece" ✅ WORKING
32-
- Index 2: FENCE_BACK_RIGHT → (128, 0) → "Top-right corner piece" ✅ WORKING
33-
- Index 3: FENCE_FRONT_LEFT → (0, 64) → "Bottom-left corner piece" ✅ WORKING
34-
- Index 4: FENCE_MIDDLE_LEFT → (0, 128) → "Left edge piece" ✅ WORKING
35-
- Index 5: FENCE_FRONT → (64, 128) → "Bottom edge piece" ✅ WORKING (FIXED!)
36-
- Index 6: FENCE_MIDDLE_RIGHT → (128, 64) → "Right edge piece" ✅ WORKING
37-
- Index 7: FENCE_FRONT_RIGHT → (128, 128) → "Bottom-right corner piece" ✅ WORKING (FIXED!)
29+
## CORRECTED FencePieceType Mapping (Clockwise Order):
30+
- Index 0: FENCE_BACK_LEFT → (0, 0) → "Top-left corner piece" ✅ CORRECT
31+
- Index 1: FENCE_BACK → (64, 0) → "Top edge piece" ✅ CORRECT
32+
- Index 2: FENCE_BACK_RIGHT → (128, 0) → "Top-right corner piece" ✅ CORRECT
33+
- Index 3: FENCE_MIDDLE_RIGHT → (128, 64) → "Right edge piece" ✅ FIXED (was 0,64)
34+
- Index 4: FENCE_FRONT_RIGHT → (128, 128) → "Bottom-right corner piece" ✅ FIXED (was 0,128)
35+
- Index 5: FENCE_FRONT → (64, 128) → "Bottom edge piece" ✅ FIXED (was 64,128)
36+
- Index 6: FENCE_FRONT_LEFT → (0, 128) → "Bottom-left corner piece" ✅ FIXED (was 128,64)
37+
- Index 7: FENCE_MIDDLE_LEFT → (0, 64) → "Left edge piece" ✅ FIXED (was 128,128)
3838

3939
## Solution Summary:
40-
**PROBLEM SOLVED**: The texture at (64, 64) appears to be empty or transparent.
41-
**FINAL SOLUTION**:
42-
- Bottom edge piece: (64, 64) → (64, 128) ✅ Now visible
43-
- Bottom-right corner piece: (64, 64) → (128, 128) ✅ Now visible
44-
- Coordinate (64, 64) is avoided as it contains no visible texture
40+
**PROBLEM IDENTIFIED AND FIXED**: Two issues were causing incorrect fence building:
4541

46-
## All 8 fence pieces now load and display correctly!
42+
### Issue 1: Incorrect Texture Coordinates
43+
- **ROOT CAUSE**: FencePieceType enum had wrong texture coordinate mapping for indices 3-7
44+
- **SOLUTION**: Fixed texture coordinates to match the correct 3x3 grid pattern:
45+
- Index 3: FENCE_MIDDLE_RIGHT → (128,64) instead of (0,64)
46+
- Index 4: FENCE_FRONT_RIGHT → (128,128) instead of (0,128)
47+
- Index 5: FENCE_FRONT → (64,128) ✓ was already correct
48+
- Index 6: FENCE_FRONT_LEFT → (0,128) instead of (128,64)
49+
- Index 7: FENCE_MIDDLE_LEFT → (0,64) instead of (128,128)
50+
51+
### Issue 2: Incorrect Piece Type Selection Logic
52+
- **ROOT CAUSE**: FenceStructureManager.determinePieceType() had flawed adjacency-based logic
53+
- **SOLUTION**: Implemented smart rectangular pattern detection:
54+
- Detects when building rectangular enclosures
55+
- Uses proven FencePieceFactory.determinePieceTypeForPosition() for rectangular patterns
56+
- Falls back to improved adjacency logic for irregular building
57+
- Automatically places correct corner and edge pieces
58+
59+
### Issue 3: Coordinate System Mismatch (FIXED)
60+
- **ROOT CAUSE**: Y-axis orientation mismatch between game world and FencePieceFactory
61+
- **SYMPTOM**: Corners were flipped (top-left showed bottom-left piece, etc.)
62+
- **SOLUTION**: Added Y-coordinate inversion when calling FencePieceFactory for rectangular patterns
63+
64+
### Issue 4: Multiple Pieces Per Click (INVESTIGATING)
65+
- **SYMPTOM**: Sometimes single click places multiple pieces
66+
- **LIKELY CAUSE**: updateConnections() method changing adjacent pieces
67+
- **SOLUTION**: Added debugging to track piece placement and updates
68+
69+
### Issue 5: No Fence Collision (FIXED)
70+
- **SYMPTOM**: Players could walk through fences as if they weren't there
71+
- **ROOT CAUSE**: Player movement collision checking didn't include fence collision detection
72+
- **SOLUTION**: Added fence collision checking to Player.wouldCollide() method:
73+
- Integrated with existing FenceBuildingManager.checkFenceCollision()
74+
- Uses player rectangle (64x64) to check collision with fence boundaries
75+
- Prevents movement when collision is detected
76+
77+
### Issue 6: Fence Collision Areas Need Precise Adjustment (FIXED)
78+
- **SYMPTOM**:
79+
- Right side fence collision was too wide, blocking movement too far from fence
80+
- Left side fence collision allowed too much overlap with fence
81+
- **ROOT CAUSE**: Collision rectangles were not precisely tuned for optimal gameplay
82+
- **SOLUTION**: Applied precise pixel-based adjustments:
83+
- **LEFT-EDGE**: Reduced collision width by 10px (from 12.8px to 2.8px)
84+
- Changed from: `Rectangle(x, y, gridSize * 0.2f, gridSize)`
85+
- Changed to: `Rectangle(x, y, gridSize * 0.044f, gridSize)`
86+
- **RIGHT-EDGE**: Moved collision area 32px closer to fence (inward) - Final adjustment
87+
- Original: `Rectangle(x + gridSize * 0.9f, y, gridSize * 0.1f, gridSize)` (57.6px from left)
88+
- Final adjustment: `Rectangle(x + gridSize * 0.391f, y, gridSize * 0.1f, gridSize)` (25px from left)
89+
90+
### Issue 7: Collision Changes Not Taking Effect (FIXED)
91+
- **SYMPTOM**: Collision adjustments in code don't affect existing fences
92+
- **ROOT CAUSE**: Existing fences retain collision boundaries created with old settings
93+
- **SOLUTION**: Added collision boundary rebuild functionality:
94+
- Added `rebuildCollisionBoundaries()` method to FenceBuildingManager
95+
- Added debug key (R) to rebuild collision boundaries while in fence building mode
96+
- Method clears all existing collision boundaries and recreates them with new settings
97+
98+
### Issue 8: Corner Collision Inconsistency (FIXED)
99+
- **SYMPTOM**: TOP-RIGHT and BOTTOM-RIGHT corners had different collision than RIGHT-EDGE when approaching from the right
100+
- **ROOT CAUSE**: Corner pieces used full 64x64 collision rectangles instead of matching adjacent edge collision
101+
- **SOLUTION**: Added custom corner collision generation:
102+
- **FENCE_BACK_RIGHT** (TOP-RIGHT): Width reduced to match RIGHT-EDGE collision (25px + 6.4px = 31.4px)
103+
- **FENCE_FRONT_RIGHT** (BOTTOM-RIGHT): Width reduced to match RIGHT-EDGE collision (25px + 6.4px = 31.4px)
104+
- **FENCE_FRONT_LEFT** (BOTTOM-LEFT): Width reduced to match LEFT-EDGE collision (2.8px)
105+
- **FENCE_BACK_LEFT** (TOP-LEFT): Remains full collision (no adjacent edge adjustments)
106+
107+
### Issue 9: Player Rendering Behind Fences (FIXED)
108+
- **SYMPTOM**: Player appears behind fences when walking near them, especially from the bottom
109+
- **ROOT CAUSE**: Fences were rendered after the player in the rendering order
110+
- **SOLUTION**: Changed rendering order in MyGdxGame.render():
111+
- **Before**: Player → Remote Players → Fences (player appears behind fences)
112+
- **After**: Fences → Player → Remote Players (player appears above fences)
113+
- **Impact**: No breaking changes - only improves visual layering
114+
- **Result**: Player now properly appears above fences when walking near them
115+
116+
### How to Apply Collision Changes
117+
1. Enter fence building mode (press **B** key)
118+
2. Press **R key** to rebuild all collision boundaries with new settings
119+
3. Test the collision by walking near fences from different directions
120+
121+
## Fence building should now create proper rectangles and squares with correct textures, piece types, consistent collision boundaries, and proper visual layering!

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

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ public class FenceBuildingManager {
7373
/** Flag to prevent targeting system interference after direct mouse operations */
7474
private boolean suppressTargetingCallback = false;
7575

76+
/** Flag to disable direct mouse input when targeting system is handling input */
77+
private boolean disableDirectMouseInput = false;
78+
7679
/**
7780
* Creates a new FenceBuildingManager with the specified dependencies.
7881
*
@@ -135,6 +138,11 @@ public void update(float deltaTime) {
135138
clearAllFences();
136139
}
137140

141+
// Handle rebuild collision boundaries (R key) when in building mode
142+
if (buildingModeActive && Gdx.input.isKeyJustPressed(Input.Keys.R)) {
143+
rebuildCollisionBoundaries();
144+
}
145+
138146

139147

140148
// Only process building input when in building mode and stable
@@ -325,17 +333,20 @@ private void processBuildingInput() {
325333
return;
326334
}
327335

328-
// Handle placement (left click)
329-
if (leftClicked) {
336+
// Handle placement (left click) - skip if targeting system is handling input
337+
if (leftClicked && !disableDirectMouseInput) {
330338
System.out.println("[FenceBuildingManager] Left click detected at grid (" + gridPos.x + ", " + gridPos.y + ")");
331339
if (placeFenceSegment(gridPos.x, gridPos.y)) {
332340
lastProcessedGridPos = new Point(gridPos.x, gridPos.y);
333341
}
334342
}
335343

336-
// Handle removal (right click)
344+
// Handle removal (right click) - always allow right-click removal
337345
if (rightClicked) {
338346
System.out.println("[FenceBuildingManager] Right click detected at grid (" + gridPos.x + ", " + gridPos.y + ")");
347+
// Debug: Check what fence pieces exist
348+
FencePiece existingPiece = structureManager.getFencePiece(gridPos);
349+
System.out.println("DEBUG: Fence piece at (" + gridPos.x + ", " + gridPos.y + "): " + (existingPiece != null ? existingPiece.getType() : "null"));
339350
if (removeFenceSegment(gridPos.x, gridPos.y)) {
340351
lastProcessedGridPos = new Point(gridPos.x, gridPos.y);
341352
// Suppress targeting system callback to prevent immediate replacement
@@ -389,7 +400,9 @@ public boolean placeFenceSegment(int gridX, int gridY) {
389400
// Consume materials from inventory
390401
FenceMaterialProvider materialProvider = validator.getMaterialProvider();
391402
if (materialProvider != null) {
403+
System.out.println("DEBUG: Consuming 1 " + selectedMaterialType + " fence material");
392404
materialProvider.consumeMaterials(selectedMaterialType, 1);
405+
System.out.println("DEBUG: Material consumption completed");
393406

394407
// Update collision boundaries immediately
395408
updateCollisionBoundaries(gridPos, true);
@@ -406,6 +419,7 @@ public boolean placeFenceSegment(int gridX, int gridY) {
406419
}
407420
return true;
408421
} else {
422+
System.out.println("DEBUG: Material provider is null - no materials consumed");
409423
// Rollback placement if material consumption fails
410424
structureManager.removeFencePiece(gridPos);
411425
displayPlacementError("Failed to consume materials", gridPos);
@@ -643,6 +657,15 @@ public boolean shouldSuppressTargetingCallback() {
643657
return suppress;
644658
}
645659

660+
/**
661+
* Set whether direct mouse input should be disabled.
662+
* Used to prevent double placement when targeting system is active.
663+
* @param disabled true to disable direct mouse input, false to enable
664+
*/
665+
public void setDirectMouseInputDisabled(boolean disabled) {
666+
this.disableDirectMouseInput = disabled;
667+
}
668+
646669
/**
647670
* Gets the currently selected material type.
648671
*
@@ -724,6 +747,20 @@ public FenceCollisionManager getCollisionManager() {
724747
return collisionManager;
725748
}
726749

750+
/**
751+
* Rebuilds all fence collision boundaries.
752+
* Useful after code changes to collision rectangle generation.
753+
*/
754+
public void rebuildCollisionBoundaries() {
755+
if (collisionManager != null) {
756+
System.out.println("[FenceBuildingManager] Starting collision boundary rebuild...");
757+
collisionManager.rebuildAllCollisionBoundaries();
758+
System.out.println("[FenceBuildingManager] Collision boundaries rebuilt successfully");
759+
} else {
760+
System.out.println("[FenceBuildingManager] Cannot rebuild - collision manager is null");
761+
}
762+
}
763+
727764
/**
728765
* Gets the sound manager.
729766
*

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

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ private Rectangle generateCollisionRectangle(Point gridPos, FencePiece piece) {
102102
Rectangle collisionRect;
103103

104104
if (piece.getType().isCornerPiece()) {
105-
// Corner pieces have full collision boundaries
106-
collisionRect = new Rectangle(worldPos.x, worldPos.y, FenceGrid.GRID_SIZE, FenceGrid.GRID_SIZE);
105+
// Corner pieces have custom collision boundaries to match adjacent edges
106+
collisionRect = generateCornerCollisionRect(worldPos, piece.getType());
107107
} else {
108108
// Edge pieces have directional collision boundaries
109109
collisionRect = generateDirectionalCollisionRect(worldPos, piece.getType());
@@ -128,27 +128,70 @@ private Rectangle generateDirectionalCollisionRect(com.badlogic.gdx.math.Vector2
128128

129129
switch (pieceType) {
130130
case FENCE_BACK:
131-
// Top edge - blocks vertical movement
132-
return new Rectangle(x, y + gridSize * 0.8f, gridSize, gridSize * 0.2f);
131+
// Top edge - blocks vertical movement (shifted left by 15px)
132+
return new Rectangle(x - 15f, y + gridSize * 0.8f, gridSize, gridSize * 0.2f);
133133

134134
case FENCE_FRONT:
135-
// Bottom edge - blocks vertical movement
136-
return new Rectangle(x, y, gridSize, gridSize * 0.2f);
135+
// Bottom edge - blocks vertical movement (shifted left by 15px)
136+
return new Rectangle(x - 15f, y, gridSize, gridSize * 0.2f);
137137

138138
case FENCE_MIDDLE_LEFT:
139-
// Left edge - blocks horizontal movement
140-
return new Rectangle(x, y, gridSize * 0.2f, gridSize);
139+
// Left edge - blocks horizontal movement (shifted left by 15px)
140+
return new Rectangle(x - 15f, y, gridSize * 0.044f, gridSize);
141141

142142
case FENCE_MIDDLE_RIGHT:
143-
// Right edge - blocks horizontal movement
144-
return new Rectangle(x + gridSize * 0.8f, y, gridSize * 0.2f, gridSize);
143+
// Right edge - blocks horizontal movement (shifted left by 15px, collision starts at 10px from left edge)
144+
Rectangle rightEdgeRect = new Rectangle(x + 10f, y, gridSize - 10f, gridSize);
145+
System.out.println("FENCE_MIDDLE_RIGHT collision: x=" + (x + 10f) + ", y=" + y + ", width=" + (gridSize - 10f) + ", height=" + gridSize);
146+
return rightEdgeRect;
145147

146148
default:
147149
// Default to full collision for unknown types
148150
return new Rectangle(x, y, gridSize, gridSize);
149151
}
150152
}
151153

154+
/**
155+
* Generates collision rectangles for corner pieces that match adjacent edge collision boundaries.
156+
* This ensures consistent collision when approaching corners from different directions.
157+
*
158+
* @param worldPos World position of the corner piece
159+
* @param pieceType Type of the corner piece
160+
* @return Rectangle representing the corner collision boundary
161+
*/
162+
private Rectangle generateCornerCollisionRect(com.badlogic.gdx.math.Vector2 worldPos,
163+
FencePieceType pieceType) {
164+
float x = worldPos.x;
165+
float y = worldPos.y;
166+
float gridSize = FenceGrid.GRID_SIZE;
167+
168+
switch (pieceType) {
169+
case FENCE_BACK_LEFT:
170+
// Top-left corner - shifted left by 15px
171+
return new Rectangle(x - 15f, y, gridSize, gridSize);
172+
173+
case FENCE_BACK_RIGHT:
174+
// Top-right corner - shifted left by 15px, collision starts at 10px from left edge
175+
Rectangle backRightRect = new Rectangle(x + 10f, y, gridSize - 10f, gridSize);
176+
System.out.println("FENCE_BACK_RIGHT collision: x=" + (x + 10f) + ", y=" + y + ", width=" + (gridSize - 10f) + ", height=" + gridSize);
177+
return backRightRect;
178+
179+
case FENCE_FRONT_RIGHT:
180+
// Bottom-right corner - shifted left by 15px, collision starts at 10px from left edge
181+
Rectangle frontRightRect = new Rectangle(x + 10f, y, gridSize - 10f, gridSize);
182+
System.out.println("FENCE_FRONT_RIGHT collision: x=" + (x + 10f) + ", y=" + y + ", width=" + (gridSize - 10f) + ", height=" + gridSize);
183+
return frontRightRect;
184+
185+
case FENCE_FRONT_LEFT:
186+
// Bottom-left corner - shifted left by 15px
187+
return new Rectangle(x - 15f, y, gridSize * 0.044f, gridSize);
188+
189+
default:
190+
// Default to full collision for unknown corner types
191+
return new Rectangle(x, y, gridSize, gridSize);
192+
}
193+
}
194+
152195
/**
153196
* Updates collision boundaries for complete enclosures.
154197
* Creates continuous collision boundaries around enclosure perimeters.

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
* The pieces are arranged in clockwise order starting from the top-left corner.
66
*/
77
public enum FencePieceType {
8-
FENCE_BACK_LEFT(0, 0, "Top-left corner piece"),
9-
FENCE_BACK(64, 0, "Top edge piece"),
10-
FENCE_BACK_RIGHT(128, 0, "Top-right corner piece"),
11-
FENCE_FRONT_LEFT(0, 64, "Bottom-left corner piece"),
12-
FENCE_MIDDLE_LEFT(0, 128, "Left edge piece"),
13-
FENCE_FRONT(64, 128, "Bottom edge piece"),
14-
FENCE_MIDDLE_RIGHT(128, 64, "Right edge piece"),
15-
FENCE_FRONT_RIGHT(128, 128, "Bottom-right corner piece");
8+
FENCE_BACK_LEFT(0, 0, "Top-left corner piece"), // Index 0 → (0,0)
9+
FENCE_BACK(64, 0, "Top edge piece"), // Index 1 → (64,0)
10+
FENCE_BACK_RIGHT(128, 0, "Top-right corner piece"), // Index 2 → (128,0)
11+
FENCE_MIDDLE_RIGHT(128, 64, "Right edge piece"), // Index 3 → (128,64) - FIXED
12+
FENCE_FRONT_RIGHT(128, 128, "Bottom-right corner piece"), // Index 4 → (128,128) - FIXED
13+
FENCE_FRONT(64, 128, "Bottom edge piece"), // Index 5 → (64,128) - FIXED
14+
FENCE_FRONT_LEFT(0, 128, "Bottom-left corner piece"), // Index 6 → (0,128) - FIXED
15+
FENCE_MIDDLE_LEFT(0, 64, "Left edge piece"); // Index 7 → (0,64) - FIXED
1616

1717
private final int textureX;
1818
private final int textureY;

0 commit comments

Comments
 (0)