Skip to content

Commit c7be9b4

Browse files
committed
Implemented planting trees and auto-deselect inventory on completion
1 parent 2aa05c4 commit c7be9b4

19 files changed

Lines changed: 1704 additions & 33 deletions

specs/baby-tree-planting-system.md

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
# BabyTree Planting System Implementation Plan
2+
3+
## Overview
4+
Implement a planting system for BabyTree items that follows the same pattern as the existing BabyBamboo planting system. Players will be able to plant BabyTree items from their inventory, which will grow into SmallTree instances after 120 seconds.
5+
6+
## Requirements Analysis
7+
8+
### Core Functionality
9+
1. **Planting Mechanics**: Plant BabyTree items using the existing targeting system
10+
2. **Growth System**: BabyTree grows into SmallTree after 120 seconds (same duration as bamboo)
11+
3. **Inventory Integration**: Reduce BabyTree count when planted
12+
4. **World Persistence**: Save/load planted trees in world saves
13+
5. **Multiplayer Support**: Synchronize planting and growth across clients
14+
6. **Biome Restrictions**: Plant on grass biomes (opposite of bamboo which plants on sand)
15+
16+
### Technical Requirements
17+
1. **PlantedTree Class**: Similar to PlantedBamboo with growth timer
18+
2. **Network Messages**: Plant and transform messages for multiplayer
19+
3. **Targeting System**: Reuse existing system with grass biome validation
20+
4. **World Save Integration**: Include planted trees in save/load operations
21+
22+
## Implementation Plan
23+
24+
### Phase 1: Core Planting Infrastructure
25+
26+
#### 1.1 Create PlantedTree Class
27+
**File**: `/src/main/java/wagemaker/uk/planting/PlantedTree.java`
28+
29+
**Features**:
30+
- Growth timer (120 seconds)
31+
- Shared texture system (like PlantedBamboo)
32+
- Tile-grid snapping
33+
- Update method returning transformation readiness
34+
35+
**Key Methods**:
36+
- `PlantedTree(float x, float y)` - Constructor with grid snapping
37+
- `boolean update(float deltaTime)` - Returns true when ready to transform
38+
- `boolean isReadyToTransform()` - Check transformation status
39+
- `Texture getTexture()` - Get shared texture
40+
- `void dispose()` - Cleanup with instance counting
41+
42+
#### 1.2 Create Network Messages
43+
**Files**:
44+
- `/src/main/java/wagemaker/uk/network/TreePlantMessage.java`
45+
- `/src/main/java/wagemaker/uk/network/TreeTransformMessage.java`
46+
47+
**TreePlantMessage Features**:
48+
- Player ID, planted tree ID, coordinates
49+
- Serializable for network transmission
50+
51+
**TreeTransformMessage Features**:
52+
- Planted tree ID, small tree ID, coordinates
53+
- Handles transformation from planted to full tree
54+
55+
#### 1.3 Update PlantingSystem
56+
**File**: `/src/main/java/wagemaker/uk/planting/PlantingSystem.java`
57+
58+
**New Methods**:
59+
- `boolean canPlantTree(float x, float y, BiomeManager biomeManager)` - Validate grass biome
60+
- `String plantTree(float x, float y, Map<String, PlantedTree> plantedTrees)` - Plant logic
61+
62+
### Phase 2: Player Integration
63+
64+
#### 2.1 Update Player Class
65+
**File**: `/src/main/java/wagemaker/uk/player/Player.java`
66+
67+
**Additions**:
68+
- `Map<String, PlantedTree> plantedTrees` reference
69+
- Tree planting logic in action handling
70+
- Biome validation for tree planting (grass only)
71+
72+
**Modified Methods**:
73+
- `handleSpacebarAction()` - Add tree planting when BabyTree selected
74+
- `setPlantedTrees()` - Setter for planted trees map
75+
76+
#### 2.2 Update Targeting System
77+
**File**: `/src/main/java/wagemaker/uk/targeting/TargetingSystem.java`
78+
79+
**Enhancements**:
80+
- Biome-aware validation
81+
- Support for both sand (bamboo) and grass (tree) planting
82+
- Method to check valid planting surface based on selected item
83+
84+
### Phase 3: Game Integration
85+
86+
#### 3.1 Update MyGdxGame Class
87+
**File**: `/src/main/java/wagemaker/uk/gdx/MyGdxGame.java`
88+
89+
**Additions**:
90+
- `Map<String, PlantedTree> plantedTrees` field
91+
- Rendering method `drawPlantedTrees()`
92+
- Update loop for planted tree growth
93+
- Transform logic (PlantedTree → SmallTree)
94+
- Network message queues for tree planting
95+
96+
**Modified Methods**:
97+
- `create()` - Initialize planted trees map
98+
- `render()` - Add planted tree updates and rendering
99+
- `dispose()` - Cleanup planted trees
100+
101+
#### 3.2 Update GameMessageHandler
102+
**File**: `/src/main/java/wagemaker/uk/gdx/GameMessageHandler.java`
103+
104+
**New Message Handlers**:
105+
- `handleTreePlantMessage()` - Process remote tree planting
106+
- `handleTreeTransformMessage()` - Process tree transformation
107+
108+
### Phase 4: World Persistence
109+
110+
#### 4.1 Create PlantedTreeState
111+
**File**: `/src/main/java/wagemaker/uk/network/PlantedTreeState.java`
112+
113+
**Features**:
114+
- Serializable state for planted trees
115+
- Growth timer persistence
116+
- Position and ID storage
117+
118+
#### 4.2 Update WorldSaveData
119+
**File**: `/src/main/java/wagemaker/uk/world/WorldSaveData.java`
120+
121+
**Additions**:
122+
- `Map<String, PlantedTreeState> plantedTrees` field
123+
- Getter/setter methods
124+
125+
#### 4.3 Update WorldSaveManager
126+
**File**: `/src/main/java/wagemaker/uk/world/WorldSaveManager.java`
127+
128+
**Enhancements**:
129+
- Save/load planted trees in world data
130+
- Include planted trees in world state extraction
131+
132+
### Phase 5: Multiplayer Support
133+
134+
#### 5.1 Update GameServer
135+
**File**: `/src/main/java/wagemaker/uk/network/GameServer.java`
136+
137+
**Additions**:
138+
- Handle TreePlantMessage broadcasting
139+
- Handle TreeTransformMessage broadcasting
140+
- Include planted trees in world state sync
141+
142+
#### 5.2 Update GameClient
143+
**File**: `/src/main/java/wagemaker/uk/network/GameClient.java`
144+
145+
**Additions**:
146+
- Send tree plant messages
147+
- Send tree transform messages
148+
- Handle incoming tree messages
149+
150+
## Implementation Details
151+
152+
### Growth and Transformation Logic
153+
```java
154+
// In MyGdxGame.render()
155+
List<String> treesToTransform = new ArrayList<>();
156+
for (Map.Entry<String, PlantedTree> entry : plantedTrees.entrySet()) {
157+
PlantedTree planted = entry.getValue();
158+
if (planted.update(deltaTime)) {
159+
treesToTransform.add(entry.getKey());
160+
}
161+
}
162+
163+
// Transform mature planted trees into small trees
164+
for (String key : treesToTransform) {
165+
PlantedTree planted = plantedTrees.remove(key);
166+
float x = planted.getX();
167+
float y = planted.getY();
168+
169+
SmallTree tree = new SmallTree(x, y);
170+
trees.put(key, tree);
171+
planted.dispose();
172+
173+
// Send transformation message in multiplayer
174+
if (gameClient != null && gameClient.isConnected()) {
175+
TreeTransformMessage message = new TreeTransformMessage(
176+
gameClient.getClientId(), key, key, x, y
177+
);
178+
gameClient.sendMessage(message);
179+
}
180+
}
181+
```
182+
183+
### Biome Validation
184+
```java
185+
// In PlantingSystem
186+
public boolean canPlantTree(float x, float y, BiomeManager biomeManager) {
187+
BiomeType biome = biomeManager.getBiomeAtPosition(x, y);
188+
return biome == BiomeType.GRASS; // Trees plant on grass, bamboo on sand
189+
}
190+
```
191+
192+
### Inventory Integration
193+
```java
194+
// In Player.handleSpacebarAction()
195+
if (selectedSlot == 5) { // BabyTree slot
196+
Inventory inventory = inventoryManager.getCurrentInventory();
197+
if (inventory.getBabyTreeCount() > 0) {
198+
// Validate grass biome
199+
if (plantingSystem.canPlantTree(targetX, targetY, biomeManager)) {
200+
// Plant the tree
201+
String plantedId = plantingSystem.plantTree(targetX, targetY, plantedTrees);
202+
if (plantedId != null) {
203+
inventory.setBabyTreeCount(inventory.getBabyTreeCount() - 1);
204+
// Send network message if multiplayer
205+
}
206+
}
207+
}
208+
}
209+
```
210+
211+
## Testing Strategy
212+
213+
### Unit Tests
214+
1. **PlantedTree Growth**: Verify 120-second growth timer
215+
2. **Biome Validation**: Test grass-only planting restriction
216+
3. **Network Messages**: Validate serialization/deserialization
217+
4. **World Persistence**: Test save/load of planted trees
218+
219+
### Integration Tests
220+
1. **Planting Flow**: End-to-end planting from inventory to SmallTree
221+
2. **Multiplayer Sync**: Verify cross-client synchronization
222+
3. **World Save/Load**: Test persistence across game sessions
223+
224+
### Manual Testing
225+
1. **Gameplay Flow**: Plant trees and verify growth
226+
2. **Biome Restrictions**: Attempt planting on sand (should fail)
227+
3. **Inventory Updates**: Verify count decreases on planting
228+
4. **Multiplayer**: Test with multiple clients
229+
230+
## Success Criteria
231+
232+
### Functional Requirements
233+
- ✅ BabyTree items can be planted from inventory
234+
- ✅ Planted trees grow into SmallTree after 120 seconds
235+
- ✅ Planting only works on grass biomes
236+
- ✅ Inventory count decreases when planting
237+
- ✅ Planted trees persist in world saves
238+
- ✅ Multiplayer synchronization works correctly
239+
240+
### Technical Requirements
241+
- ✅ No memory leaks from texture management
242+
- ✅ Thread-safe multiplayer operations
243+
- ✅ Consistent behavior across game modes
244+
- ✅ Proper cleanup on game exit
245+
246+
## Risk Mitigation
247+
248+
### Potential Issues
249+
1. **Texture Memory**: Use shared texture pattern like PlantedBamboo
250+
2. **Network Desync**: Implement proper message queuing
251+
3. **Save Corruption**: Validate planted tree data on load
252+
4. **Performance**: Limit planted tree count per area
253+
254+
### Mitigation Strategies
255+
1. **Shared Textures**: Implement instance counting for disposal
256+
2. **Deferred Operations**: Use render thread for OpenGL operations
257+
3. **Data Validation**: Check bounds and types on load
258+
4. **Spatial Limits**: Prevent excessive planting in small areas
259+
260+
## Implementation Order
261+
262+
1. **Core Classes**: PlantedTree, network messages
263+
2. **Game Integration**: MyGdxGame updates, rendering
264+
3. **Player Integration**: Planting logic, targeting
265+
4. **World Persistence**: Save/load functionality
266+
5. **Multiplayer**: Network synchronization
267+
6. **Testing**: Unit and integration tests
268+
7. **Polish**: Error handling, edge cases
269+
270+
This plan ensures a systematic implementation that follows the established patterns in the codebase while providing the same functionality as the BabyBamboo system but for trees on grass biomes.

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import wagemaker.uk.network.WorldStateUpdateMessage;
3131
import wagemaker.uk.network.ResourceRespawnMessage;
3232
import wagemaker.uk.network.RespawnStateMessage;
33+
import wagemaker.uk.network.TreePlantMessage;
34+
import wagemaker.uk.network.TreeTransformMessage;
3335
import wagemaker.uk.player.RemotePlayer;
3436

