diff --git a/art/tiles/FG_Village.png b/art/tiles/FG_Village.png new file mode 100644 index 0000000..1cda3bf Binary files /dev/null and b/art/tiles/FG_Village.png differ diff --git a/art/tiles/FG_Village.png.import b/art/tiles/FG_Village.png.import new file mode 100644 index 0000000..b91e293 --- /dev/null +++ b/art/tiles/FG_Village.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cbqcq5n5iy737" +path="res://.godot/imported/FG_Village.png-cc0ade50cce054d39cffc82cfd873349.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/FG_Village.png" +dest_files=["res://.godot/imported/FG_Village.png-cc0ade50cce054d39cffc82cfd873349.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/entities/door.gd b/scenes/entities/door.gd index 86b5d41..9fc1556 100644 --- a/scenes/entities/door.gd +++ b/scenes/entities/door.gd @@ -13,12 +13,14 @@ class_name Door extends Node2D ## complete: it registers with World for future open/close logic, does NOT ## call set_cell_walkable(false), and transitions from ghost to solid. ## -## Render: a 32×32 closed-wood-door sprite from FG_Fortress (atlas (4..5, 19..20)) -## is bottom-anchored on the door tile. The sprite is 2 tiles wide so the stone -## arch extends 8 px into each flanking tile — which is correct, since walls -## typically sit on those tiles and the arch is supposed to merge into them. -## The sprite is 2 tiles tall so the lintel rises one tile above the door tile -## (matching Wall's bottom-anchored sprite convention). +## Render: a 16×16 olive-wood cabin door sprite from FG_Village (atlas (3, 24)) +## is bottom-anchored on the door tile. The sprite occupies exactly one tile — +## same footprint as the surrounding wall, no overhang into neighbours — so +## a 1-tile gap in a wall reads cleanly as "door here". +## +## The previous pick was the 32×32 FG_Fortress stone-arch gate at (4, 19): a +## proper castle entrance, far too imposing for a cabin's front door. Swapped +## 2026-05-12 after the user flagged it as "a door for a entrance to a castle". ## ## World registration: World.register_build_site / World.unregister_build_site ## are called from _ready / _exit_tree. Methods land in the Opus integration pass. @@ -28,12 +30,11 @@ const TILE_SIZE_PX: int = 16 ## Sim ticks to build a door at 1× speed (80 ticks = 4 sim seconds). const BUILD_TICKS: int = 80 -## ElvGames Fortress atlas. Stone-arched closed wooden door — top-left of the -## 32×32 region at (4, 19); covers tiles (4..5, 19..20). -const _DOOR_TEX: Texture2D = preload("res://art/tiles/FG_Fortress.png") -const _DOOR_COORD: Vector2i = Vector2i(4, 19) -const _DOOR_W_TILES: int = 2 -const _DOOR_H_TILES: int = 2 +## ElvGames Village atlas. Single-tile olive-wood cabin door with a white +## U-shaped handle at (3, 24) — extracted from the red-roofed cottage template +## on FG_Village. See /tmp/village_just_3_24.png for the standalone preview. +const _DOOR_TEX: Texture2D = preload("res://art/tiles/FG_Village.png") +const _DOOR_COORD: Vector2i = Vector2i(3, 24) # ── state ────────────────────────────────────────────────────────────────────── @@ -72,10 +73,10 @@ func setup(p_tile: Vector2i) -> void: Audit.log("door", "door ghost placed at %s" % tile) -## Builds the 32×32 FG_Fortress closed-door Sprite2D child. Bottom-anchored -## so it sits flush with the door tile's bottom edge — the lintel rises into -## the tile above and the stone arch extends one half-tile into each adjacent -## tile. Idempotent: re-running drops the previous sprite first. +## Builds the 16×16 FG_Village cabin-door Sprite2D child. Bottom-anchored so the +## door sits flush with the tile's bottom edge, matching Wall's convention so +## Y-sort layers pawns correctly relative to it. Idempotent: re-running drops +## the previous sprite first. func _build_sprite() -> void: var prev := get_node_or_null("Sprite") if prev != null: @@ -84,19 +85,17 @@ func _build_sprite() -> void: sprite.name = "Sprite" sprite.texture = _DOOR_TEX sprite.region_enabled = true - var pixels_w: int = TILE_SIZE_PX * _DOOR_W_TILES - var pixels_h: int = TILE_SIZE_PX * _DOOR_H_TILES sprite.region_rect = Rect2( _DOOR_COORD.x * TILE_SIZE_PX, _DOOR_COORD.y * TILE_SIZE_PX, - pixels_w, - pixels_h, + TILE_SIZE_PX, + TILE_SIZE_PX, ) sprite.centered = true - # Centred at (0, -16): bottom edge of sprite at y=0 (= tile bottom), top at - # y=-32. Horizontally centred so the 32-wide sprite extends ±16 px around - # the door tile's centre, overlapping the two neighbouring wall tiles. - sprite.offset = Vector2(0.0, -float(pixels_h) / 2.0) + # Sprite center at y=-8 so the 16×16 region spans y=-16..0 — flush against + # the bottom edge of the door tile (matches Wall._build_stone_sprite). No + # horizontal overhang into neighbouring tiles. + sprite.offset = Vector2(0.0, -8.0) sprite.z_index = 0 # Ghost state — translucent until built. Solidified in _complete(). sprite.modulate.a = 1.0 if _completed else 0.4 @@ -155,9 +154,9 @@ static func from_dict(d: Dictionary) -> Dictionary: func _draw() -> void: # Door body is rendered by the Sprite2D child (see _build_sprite()). - # No procedural overlay needed — the FG_Fortress closed-door sprite already - # shows the wood panels, stone arch, and lintel. Ghost alpha is handled - # via sprite.modulate.a in _build_sprite / _complete. + # No procedural overlay needed — the FG_Village cabin-door sprite already + # shows the wood planks and U-handle. Ghost alpha is handled via + # sprite.modulate.a in _build_sprite / _complete. pass