Godot Version
4.6
Question
I’ve just started expanding a game from the one scene testing area to one that manages the player globally across multiple maps, but I keep breaking my farming system in one of two ways. Either the Farm Manager can no longer tell what tile the player is standing on, or the tool scripting can’t see the Farm Manager. I’ve tried changing the player back to an actual child of the scene running rather than the manager but the tools scripting (child of player) still cant find the Farm Manager even with an absolute path set.
If you share code, please wrap it inside three backticks or replace the code in the next block:
extends Node #Player Manager Global Script#
const PLAYER_NODE = preload("uid://cdr1qa3m5xq3q")
var player : Player
var player_spawned : bool = false
func _ready() -> void:
add_player_instance()
func add_player_instance():
player = PLAYER_NODE.instantiate()
get_tree().current_scene.add_child (player)
func set_player_position(_new_pos : Vector2):
player.global_position = _new_pos
class_name PlayerTools
extends Node2D
enum Tool {
WATER_BUCKET,
SCYTHE,
SEED,
HOE
}
var current_tool : Tool
var current_seed : CropData
@onready var farm_manager: FarmManager = %FarmManager
func _ready() -> void:
current_tool = Tool.HOE
Global.SetPlayerTool.connect(set_tool)
func set_tool (tool: Tool, seed: CropData):
current_tool = tool
current_seed = seed
func _process(delta: float) -> void:
if Input.is_action_just_pressed("Plant"):
match current_tool:
Tool.HOE:
print("Is my node valid? ", is_instance_valid(farm_manager))
print("What is inside my variable? ", farm_manager)
farm_manager.try_till_tile(global_position)
Tool.WATER_BUCKET:
farm_manager.try_water_tile(global_position)
Tool.SCYTHE:
farm_manager.try_harvest_tile(global_position)
Tool.SEED:
farm_manager.try_seed_tile(global_position, current_seed)
class_name FarmManager #Controls Tile Types#
extends Node
enum TileType {
GRASS,
TILLED,
TILLED_WATERED,
NO_TILL
}
class TileInfo:
var tilled: bool
var watered: bool
var crop : PlanterCrop
@onready var tile_map_layer: TileMapLayer = $FarmTile
var tile_info : Dictionary[Vector2i, TileInfo]
var crop_scene : PackedScene = preload("res://Assets/Scenes/Harvestables/planter_crop.tscn")
var tile_atlas_coords : Dictionary[TileType, Vector2i] = {
TileType.GRASS: Vector2i(1,1),
TileType.TILLED: Vector2i(3,1),
TileType.TILLED_WATERED: Vector2i (4,1),
TileType.NO_TILL: Vector2i(0,1)
}
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
Global.NewDay.connect(_on_new_day)
Global.HarvestCrop.connect(_on_harvest_crop)
for cell in tile_map_layer.get_used_cells():
tile_info [cell] = TileInfo.new()
#Custom Functions#
func _on_new_day (day: int):
for tile_pos in tile_map_layer.get_used_cells():
if tile_info[tile_pos].watered:
_set_tile_state(tile_pos, TileType.TILLED)
elif tile_info[tile_pos].tilled:
if tile_info[tile_pos].crop == null:
_set_tile_state(tile_pos, TileType.GRASS)
func _on_harvest_crop (crop: PlanterCrop):
tile_info[crop.tile_map_coords].crop = null
_set_tile_state(crop.tile_map_coords, TileType.TILLED)
func try_till_tile (player_pos: Vector2):
print("tilled")
var coords: Vector2i = tile_map_layer.local_to_map(player_pos)
print(player_pos)
if tile_info[coords].crop:
return
if tile_info[coords].tilled:
return
_set_tile_state(coords,TileType.TILLED)
func try_water_tile (player_pos: Vector2):
#Get player Position
var coords: Vector2i = tile_map_layer.local_to_map(player_pos)
#Check if Tilled#
if not tile_info[coords].tilled:
return
#Otherwise Water#
_set_tile_state(coords, TileType.TILLED_WATERED)
#Also water plant#
if tile_info [coords].crop:
tile_info [coords].crop.watered = true
func try_seed_tile (player_pos: Vector2, crop_data : CropData):
var coords: Vector2i = tile_map_layer.local_to_map(player_pos)
#Only plant on tilled#
if not tile_info[coords].tilled:
return
#Can't plant new seed on tile#
if tile_info[coords].crop:
return
if Global.owned_seeds[crop_data] <= 0:
return
var crop: PlanterCrop = crop_scene.instantiate()
add_child(crop)
crop.global_position = tile_map_layer.to_global(tile_map_layer.map_to_local(coords))
#Call Function located in Planter Crop Scripting#
crop.set_crop(crop_data, is_tile_watered(coords), coords)
tile_info[coords].crop = crop
Global.consume_seed(crop_data)
#Remove Seeds Here#
func try_harvest_tile (player_pos: Vector2):
var coords: Vector2i = tile_map_layer.local_to_map(player_pos)
if not tile_info[coords].crop: #Dont check unplanted cells#
return
if not tile_info[coords].crop.harvestable: #Only harvest when ready#
return
Global.harvest_crop(tile_info[coords].crop)
tile_info[coords].crop = null
func is_tile_watered (pos: Vector2) -> bool:
var coords := tile_map_layer.local_to_map(pos)
return tile_info[coords].watered
func _set_tile_state (coords: Vector2i, tile_type: TileType):
tile_map_layer.set_cell (coords,0, tile_atlas_coords[tile_type])
match tile_type:
TileType.GRASS:
tile_info[coords].tilled = false
tile_info[coords].watered = false
TileType.TILLED:
tile_info[coords].tilled = true
tile_info[coords].watered = false
TileType.TILLED_WATERED:
tile_info[coords].tilled = true
tile_info[coords].watered = true