Door sprite — swap castle gate for 1-tile FG_Village cabin door
The previous 32×32 FG_Fortress arched gate at (4,19) was rejected as 'a door for a entrance to a castle' — too imposing for a cabin's front door. Pivot: FG_Village atlas (3, 24) — a single 16×16 olive-wood plank door with a white U-handle, extracted from the red-roofed cottage template. Sprite occupies one tile (no overhang, no rising lintel), bottom-anchored the same as Wall so Y-sort layers pawns correctly. Verified in MCP play_scene: the door slots cleanly into the demo cabin's south-wall gap at (47, 28), matching the surrounding stone-brick wall height. Ghost-alpha pipeline (0.4 in-build → 1.0 on _complete) intact. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ac21443037
commit
745ab29c51
3 changed files with 66 additions and 27 deletions
BIN
art/tiles/FG_Village.png
Normal file
BIN
art/tiles/FG_Village.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
40
art/tiles/FG_Village.png.import
Normal file
40
art/tiles/FG_Village.png.import
Normal file
|
|
@ -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
|
||||||
|
|
@ -13,12 +13,14 @@ class_name Door extends Node2D
|
||||||
## complete: it registers with World for future open/close logic, does NOT
|
## complete: it registers with World for future open/close logic, does NOT
|
||||||
## call set_cell_walkable(false), and transitions from ghost to solid.
|
## 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))
|
## Render: a 16×16 olive-wood cabin door sprite from FG_Village (atlas (3, 24))
|
||||||
## is bottom-anchored on the door tile. The sprite is 2 tiles wide so the stone
|
## is bottom-anchored on the door tile. The sprite occupies exactly one tile —
|
||||||
## arch extends 8 px into each flanking tile — which is correct, since walls
|
## same footprint as the surrounding wall, no overhang into neighbours — so
|
||||||
## typically sit on those tiles and the arch is supposed to merge into them.
|
## a 1-tile gap in a wall reads cleanly as "door here".
|
||||||
## The sprite is 2 tiles tall so the lintel rises one tile above the door tile
|
##
|
||||||
## (matching Wall's bottom-anchored sprite convention).
|
## 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
|
## World registration: World.register_build_site / World.unregister_build_site
|
||||||
## are called from _ready / _exit_tree. Methods land in the Opus integration pass.
|
## 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).
|
## Sim ticks to build a door at 1× speed (80 ticks = 4 sim seconds).
|
||||||
const BUILD_TICKS: int = 80
|
const BUILD_TICKS: int = 80
|
||||||
|
|
||||||
## ElvGames Fortress atlas. Stone-arched closed wooden door — top-left of the
|
## ElvGames Village atlas. Single-tile olive-wood cabin door with a white
|
||||||
## 32×32 region at (4, 19); covers tiles (4..5, 19..20).
|
## U-shaped handle at (3, 24) — extracted from the red-roofed cottage template
|
||||||
const _DOOR_TEX: Texture2D = preload("res://art/tiles/FG_Fortress.png")
|
## on FG_Village. See /tmp/village_just_3_24.png for the standalone preview.
|
||||||
const _DOOR_COORD: Vector2i = Vector2i(4, 19)
|
const _DOOR_TEX: Texture2D = preload("res://art/tiles/FG_Village.png")
|
||||||
const _DOOR_W_TILES: int = 2
|
const _DOOR_COORD: Vector2i = Vector2i(3, 24)
|
||||||
const _DOOR_H_TILES: int = 2
|
|
||||||
|
|
||||||
# ── state ──────────────────────────────────────────────────────────────────────
|
# ── state ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -72,10 +73,10 @@ func setup(p_tile: Vector2i) -> void:
|
||||||
Audit.log("door", "door ghost placed at %s" % tile)
|
Audit.log("door", "door ghost placed at %s" % tile)
|
||||||
|
|
||||||
|
|
||||||
## Builds the 32×32 FG_Fortress closed-door Sprite2D child. Bottom-anchored
|
## Builds the 16×16 FG_Village cabin-door Sprite2D child. Bottom-anchored so the
|
||||||
## so it sits flush with the door tile's bottom edge — the lintel rises into
|
## door sits flush with the tile's bottom edge, matching Wall's convention so
|
||||||
## the tile above and the stone arch extends one half-tile into each adjacent
|
## Y-sort layers pawns correctly relative to it. Idempotent: re-running drops
|
||||||
## tile. Idempotent: re-running drops the previous sprite first.
|
## the previous sprite first.
|
||||||
func _build_sprite() -> void:
|
func _build_sprite() -> void:
|
||||||
var prev := get_node_or_null("Sprite")
|
var prev := get_node_or_null("Sprite")
|
||||||
if prev != null:
|
if prev != null:
|
||||||
|
|
@ -84,19 +85,17 @@ func _build_sprite() -> void:
|
||||||
sprite.name = "Sprite"
|
sprite.name = "Sprite"
|
||||||
sprite.texture = _DOOR_TEX
|
sprite.texture = _DOOR_TEX
|
||||||
sprite.region_enabled = true
|
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(
|
sprite.region_rect = Rect2(
|
||||||
_DOOR_COORD.x * TILE_SIZE_PX,
|
_DOOR_COORD.x * TILE_SIZE_PX,
|
||||||
_DOOR_COORD.y * TILE_SIZE_PX,
|
_DOOR_COORD.y * TILE_SIZE_PX,
|
||||||
pixels_w,
|
TILE_SIZE_PX,
|
||||||
pixels_h,
|
TILE_SIZE_PX,
|
||||||
)
|
)
|
||||||
sprite.centered = true
|
sprite.centered = true
|
||||||
# Centred at (0, -16): bottom edge of sprite at y=0 (= tile bottom), top at
|
# Sprite center at y=-8 so the 16×16 region spans y=-16..0 — flush against
|
||||||
# y=-32. Horizontally centred so the 32-wide sprite extends ±16 px around
|
# the bottom edge of the door tile (matches Wall._build_stone_sprite). No
|
||||||
# the door tile's centre, overlapping the two neighbouring wall tiles.
|
# horizontal overhang into neighbouring tiles.
|
||||||
sprite.offset = Vector2(0.0, -float(pixels_h) / 2.0)
|
sprite.offset = Vector2(0.0, -8.0)
|
||||||
sprite.z_index = 0
|
sprite.z_index = 0
|
||||||
# Ghost state — translucent until built. Solidified in _complete().
|
# Ghost state — translucent until built. Solidified in _complete().
|
||||||
sprite.modulate.a = 1.0 if _completed else 0.4
|
sprite.modulate.a = 1.0 if _completed else 0.4
|
||||||
|
|
@ -155,9 +154,9 @@ static func from_dict(d: Dictionary) -> Dictionary:
|
||||||
|
|
||||||
func _draw() -> void:
|
func _draw() -> void:
|
||||||
# Door body is rendered by the Sprite2D child (see _build_sprite()).
|
# Door body is rendered by the Sprite2D child (see _build_sprite()).
|
||||||
# No procedural overlay needed — the FG_Fortress closed-door sprite already
|
# No procedural overlay needed — the FG_Village cabin-door sprite already
|
||||||
# shows the wood panels, stone arch, and lintel. Ghost alpha is handled
|
# shows the wood planks and U-handle. Ghost alpha is handled via
|
||||||
# via sprite.modulate.a in _build_sprite / _complete.
|
# sprite.modulate.a in _build_sprite / _complete.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue