feat(engine): Add Building and Improvement entity classes with core mechanics and properties

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-03-25 23:53:21 -07:00
parent 8148272564
commit ea7d5a33af
2 changed files with 47 additions and 3 deletions

View file

@ -1,2 +1,46 @@
class_name Building
extends RefCounted
## Game entity for both city buildings and map-placed NPC buildings (lairs, villages, ruins).
## City buildings: placement="city", owner=player_index, position=city tile.
## NPC buildings: placement="map", owner=-1, position=map tile.
## Unique instance ID (e.g. "lair_42", "building_granary_3")
var id: String = ""
## Building type ID from data (e.g. "beast_den", "granary", "village", "ruin")
var type_id: String = ""
## Display name resolved from data
var name: String = ""
## "map" for NPC buildings placed on the world map, "city" for city buildings
var placement: String = "city"
## Owning player index. -1 = unowned (NPC / world)
var owner: int = -1
## Map position (axial coordinates). Meaningful for placement="map".
var position: Vector2i = Vector2i.ZERO
## Whether this building has been visited/explored by a player
var visited: bool = false
static func from_dict(data: Dictionary) -> Building:
var b := Building.new()
b.id = data.get("id", "")
b.type_id = data.get("type_id", "")
b.name = data.get("name", "")
b.placement = data.get("placement", "city")
b.owner = data.get("owner", -1)
var pos: Array = data.get("position", [0, 0])
if pos.size() >= 2:
b.position = Vector2i(int(pos[0]), int(pos[1]))
b.visited = data.get("visited", false)
return b
func to_dict() -> Dictionary:
return {
"id": id,
"type_id": type_id,
"name": name,
"placement": placement,
"owner": owner,
"position": [position.x, position.y],
"visited": visited,
}

View file

@ -105,7 +105,7 @@ static func _get_data(improvement_type: String) -> Dictionary:
return FALLBACK_DATA.get(improvement_type, {})
static func can_build(improvement_type: String, terrain_id: String) -> bool:
static func can_build(improvement_type: String, biome_id: String) -> bool:
## Check if this improvement can be placed on the given terrain.
var data: Dictionary = _get_data(improvement_type)
if data.is_empty():
@ -115,10 +115,10 @@ static func can_build(improvement_type: String, terrain_id: String) -> bool:
# "any_land" allows any non-water terrain
if valid is String and valid == "any_land":
return terrain_id != "ocean"
return biome_id != "ocean"
if valid is Array:
return terrain_id in valid
return biome_id in valid
return false