33import com .badlogic .gdx .Gdx ;
44import com .badlogic .gdx .Input ;
55import com .badlogic .gdx .graphics .OrthographicCamera ;
6+ import com .badlogic .gdx .graphics .g2d .SpriteBatch ;
7+ import com .badlogic .gdx .graphics .g2d .TextureRegion ;
68import com .badlogic .gdx .math .Rectangle ;
79import com .badlogic .gdx .math .Vector2 ;
810import com .badlogic .gdx .math .Vector3 ;
911import java .awt .Point ;
1012import java .util .List ;
13+ import java .util .Map ;
1114
1215/**
1316 * Central coordinator for all fence building operations.
@@ -67,6 +70,9 @@ public class FenceBuildingManager {
6770 /** Flag to indicate building mode was just activated this frame */
6871 private boolean buildingModeJustActivated = false ;
6972
73+ /** Flag to prevent targeting system interference after direct mouse operations */
74+ private boolean suppressTargetingCallback = false ;
75+
7076 /**
7177 * Creates a new FenceBuildingManager with the specified dependencies.
7278 *
@@ -124,6 +130,13 @@ public void update(float deltaTime) {
124130 enterBuildingMode ();
125131 }
126132
133+ // Handle clear all fences (C key) when in building mode
134+ if (buildingModeActive && Gdx .input .isKeyJustPressed (Input .Keys .C )) {
135+ clearAllFences ();
136+ }
137+
138+
139+
127140 // Only process building input when in building mode and stable
128141 if (buildingModeActive && !buildingModeJustActivated ) {
129142 processBuildingInput ();
@@ -145,6 +158,45 @@ public void renderFences() {
145158 }
146159 }
147160
161+ /**
162+ * Renders all fence structures using the provided SpriteBatch.
163+ * This ensures proper rendering order with other game elements.
164+ *
165+ * @param batch The SpriteBatch to use for rendering
166+ */
167+ public void renderFences (SpriteBatch batch ) {
168+ if (structureManager == null ) {
169+ return ;
170+ }
171+
172+ Map <Point , FencePiece > allPieces = structureManager .getAllFencePieces ();
173+ if (allPieces .isEmpty ()) {
174+ return ;
175+ }
176+
177+ // Get the texture atlas from the fence renderer
178+ FenceTextureAtlas textureAtlas = null ;
179+ if (fenceRenderer != null ) {
180+ textureAtlas = fenceRenderer .getTextureAtlas ();
181+ }
182+
183+ if (textureAtlas == null || !textureAtlas .isInitialized ()) {
184+ System .err .println ("[FenceBuildingManager] Texture atlas not available for rendering" );
185+ return ;
186+ }
187+
188+ // Render all fence pieces using the main batch
189+ for (FencePiece piece : allPieces .values ()) {
190+ TextureRegion region = textureAtlas .getTextureRegion (piece .getType ());
191+ if (region != null ) {
192+ batch .draw (region , piece .getX (), piece .getY (),
193+ textureAtlas .getPieceSize (), textureAtlas .getPieceSize ());
194+ } else {
195+ System .err .println ("[FenceBuildingManager] No texture region for " + piece .getType ());
196+ }
197+ }
198+ }
199+
148200 /**
149201 * Renders visual effects for fence building operations.
150202 * Should be called during the rendering phase.
@@ -174,6 +226,7 @@ public void toggleBuildingMode() {
174226 * Validates material availability before allowing entry.
175227 */
176228 private void enterBuildingMode () {
229+
177230 // Check if player has any fence materials
178231 FenceMaterialProvider materialProvider = validator .getMaterialProvider ();
179232 if (materialProvider != null ) {
@@ -203,6 +256,8 @@ private void enterBuildingMode() {
203256
204257 System .out .println ("[FenceBuildingManager] Entered fence building mode - Press " + Input .Keys .toString (buildingModeToggleKey ) + " to exit" );
205258 System .out .println ("[FenceBuildingManager] Left click to place fence, Right click to remove fence" );
259+ System .out .println ("[FenceBuildingManager] Press C to clear all fences" );
260+
206261 System .out .println ("[FenceBuildingManager] Current material: " + selectedMaterialType .getDisplayName ());
207262 System .out .println ("[FenceBuildingManager] State: buildingModeActive=" + buildingModeActive +
208263 ", buildingModeJustActivated=" + buildingModeJustActivated +
@@ -245,6 +300,23 @@ private void processBuildingInput() {
245300 Vector3 mousePos = new Vector3 (Gdx .input .getX (), Gdx .input .getY (), 0 );
246301 camera .unproject (mousePos );
247302
303+ // Constrain fence placement to be within reasonable distance from camera (viewport area)
304+ float maxDistance = Math .min (camera .viewportWidth , camera .viewportHeight ) / 2f ; // Half viewport size
305+ float cameraX = camera .position .x ;
306+ float cameraY = camera .position .y ;
307+
308+ // Calculate distance from camera center
309+ float dx = mousePos .x - cameraX ;
310+ float dy = mousePos .y - cameraY ;
311+ float distance = (float ) Math .sqrt (dx * dx + dy * dy );
312+
313+ // If click is too far from camera, clamp it to viewport area
314+ if (distance > maxDistance ) {
315+ float ratio = maxDistance / distance ;
316+ mousePos .x = cameraX + dx * ratio ;
317+ mousePos .y = cameraY + dy * ratio ;
318+ }
319+
248320 // Convert to grid coordinates
249321 Point gridPos = structureManager .getGrid ().worldToGrid (mousePos .x , mousePos .y );
250322
@@ -255,15 +327,19 @@ private void processBuildingInput() {
255327
256328 // Handle placement (left click)
257329 if (leftClicked ) {
330+ System .out .println ("[FenceBuildingManager] Left click detected at grid (" + gridPos .x + ", " + gridPos .y + ")" );
258331 if (placeFenceSegment (gridPos .x , gridPos .y )) {
259332 lastProcessedGridPos = new Point (gridPos .x , gridPos .y );
260333 }
261334 }
262335
263336 // Handle removal (right click)
264337 if (rightClicked ) {
338+ System .out .println ("[FenceBuildingManager] Right click detected at grid (" + gridPos .x + ", " + gridPos .y + ")" );
265339 if (removeFenceSegment (gridPos .x , gridPos .y )) {
266340 lastProcessedGridPos = new Point (gridPos .x , gridPos .y );
341+ // Suppress targeting system callback to prevent immediate replacement
342+ suppressTargetingCallback = true ;
267343 }
268344 }
269345
@@ -304,10 +380,12 @@ public boolean placeFenceSegment(int gridX, int gridY) {
304380 }
305381
306382 try {
383+ System .out .println ("[FenceBuildingManager] Attempting to place fence at grid (" + gridPos .x + ", " + gridPos .y + ") with material " + selectedMaterialType );
307384 // Attempt to place the fence piece with automatic piece type selection
308385 FencePiece placedPiece = structureManager .addFencePiece (gridPos , selectedMaterialType );
309386
310387 if (placedPiece != null ) {
388+ System .out .println ("[FenceBuildingManager] Fence piece created: " + placedPiece .getType () + " at world (" + placedPiece .getX () + ", " + placedPiece .getY () + ")" );
311389 // Consume materials from inventory
312390 FenceMaterialProvider materialProvider = validator .getMaterialProvider ();
313391 if (materialProvider != null ) {
@@ -553,6 +631,18 @@ public boolean wasBuildingModeJustActivated() {
553631 return buildingModeJustActivated ;
554632 }
555633
634+ /**
635+ * Checks if targeting system callbacks should be suppressed.
636+ * Used to prevent targeting system interference after direct mouse operations.
637+ *
638+ * @return true if targeting callbacks should be suppressed, false otherwise
639+ */
640+ public boolean shouldSuppressTargetingCallback () {
641+ boolean suppress = suppressTargetingCallback ;
642+ suppressTargetingCallback = false ; // Reset flag after checking
643+ return suppress ;
644+ }
645+
556646 /**
557647 * Gets the currently selected material type.
558648 *
@@ -733,6 +823,26 @@ private void updateCollisionBoundaries(Point gridPos, boolean placed) {
733823 }
734824 }
735825
826+ /**
827+ * Clears all fence pieces from the world.
828+ * Useful for debugging and testing.
829+ */
830+ public void clearAllFences () {
831+ if (structureManager != null ) {
832+ int fenceCount = structureManager .getFencePieceCount ();
833+ structureManager .clear ();
834+
835+ // Clear collision boundaries
836+ if (collisionManager != null ) {
837+ collisionManager .clear ();
838+ }
839+
840+ System .out .println ("[FenceBuildingManager] Cleared " + fenceCount + " fence pieces" );
841+ }
842+ }
843+
844+
845+
736846 /**
737847 * Disposes of resources used by this manager.
738848 */
0 commit comments