331 lines
7.9 KiB
GDScript
331 lines
7.9 KiB
GDScript
extends Spatial
|
|
|
|
enum {OPEN_UP, OPEN_DOWN, OPEN_LEFT, OPEN_RIGHT}
|
|
|
|
var bitflags = 0
|
|
const BITUP = (1 << 0)
|
|
const BITDOWN = (1 << 1)
|
|
const BITLEFT = (1 << 2)
|
|
const BITRIGHT = (1 << 3)
|
|
var exits = []
|
|
var windows = []
|
|
var outside_doors = []
|
|
|
|
var door = preload("res://scenes/maps/door.tscn")
|
|
var jail_door = preload("res://scenes/maps/jail-door.tscn")
|
|
var window = preload("res://scenes/maps/window.tscn")
|
|
var outside_door = preload("res://scenes/maps/door-outside.tscn")
|
|
var stairs = preload("res://scenes/maps/stairs.tscn")
|
|
var outside_door_placed = false
|
|
var tw2d
|
|
var te2d
|
|
var tn2d
|
|
var ts2d
|
|
|
|
var furniture_data = {}
|
|
var save_data = {
|
|
"personal_room": false,
|
|
"kitchen_room": false,
|
|
"master_room": false,
|
|
"edit_room": false,
|
|
"jail_room": false,
|
|
"remove_iws": false,
|
|
'stairs': -1
|
|
}
|
|
|
|
func v2s(v: Vector3):
|
|
return str(v.x) + " " + str(v.y) + " " + str(v.z)
|
|
func xform2s(xform: Transform):
|
|
var v1 = xform.origin
|
|
var v2 = xform.basis[0]
|
|
var v3 = xform.basis[1]
|
|
var v4 = xform.basis[2]
|
|
var ret = ""
|
|
for v in [v1, v2, v3, v4]:
|
|
ret += v2s(v)
|
|
if v != v4:
|
|
ret += " "
|
|
return ret
|
|
func s2xform(s: String):
|
|
var vs = s.split(" ")
|
|
var fvs = []
|
|
for v in vs:
|
|
fvs.push_back(float(v))
|
|
var ret: = Transform()
|
|
ret.origin = Vector3(fvs[0], fvs[1], fvs[2])
|
|
ret.basis[0] = Vector3(fvs[3], fvs[4], fvs[5])
|
|
ret.basis[1] = Vector3(fvs[6], fvs[7], fvs[8])
|
|
ret.basis[2] = Vector3(fvs[9], fvs[10], fvs[11])
|
|
return ret
|
|
|
|
func save_furniture():
|
|
for k in get_children():
|
|
var save_data = []
|
|
for e in ["fc", "fwb"]:
|
|
if k.name.begins_with(e):
|
|
for l in k.get_children():
|
|
if l.has_meta("save_path"):
|
|
save_data.push_back({"path": l.get_meta("save_path"), "xform": xform2s(l.transform)})
|
|
furniture_data[k.name] = save_data
|
|
func save():
|
|
save_data.exits = exits
|
|
save_data.windows = windows
|
|
if has_meta("master_room"):
|
|
save_data.master_room = true
|
|
if has_meta("kitchen_room"):
|
|
save_data.kitchen_room = true
|
|
if has_meta("jail_room"):
|
|
save_data.jail_room = true
|
|
if has_meta("exit_room"):
|
|
save_data.exit_room = true
|
|
if has_meta("stairs"):
|
|
save_data.stairs = get_meta("stairs")
|
|
save_furniture()
|
|
save_data.furniture = furniture_data
|
|
var spawns = {}
|
|
for k in get_children():
|
|
var e: Spatial = k
|
|
if e.is_in_group("spawn"):
|
|
var stats = []
|
|
if e.has_meta("stats"):
|
|
stats = e.get_meta("stats")
|
|
spawns[e.name] = {"groups": e.get_groups(), "xform": xform2s(e.transform), "stats": stats}
|
|
save_data.spawns = spawns
|
|
|
|
func restore_furniture():
|
|
for k in furniture_data.keys():
|
|
var ch = get_node(k)
|
|
for d in furniture_data[k]:
|
|
var f = load(d.path).instance()
|
|
ch.add_child(f)
|
|
f.transform = s2xform(d.xform)
|
|
func restore():
|
|
for k in save_data.exits:
|
|
open_path(k)
|
|
for k in save_data.windows:
|
|
open_window(k)
|
|
if save_data.master_room:
|
|
set_meta("master_room", true)
|
|
if save_data.kitchen_room:
|
|
set_meta("kitchen_room", true)
|
|
if save_data.jail_room:
|
|
set_meta("jail_room", true)
|
|
if save_data.stairs >= 0:
|
|
set_meta("stairs", save_data.stairs)
|
|
create_rooms()
|
|
furniture_data = save_data.furniture
|
|
restore_furniture()
|
|
var spawns = save_data.spawns
|
|
for k in spawns.keys():
|
|
var e = Spatial.new()
|
|
for g in spawns[k].groups:
|
|
e.add_to_group(g)
|
|
e.transform = s2xform(spawns[k].xform)
|
|
add_child(e)
|
|
e.name = k
|
|
func _ready():
|
|
tw2d = $c_modular/w2d.transform
|
|
te2d = $c_modular/e2d.transform
|
|
tn2d = $c_modular/n2d.transform
|
|
ts2d = $c_modular/s2d.transform
|
|
var open_paths = {
|
|
OPEN_UP: {
|
|
"rm_walls": ["n2d", "iw4d"],
|
|
"rm": ["fc4"],
|
|
"bit": BITUP
|
|
},
|
|
OPEN_DOWN: {
|
|
"rm_walls": ["s2d", "iw11d"],
|
|
"rm": ["fc5"],
|
|
"bit": BITDOWN
|
|
},
|
|
OPEN_LEFT: {
|
|
"rm_walls": ["w2d", "iw17d"],
|
|
"rm": ["fc2"],
|
|
"bit": BITLEFT
|
|
},
|
|
OPEN_RIGHT: {
|
|
"rm_walls": ["e2d", "iw22d"],
|
|
"rm": ["fc3"],
|
|
"bit": BITRIGHT
|
|
},
|
|
}
|
|
func open_path(flag):
|
|
if !flag in exits:
|
|
var kf = open_paths[flag]
|
|
bitflags |= kf.bit
|
|
exits.push_back(flag)
|
|
for e in kf.rm:
|
|
if get_node(e):
|
|
get_node(e).queue_free()
|
|
func create_paths():
|
|
for flag in exits:
|
|
var kf = open_paths[flag]
|
|
for e in kf.rm_walls:
|
|
$c_modular.get_node(e).queue_free()
|
|
for e in kf.rm:
|
|
if get_node(e):
|
|
get_node(e).queue_free()
|
|
if exits.size() == 1 && !has_meta("master_room"):
|
|
$fc1.queue_free()
|
|
func open_window(flag):
|
|
if !flag in windows:
|
|
windows.push_back(flag)
|
|
func remove_iws():
|
|
for k in $c_modular.get_children():
|
|
if k.name.begins_with("iw"):
|
|
k.queue_free()
|
|
save_data.remove_iws = true
|
|
func personal_room():
|
|
var door_xform
|
|
remove_iws()
|
|
assert(exits.size() == 1)
|
|
match(int(exits[0])):
|
|
OPEN_UP:
|
|
door_xform = tn2d
|
|
OPEN_DOWN:
|
|
door_xform = ts2d
|
|
OPEN_LEFT:
|
|
door_xform = tw2d
|
|
OPEN_RIGHT:
|
|
door_xform = te2d
|
|
_:
|
|
print(exits)
|
|
assert(false)
|
|
var door_i = door.instance()
|
|
add_child(door_i)
|
|
door_i.transform = door_xform
|
|
save_data.personal_room = true
|
|
func master_room():
|
|
remove_iws()
|
|
for k in exits:
|
|
var door_xform: Transform
|
|
match(int(k)):
|
|
OPEN_UP:
|
|
door_xform = tn2d
|
|
OPEN_DOWN:
|
|
door_xform = ts2d
|
|
OPEN_LEFT:
|
|
door_xform = tw2d
|
|
OPEN_RIGHT:
|
|
door_xform = te2d
|
|
_:
|
|
print(exits)
|
|
assert(false)
|
|
var door_i = door.instance()
|
|
add_child(door_i)
|
|
door_i.transform = door_xform
|
|
func wall2door(n):
|
|
var door_xform = n.transform
|
|
var door_i
|
|
for e in get_tree().get_nodes_in_group("door"):
|
|
var xpos = e.global_transform.origin
|
|
var ypos = n.global_transform.origin
|
|
if xpos.distance_to(ypos) < 1.3:
|
|
n.queue_free()
|
|
return
|
|
if has_meta("jail_room"):
|
|
door_i = jail_door.instance()
|
|
else:
|
|
door_i = door.instance()
|
|
add_child(door_i)
|
|
door_i.transform = door_xform
|
|
door_i.add_to_group("door")
|
|
n.queue_free()
|
|
func exit_door(n):
|
|
var xn = n.name
|
|
var exit_door_xform = n.transform
|
|
var xdoor_i = outside_door.instance()
|
|
add_child(xdoor_i)
|
|
xdoor_i.transform = exit_door_xform
|
|
xdoor_i.name = xn
|
|
n.queue_free()
|
|
xdoor_i.add_to_group("exit_door")
|
|
func wall2window(n):
|
|
var window_xform = n.transform
|
|
var xn = n.name
|
|
var window_i
|
|
window_i = window.instance()
|
|
add_child(window_i)
|
|
window_i.name = xn
|
|
window_i.transform = window_xform
|
|
n.queue_free()
|
|
|
|
var bitdata = {
|
|
BITLEFT: {
|
|
"doors": ["iw17d"],
|
|
"path_remove": ["path_west"],
|
|
"nodes_remove": ["iw1", "iw2d", "iw3", "iw8", "iw9d", "iw10"]
|
|
},
|
|
BITRIGHT: {
|
|
"doors": ["iw22d"],
|
|
"path_remove": ["path_east"],
|
|
"nodes_remove": ["iw5", "iw6d", "iw7", "iw12", "iw13d", "iw14"]
|
|
},
|
|
BITUP: {
|
|
"doors": [],
|
|
"path_remove": ["path_north"],
|
|
"nodes_remove": ["iw15", "iw16d", "iw23d", "iw24"]
|
|
},
|
|
BITDOWN: {
|
|
"doors": [],
|
|
"path_remove": ["path_south"],
|
|
"nodes_remove": ["iw18d", "iw19", "iw20", "iw21d"]
|
|
}
|
|
}
|
|
|
|
var master_metas = ["master_room", "kitchen_room", "exit_room", "stairs"]
|
|
func create_rooms():
|
|
assert(exits.size() > 0)
|
|
create_paths()
|
|
var is_master_room = false
|
|
for m in master_metas:
|
|
if has_meta(m):
|
|
is_master_room = true
|
|
if is_master_room:
|
|
master_room()
|
|
if has_meta("exit_room"):
|
|
assert(windows.size() > 0)
|
|
for e in get_children():
|
|
if e.is_in_group("furniture"):
|
|
e.queue_free()
|
|
if has_meta("stairs"):
|
|
var stairs_i = stairs.instance()
|
|
add_child(stairs_i)
|
|
for e in get_children():
|
|
if e.is_in_group("furniture"):
|
|
e.queue_free()
|
|
if get_meta("stairs") > 0:
|
|
$c_modular/floor.queue_free()
|
|
elif exits.size() == 1:
|
|
personal_room()
|
|
elif exits.size() == 4:
|
|
wall2door($c_modular/iw2d)
|
|
wall2door($c_modular/iw6d)
|
|
wall2door($c_modular/iw9d)
|
|
wall2door($c_modular/iw13d)
|
|
else:
|
|
for e in [BITLEFT, BITRIGHT, BITUP, BITDOWN]:
|
|
if bitflags & e == 0:
|
|
for g in bitdata[e].doors:
|
|
wall2door($c_modular.get_node(g))
|
|
for g in bitdata[e].path_remove:
|
|
get_node(g).queue_free()
|
|
for g in bitdata[e].nodes_remove:
|
|
$c_modular.get_node(g).queue_free()
|
|
var external = {
|
|
OPEN_LEFT: ["w1", "w2d", "w3"],
|
|
OPEN_DOWN: ["s1", "s2d", "s3"],
|
|
OPEN_RIGHT: ["e1", "e2d", "e3"],
|
|
OPEN_UP: ["n1", "n2d", "n3"]
|
|
}
|
|
for p in windows:
|
|
for q in external[p]:
|
|
var n = $c_modular.get_node(q)
|
|
if !p in outside_doors:
|
|
wall2window(n)
|
|
for p in outside_doors:
|
|
var q = external[p][1]
|
|
var n = $c_modular.get_node(q)
|
|
exit_door(n)
|