3537
/**
@@ -382,6 +384,35 @@ protected void handleBambooTransform(wagemaker.uk.network.BambooTransformMessage
382384
game.queueBambooTransform(message);
383385
}
384386

387+
@Override
388+
protected void handleTreePlant(wagemaker.uk.network.TreePlantMessage message) {
389+
String myClientId = game.getGameClient() != null ? game.getGameClient().getClientId() : "null";
390+
String senderPlayerId = message.getPlayerId();
391+
392+
System.out.println("[GameMessageHandler] Received TreePlantMessage:");
393+
System.out.println(" - My Client ID: " + myClientId);
394+
System.out.println(" - Sender Player ID: " + senderPlayerId);
395+
System.out.println(" - Planted Tree ID: " + message.getPlantedTreeId());
396+
System.out.println(" - Position: (" + message.getX() + ", " + message.getY() + ")");
397+
398+
// Don't process our own planting messages (already handled locally)
399+
if (game.getGameClient() != null &&
400+
message.getPlayerId().equals(game.getGameClient().getClientId())) {
401+
System.out.println(" - SKIPPING: This is my own planting message");
402+
return;
403+
}
404+
405+
System.out.println(" - PROCESSING: This is a remote player's planting");
406+
// Queue tree planting to be processed on the main thread
407+
game.queueTreePlant(message);
408+
}
409+
410+
@Override
411+
protected void handleTreeTransform(wagemaker.uk.network.TreeTransformMessage message) {
412+
// Queue tree transformation to be processed on the main thread
413+
game.queueTreeTransform(message);
414+
}
415+
385416
@Override
386417
protected void handleTreeCreated(wagemaker.uk.network.TreeCreatedMessage message) {
387418
// Create tree state from message

0 commit comments

Comments
 (0)