init
This commit is contained in:
commit
e45f121fb9
89 changed files with 336069 additions and 0 deletions
135
demo/scripts/bake_dungeon.gd
Normal file
135
demo/scripts/bake_dungeon.gd
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
extends SceneTree
|
||||
|
||||
# Usage:
|
||||
# godot --headless --path demo --script scripts/bake_dungeon.gd -- SEED DEPTH OUT_DIR
|
||||
#
|
||||
# Shells out to bin/genesis --emit=json and bakes the result into two sibling
|
||||
# assets under OUT_DIR:
|
||||
# - mesh_library.tres (tile catalog, same content MLB.build()
|
||||
# produces at runtime — shareable across bakes)
|
||||
# - dungeon_seed<S>_depth<D>.tscn (PackedScene with a GridMap referencing
|
||||
# the MeshLibrary, populated per the
|
||||
# generated dungeon)
|
||||
#
|
||||
# Override the genesis binary path with the GENESIS_BIN env var; default is
|
||||
# "../bin/genesis" relative to the Godot project.
|
||||
|
||||
const MESH_LIB_NAME := "mesh_library.tres"
|
||||
const MLB = preload("res://scripts/mesh_library_builder.gd")
|
||||
|
||||
func _init() -> void:
|
||||
var args := OS.get_cmdline_user_args()
|
||||
if args.size() != 3:
|
||||
push_error("usage: -- SEED DEPTH OUT_DIR")
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var seed := int(args[0])
|
||||
var depth := int(args[1])
|
||||
var out_dir := args[2]
|
||||
|
||||
var bin_path := OS.get_environment("GENESIS_BIN")
|
||||
if bin_path == "":
|
||||
bin_path = ProjectSettings.globalize_path("res://") + "../bin/genesis"
|
||||
bin_path = bin_path.simplify_path()
|
||||
|
||||
if not DirAccess.dir_exists_absolute(out_dir):
|
||||
var err := DirAccess.make_dir_recursive_absolute(out_dir)
|
||||
if err != OK:
|
||||
push_error("cannot create %s (err %d)" % [out_dir, err])
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var stdout: Array = []
|
||||
var exit_code := OS.execute(bin_path, [
|
||||
"--seed", str(seed), "--depth", str(depth), "--emit=json",
|
||||
], stdout, true)
|
||||
if exit_code != 0:
|
||||
push_error("genesis exited %d (bin=%s)" % [exit_code, bin_path])
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var grid: Dictionary = JSON.parse_string(stdout[0])
|
||||
if grid.is_empty():
|
||||
push_error("genesis produced invalid JSON")
|
||||
quit(1)
|
||||
return
|
||||
|
||||
# Step 1 — MeshLibrary.tres.
|
||||
var lib_path := "%s/%s" % [out_dir, MESH_LIB_NAME]
|
||||
var save_err := MLB.save_resource(lib_path, true)
|
||||
if save_err != OK:
|
||||
push_error("failed to save %s (err %d)" % [lib_path, save_err])
|
||||
quit(1)
|
||||
return
|
||||
|
||||
# Step 2 — PackedScene with populated GridMap.
|
||||
var lib: MeshLibrary = load(lib_path)
|
||||
var root := Node3D.new()
|
||||
root.name = "Dungeon_seed%d_depth%d" % [seed, depth]
|
||||
var gm := GridMap.new()
|
||||
gm.name = "GridMap"
|
||||
gm.mesh_library = lib
|
||||
gm.cell_size = Vector3(1, 1, 1)
|
||||
root.add_child(gm)
|
||||
gm.owner = root
|
||||
|
||||
var cells_set := _populate(gm, grid)
|
||||
|
||||
var packed := PackedScene.new()
|
||||
var pack_err := packed.pack(root)
|
||||
if pack_err != OK:
|
||||
push_error("failed to pack scene (err %d)" % pack_err)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var scn_path := "%s/dungeon_seed%d_depth%d.tscn" % [out_dir, seed, depth]
|
||||
var scn_err := ResourceSaver.save(packed, scn_path)
|
||||
if scn_err != OK:
|
||||
push_error("failed to save %s (err %d)" % [scn_path, scn_err])
|
||||
quit(1)
|
||||
return
|
||||
|
||||
print("wrote %s + %s — %d cells" % [scn_path, lib_path, cells_set])
|
||||
quit(0)
|
||||
|
||||
# Decode the base64 layers and stamp tile IDs into the GridMap. Mirrors
|
||||
# arcade_scene.gd _populate_grid_map so the CLI produces the same geometry
|
||||
# as the in-engine path for the same seed/depth. Chasms stay as empty cells.
|
||||
func _populate(gm: GridMap, grid: Dictionary) -> int:
|
||||
var w := int(grid["width"])
|
||||
var h := int(grid["height"])
|
||||
var terrain := Marshalls.base64_to_raw(grid["terrain"])
|
||||
var liquid := Marshalls.base64_to_raw(grid["liquid"])
|
||||
|
||||
var count := 0
|
||||
for y in range(h):
|
||||
for x in range(w):
|
||||
var idx := y * w + x
|
||||
var t := terrain[idx]
|
||||
var liq := liquid[idx]
|
||||
if t == 5 and liq == 3: # T_LIQUID + L_CHASM
|
||||
continue
|
||||
var tile := _tile_for(t, liq)
|
||||
if tile < 0:
|
||||
continue
|
||||
gm.set_cell_item(Vector3i(x, 0, y), tile)
|
||||
count += 1
|
||||
return count
|
||||
|
||||
func _tile_for(terrain: int, liquid: int) -> int:
|
||||
match terrain:
|
||||
1: return MLB.TILE_FLOOR
|
||||
4: return MLB.TILE_CORRIDOR
|
||||
3: return MLB.TILE_DOOR
|
||||
2: return MLB.TILE_WALL
|
||||
6: return MLB.TILE_BRIDGE
|
||||
7: return MLB.TILE_STAIRS_UP
|
||||
8: return MLB.TILE_STAIRS_DOWN
|
||||
5:
|
||||
match liquid:
|
||||
1: return MLB.TILE_WATER
|
||||
2: return MLB.TILE_LAVA
|
||||
4: return MLB.TILE_BRIMSTONE
|
||||
_: return MLB.TILE_WATER
|
||||
_: return -1
|
||||
Loading…
Add table
Add a link
Reference in a new issue