extends Node # Declare member variables here. Examples: # var a = 2 # var b = "text" # Called when the node enters the scene tree for the first time. var freeze_dist = 20.0 func _ready(): pass # Replace with function body. # Called every frame. 'delta' is the elapsed time since the previous frame. func freeze_character(c): var pos = c.transform var sp = Spatial.new() var pp = c.get_parent() var character_data = {} var stats = {} if c.has_meta("character_data"): character_data = c.get_meta("character_data") if c.has_meta("stats"): stats = c.get_meta("stats") pp.add_child(sp) sp.transform = pos sp.add_to_group("frozen") sp.set_meta("character_data", character_data) var animtree: AnimationTree = c.get_meta("animation_tree") assert(animtree) var animation_node = animtree["parameters/state/playback"].get_current_node() sp.set_meta("animation_node", animation_node) # sp.set_meta("animation_tree", str(c.get_path_to(animtree))) sp.set_meta("stats", stats) if characters.get_crowd(): characters.get_crowd().remove_agent(c) c.queue_free() func prepare_save_data() -> bool: if !freeze_all(): return false scenario.save_data.characters = [] for c in get_tree().get_nodes_in_group("frozen"): var n = {} n.character_data = c.get_meta("character_data") n.stats = c.get_meta("stats") n.animation_node = c.get_meta("animation_node") n.xform = var2str(c.global_transform) scenario.save_data.characters.push_back(n) return true func get_player(): var c = get_viewport().get_camera() if !c: return null if !c.has_meta("player"): return null var player = c.get_meta("player") if !player: return null return player func unfreeze_character(c): var data = c.get_meta("character_data") var stats = c.get_meta("stats") print("HAIR: ", data.hair, " ", data.hair_mat) var nc = characters.replace_character(c, data.sex, data.modules, data.face, data.hair, data.hair_mat) nc.set_meta("stats", stats) var animtree: AnimationTree = nc.get_meta("animation_tree") assert(animtree) var animation_node = c.get_meta("animation_node") animtree["parameters/state/playback"].start(animation_node) animtree["parameters/state/playback"].travel(animation_node) nc.set_meta("saved_anim_state", animation_node) var state = 0 var delay = 0.0 func freeze_all() -> bool: var player = get_player() var ok = true for c in get_tree().get_nodes_in_group("character"): if c == player: continue elif c.name.begins_with("npc_spawn"): c.queue_free() continue elif c.name == "npc" && !c.has_meta("animation_tree"): print("bad ", c.name, " ", c.get_meta_list()) for e in c.get_meta_list(): print("bad", c.get_meta(e)) c.queue_free() continue assert(c.has_meta("animation_tree")) if c.has_meta("animation_tree"): freeze_character(c) else: ok = false assert(ok) return ok func _process(delta): return var cam = get_viewport().get_camera() var player = get_player() if !player: return var cpos = cam.global_transform.origin match state: 0: characters.set_process(false) for c in get_tree().get_nodes_in_group("character"): if c == player: continue var p = c.global_transform.origin if p.distance_squared_to(cpos) > freeze_dist * freeze_dist: if c.has_meta("animation_tree"): freeze_character(c) characters.set_process(true) state = 1 delay = 1.0 # print("spawned: ", get_tree().get_nodes_in_group("character").size()) # print("frozen: ", get_tree().get_nodes_in_group("frozen").size()) 1: characters.set_process(false) for c in get_tree().get_nodes_in_group("frozen"): var p = c.global_transform.origin if p.distance_squared_to(cpos) < 0.25 * freeze_dist * freeze_dist: print("unfreeze") unfreeze_character(c) characters.set_process(true) if delay > 0.0: delay -= delta else: state = 0