2024-09-14 22:01:46 +00:00
|
|
|
extends TileMapLayer
|
|
|
|
|
|
|
|
@export var building_spots: Array[Vector2i]
|
2024-09-15 02:20:30 +00:00
|
|
|
@export var tree_spots: Array[Vector2i]
|
|
|
|
@export var rock_spots: Array[Vector2i]
|
2024-09-15 04:46:49 +00:00
|
|
|
@export var th_spots: Array[Vector2i]
|
2024-09-15 05:37:02 +00:00
|
|
|
@export var level: int
|
|
|
|
var ruins_spots: Array[Vector2i]
|
2024-09-24 01:07:44 +00:00
|
|
|
var error_pings: Dictionary
|
2024-09-14 22:01:46 +00:00
|
|
|
|
|
|
|
var building_data = {}
|
2024-09-15 02:20:30 +00:00
|
|
|
var last_tile
|
|
|
|
var last_text
|
2024-09-15 08:43:56 +00:00
|
|
|
var last_food_text
|
|
|
|
var last_water_text
|
2024-09-15 03:33:24 +00:00
|
|
|
var rand = 0
|
2024-09-14 22:01:46 +00:00
|
|
|
|
2024-09-15 02:20:30 +00:00
|
|
|
const NAME_ICON = preload("res://NameIcon.tscn")
|
2024-09-15 07:29:19 +00:00
|
|
|
const RESOURCE_GAIN = preload("res://ResourceGain.tscn")
|
2024-09-24 01:07:44 +00:00
|
|
|
const ERROR_PING = preload("res://ErrorPing.tscn")
|
2024-09-14 22:01:46 +00:00
|
|
|
|
2024-09-15 03:33:24 +00:00
|
|
|
var building_to_tile_map = {
|
|
|
|
"tents": {
|
|
|
|
"source": 8,
|
|
|
|
"atlas": 0
|
|
|
|
},
|
|
|
|
"quarter": {
|
|
|
|
"source": 8,
|
|
|
|
"atlas": 1
|
|
|
|
},
|
|
|
|
"house": {
|
|
|
|
"source": 8,
|
|
|
|
"atlas": 2
|
|
|
|
},
|
|
|
|
"essencecompressor": {
|
2024-09-15 03:58:33 +00:00
|
|
|
"source": 9,
|
2024-09-15 03:33:24 +00:00
|
|
|
"atlas": 2
|
|
|
|
},
|
|
|
|
"woodcutter": {
|
2024-09-15 03:58:33 +00:00
|
|
|
"source": 9,
|
|
|
|
"atlas": 1
|
2024-09-15 03:33:24 +00:00
|
|
|
},
|
|
|
|
"stoneminer": {
|
2024-09-15 03:58:33 +00:00
|
|
|
"source": 9,
|
|
|
|
"atlas": 0
|
2024-09-15 03:33:24 +00:00
|
|
|
},
|
|
|
|
"foodgathering": {
|
|
|
|
"source": 7,
|
|
|
|
"atlas": 2
|
|
|
|
},
|
|
|
|
"foodprocessing": {
|
|
|
|
"source": 7,
|
|
|
|
"atlas": 3
|
|
|
|
},
|
|
|
|
"waterprocessor": {
|
|
|
|
"source": 7,
|
|
|
|
"atlas": 1
|
|
|
|
},
|
|
|
|
"waterpump": {
|
|
|
|
"source": 7,
|
|
|
|
"atlas": 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-14 22:01:46 +00:00
|
|
|
func _process(delta: float) -> void:
|
|
|
|
var tile = local_to_map(get_global_mouse_position())
|
|
|
|
var building_mode = Persister.get_value("building_mode")
|
|
|
|
|
|
|
|
for spot in building_spots:
|
2024-09-15 05:37:02 +00:00
|
|
|
if not building_data.has(spot) and not tree_spots.has(spot) and not rock_spots.has(spot) and not th_spots.has(spot) and not ruins_spots.has(spot):
|
2024-09-14 22:01:46 +00:00
|
|
|
erase_cell(spot)
|
|
|
|
|
2024-09-15 02:20:30 +00:00
|
|
|
if last_tile != tile:
|
|
|
|
if last_text and is_instance_valid(last_text) and last_text.selected:
|
|
|
|
last_text._deselect()
|
2024-09-15 08:43:56 +00:00
|
|
|
if last_food_text and is_instance_valid(last_food_text) and last_food_text.selected:
|
|
|
|
last_food_text._deselect()
|
|
|
|
if last_water_text and is_instance_valid(last_water_text) and last_water_text.selected:
|
|
|
|
last_water_text._deselect()
|
2024-09-15 02:20:30 +00:00
|
|
|
|
2024-09-15 03:33:24 +00:00
|
|
|
rand = randi_range(0, 1)
|
|
|
|
|
2024-09-15 09:40:28 +00:00
|
|
|
if not Persister.get_value("building_mode") and Persister.get_value("flood_level", PersisterEnums.Scope.UNKNOWN, 0) < level:
|
2024-09-15 02:20:30 +00:00
|
|
|
if rock_spots.has(tile):
|
|
|
|
last_text = NAME_ICON.instantiate()
|
|
|
|
last_text.text = "[center]Rock"
|
|
|
|
last_text.position = map_to_local(tile) + Vector2(-25, -10)
|
|
|
|
add_sibling(last_text)
|
|
|
|
elif tree_spots.has(tile):
|
|
|
|
last_text = NAME_ICON.instantiate()
|
|
|
|
last_text.text = "[center]Tree"
|
|
|
|
last_text.position = map_to_local(tile) + Vector2(-25, -10)
|
|
|
|
add_sibling(last_text)
|
2024-09-15 04:46:49 +00:00
|
|
|
elif th_spots.has(tile):
|
|
|
|
last_text = NAME_ICON.instantiate()
|
|
|
|
last_text.text = "[center]Town Hall"
|
2024-09-15 08:43:56 +00:00
|
|
|
last_text.position = map_to_local(tile) + Vector2(-25, -30)
|
2024-09-15 04:46:49 +00:00
|
|
|
add_sibling(last_text)
|
2024-09-15 08:43:56 +00:00
|
|
|
last_food_text = NAME_ICON.instantiate()
|
|
|
|
last_food_text.text = "[center]%d Food" % [Persister.get_value("food")]
|
|
|
|
last_food_text.position = map_to_local(tile) + Vector2(-25, -20)
|
|
|
|
add_sibling(last_food_text)
|
|
|
|
last_water_text = NAME_ICON.instantiate()
|
|
|
|
last_water_text.text = "[center]%d Water" % [Persister.get_value("water")]
|
|
|
|
last_water_text.position = map_to_local(tile) + Vector2(-25, -10)
|
|
|
|
add_sibling(last_water_text)
|
2024-09-15 05:37:02 +00:00
|
|
|
elif ruins_spots.has(tile):
|
|
|
|
last_text = NAME_ICON.instantiate()
|
|
|
|
last_text.text = "[center]Ruins"
|
|
|
|
last_text.position = map_to_local(tile) + Vector2(-25, -10)
|
|
|
|
add_sibling(last_text)
|
2024-09-15 02:20:30 +00:00
|
|
|
elif building_data.has(tile):
|
|
|
|
last_text = NAME_ICON.instantiate()
|
|
|
|
last_text.text = "[center]%s" % [Data.data.buildings[building_data[tile].key].name]
|
|
|
|
last_text.position = map_to_local(tile) + Vector2(-25, -10)
|
|
|
|
add_sibling(last_text)
|
|
|
|
|
2024-09-15 07:29:19 +00:00
|
|
|
for coords in building_data:
|
|
|
|
var building = building_data[coords]
|
|
|
|
if building.has("workers") and building.workers > 0 and (not Data.data.buildings[building.key].has("needs") or (Persister.get_value(Data.data.buildings[building.key].needs, PersisterEnums.Scope.UNKNOWN, 0) > 0)):
|
|
|
|
building.progress += delta * building.efficiency / 100.0
|
|
|
|
|
|
|
|
if building.progress >= Data.data.buildings[building.key].time:
|
|
|
|
if Data.data.buildings[building.key].has("needs"):
|
|
|
|
Persister.change_value(Data.data.buildings[building.key].needs, -1)
|
|
|
|
Persister.change_value(Data.data.buildings[building.key].resource, Data.data.buildings[building.key].amount)
|
|
|
|
var gain = RESOURCE_GAIN.instantiate()
|
|
|
|
gain.text = "[center]+1 %s" % [Data.data.buildings[building.key].resourcename]
|
2024-09-15 08:58:02 +00:00
|
|
|
gain.position = map_to_local(coords) + Vector2(-60, -5)
|
2024-09-15 07:29:19 +00:00
|
|
|
add_sibling(gain)
|
|
|
|
building.progress -= Data.data.buildings[building.key].time
|
|
|
|
|
|
|
|
if building.has("workers"):
|
|
|
|
var close_bonus = 1.0
|
|
|
|
|
2024-09-24 01:07:44 +00:00
|
|
|
if building.workers == 0 and not error_pings.has(coords):
|
|
|
|
var new_ping = ERROR_PING.instantiate()
|
|
|
|
new_ping.type = "workers"
|
|
|
|
new_ping.position = map_to_local(coords) + Vector2(2, -10)
|
|
|
|
add_sibling(new_ping)
|
|
|
|
error_pings[coords] = new_ping
|
|
|
|
elif building.workers != 0 and error_pings.has(coords) and error_pings[coords].type == "workers":
|
|
|
|
error_pings[coords].queue_free()
|
|
|
|
error_pings.erase(coords)
|
|
|
|
|
2024-09-15 07:29:19 +00:00
|
|
|
if building.key == "woodcutter":
|
|
|
|
if tree_spots.size() == 0:
|
|
|
|
close_bonus = 0
|
|
|
|
else:
|
|
|
|
var min_distance = INF
|
|
|
|
for tree in tree_spots:
|
|
|
|
var distance = tree.distance_to(coords)
|
|
|
|
|
|
|
|
if distance < min_distance:
|
|
|
|
min_distance = distance
|
|
|
|
|
|
|
|
if min_distance > 5:
|
|
|
|
close_bonus = 0
|
|
|
|
else:
|
|
|
|
close_bonus = 1 - (min_distance / 5)
|
|
|
|
elif building.key == "stoneminer":
|
|
|
|
if rock_spots.size() == 0:
|
|
|
|
close_bonus = 0
|
|
|
|
else:
|
|
|
|
var min_distance = INF
|
|
|
|
for tree in rock_spots:
|
|
|
|
var distance = tree.distance_to(coords)
|
|
|
|
|
|
|
|
if distance < min_distance:
|
|
|
|
min_distance = distance
|
|
|
|
|
|
|
|
if min_distance > 5:
|
|
|
|
close_bonus = 0
|
|
|
|
else:
|
|
|
|
close_bonus = 1 - (min_distance / 5)
|
|
|
|
elif building.key == "waterpump":
|
|
|
|
var water_level = Persister.get_value("flood_level", PersisterEnums.Scope.UNKNOWN, 0)
|
|
|
|
|
|
|
|
var amount = level - water_level
|
|
|
|
|
|
|
|
if amount > 3:
|
|
|
|
close_bonus = 0
|
|
|
|
else:
|
|
|
|
close_bonus = (3 - amount)
|
|
|
|
|
|
|
|
building.efficiency = (100 + Persister.get_value("conduit_bonus", PersisterEnums.Scope.UNKNOWN, 0)) * building.workers * 0.5 * close_bonus
|
2024-09-24 01:07:44 +00:00
|
|
|
|
|
|
|
if building.efficiency == 0 and not building.workers == 0 and not error_pings.has(coords):
|
|
|
|
var new_ping = ERROR_PING.instantiate()
|
|
|
|
new_ping.type = "resources"
|
|
|
|
new_ping.position = map_to_local(coords) + Vector2(2, -10)
|
|
|
|
add_sibling(new_ping)
|
|
|
|
error_pings[coords] = new_ping
|
|
|
|
elif (building.efficiency != 0 or building.workers == 0) and error_pings.has(coords) and error_pings[coords].type == "resources":
|
|
|
|
error_pings[coords].queue_free()
|
|
|
|
error_pings.erase(coords)
|
2024-09-15 07:29:19 +00:00
|
|
|
|
2024-09-15 02:20:30 +00:00
|
|
|
last_tile = tile
|
|
|
|
|
2024-09-14 22:01:46 +00:00
|
|
|
if not building_mode:
|
|
|
|
return
|
|
|
|
|
2024-09-15 05:37:02 +00:00
|
|
|
if building_spots.has(tile) and not rock_spots.has(tile) and not tree_spots.has(tile) and not th_spots.has(tile) and not building_data.has(tile) and not ruins_spots.has(tile):
|
2024-09-15 03:33:24 +00:00
|
|
|
var build_data = building_to_tile_map[Persister.get_value("building_key")]
|
|
|
|
set_cell(tile, build_data["source"], Vector2i(build_data["atlas"],rand), 0)
|
2024-09-15 02:20:30 +00:00
|
|
|
|
|
|
|
|
2024-09-14 22:01:46 +00:00
|
|
|
|
2024-09-15 05:37:02 +00:00
|
|
|
func _ready() -> void:
|
|
|
|
Triggerer.listen("flood_level", _on_flood_level)
|
|
|
|
|
|
|
|
|
2024-09-15 07:29:19 +00:00
|
|
|
|
2024-09-15 05:37:02 +00:00
|
|
|
func _on_flood_level(data):
|
|
|
|
var value = int(data.value)
|
|
|
|
|
|
|
|
if value >= level:
|
|
|
|
for coords in building_data:
|
|
|
|
var building = building_data[coords]
|
|
|
|
var build_data = Data.data.buildings[building.key]
|
|
|
|
var bttm = building_to_tile_map[building.key]
|
|
|
|
|
|
|
|
var atlas = bttm.atlas
|
|
|
|
var source
|
|
|
|
|
|
|
|
match build_data.type:
|
|
|
|
"utility":
|
|
|
|
source = 11
|
|
|
|
"housing":
|
|
|
|
source = 12
|
|
|
|
"production":
|
|
|
|
source = 10
|
|
|
|
|
2024-09-15 07:43:45 +00:00
|
|
|
if building.has("workers"):
|
|
|
|
Persister.change_value("avail_population", building.workers)
|
|
|
|
elif build_data.type == "housing":
|
2024-09-24 00:36:55 +00:00
|
|
|
Persister.change_value("max_population", -build_data.amount)
|
2024-09-15 07:43:45 +00:00
|
|
|
|
2024-09-15 05:37:02 +00:00
|
|
|
ruins_spots.push_back(coords)
|
|
|
|
set_cell(coords, source, Vector2i(atlas,building.rand), 0)
|
|
|
|
building_data.clear()
|
2024-09-24 01:07:44 +00:00
|
|
|
|
|
|
|
for error_ping in error_pings:
|
|
|
|
error_pings[error_ping].queue_free()
|
|
|
|
error_pings.clear()
|
2024-09-14 22:01:46 +00:00
|
|
|
|
2024-09-15 07:43:45 +00:00
|
|
|
|
|
|
|
func kill_citizen():
|
|
|
|
for coords in building_data:
|
|
|
|
var building = building_data[coords]
|
|
|
|
|
|
|
|
if building.has("workers") and building.workers > 0:
|
|
|
|
building.workers -= 1
|
|
|
|
return true
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
|
2024-09-23 23:59:35 +00:00
|
|
|
func pick_block():
|
|
|
|
if Persister.get_value("win") or Persister.get_value("lose"):
|
|
|
|
return
|
|
|
|
|
|
|
|
var tile = local_to_map(get_global_mouse_position())
|
|
|
|
|
|
|
|
if building_data.has(tile):
|
|
|
|
var data = Data.data.buildings[building_data[tile].key]
|
|
|
|
if (not data.cost.has("wood") or int(data.cost.wood) <= Persister.get_value("wood")) and (not data.cost.has("stone") or int(data.cost.stone) <= Persister.get_value("stone")):
|
|
|
|
Persister.persist_data("building_mode", true)
|
|
|
|
Persister.persist_data("building_key", building_data[tile].key)
|
|
|
|
|
|
|
|
|
2024-09-24 00:36:55 +00:00
|
|
|
func destroy(tile: Vector2i):
|
|
|
|
if building_data.has(tile):
|
|
|
|
var building = building_data[tile]
|
|
|
|
var build_data = Data.data.buildings[building.key]
|
|
|
|
if building.has("workers"):
|
|
|
|
Persister.change_value("avail_population", building.workers)
|
|
|
|
elif build_data.type == "housing":
|
|
|
|
Persister.change_value("max_population", -build_data.amount)
|
|
|
|
building_data.erase(tile)
|
|
|
|
ruins_spots = ruins_spots.filter(func(coords): return coords != tile)
|
2024-09-24 01:07:44 +00:00
|
|
|
if error_pings.has(tile):
|
|
|
|
error_pings[tile].queue_free()
|
|
|
|
error_pings.erase(tile)
|
2024-09-24 00:36:55 +00:00
|
|
|
|
|
|
|
|
2024-09-14 22:01:46 +00:00
|
|
|
func place_building():
|
2024-09-15 08:43:56 +00:00
|
|
|
if Persister.get_value("win") or Persister.get_value("lose"):
|
|
|
|
return
|
|
|
|
|
2024-09-14 22:01:46 +00:00
|
|
|
var tile = local_to_map(get_global_mouse_position())
|
2024-09-24 00:36:55 +00:00
|
|
|
if building_spots.has(tile) and not building_data.has(tile) and not tree_spots.has(tile) and not rock_spots.has(tile) and not th_spots.has(tile):
|
2024-09-14 22:01:46 +00:00
|
|
|
Persister.persist_data("building_mode", false)
|
|
|
|
building_data[tile] = {
|
|
|
|
"key": Persister.get_value("building_key"),
|
2024-09-15 06:15:37 +00:00
|
|
|
"rand": rand,
|
2024-09-24 00:36:55 +00:00
|
|
|
"level": level,
|
|
|
|
"coords": tile
|
2024-09-14 22:01:46 +00:00
|
|
|
}
|
2024-09-15 04:22:02 +00:00
|
|
|
|
2024-09-15 04:25:59 +00:00
|
|
|
var build_data = Data.data.buildings[Persister.get_value("building_key")]
|
|
|
|
var cost = build_data.cost
|
2024-09-15 04:22:02 +00:00
|
|
|
|
|
|
|
if cost.has("wood"):
|
|
|
|
Persister.change_value("wood", -int(cost.wood))
|
|
|
|
if cost.has("stone"):
|
|
|
|
Persister.change_value("stone", -int(cost.stone))
|
2024-09-15 04:25:59 +00:00
|
|
|
|
|
|
|
if build_data.type == "housing":
|
|
|
|
Persister.change_value("max_population", int(build_data.amount))
|
|
|
|
building_data[tile].max_population = int(build_data.amount)
|
2024-09-15 07:29:19 +00:00
|
|
|
elif build_data.name != "Conduit":
|
2024-09-15 06:15:37 +00:00
|
|
|
building_data[tile].workers = 0
|
|
|
|
building_data[tile].max_workers = 6
|
2024-09-15 07:29:19 +00:00
|
|
|
building_data[tile].efficiency = 100 + Persister.get_value("conduit_bonus", PersisterEnums.Scope.UNKNOWN, 0)
|
|
|
|
building_data[tile].progress = 0
|
|
|
|
else:
|
|
|
|
Persister.change_value("conduit_bonus", 20)
|
2024-09-14 22:01:46 +00:00
|
|
|
|
|
|
|
Persister.persist_data("drag_mode", false)
|
|
|
|
|
|
|
|
|
|
|
|
func show_info_building():
|
|
|
|
var tile = local_to_map(get_global_mouse_position())
|
|
|
|
if building_data.has(tile):
|
|
|
|
Triggerer.trigger("show_info", building_data[tile])
|
2024-09-24 00:36:55 +00:00
|
|
|
elif ruins_spots.has(tile):
|
|
|
|
Triggerer.trigger("show_info", {
|
|
|
|
"key": "ruins",
|
|
|
|
"coords": tile,
|
|
|
|
"level": level
|
|
|
|
})
|