extends Spatial var loading func new_quest(q): var title = q.get_title() var desc = q.get_description() print("title: ", title) print("desc: ", desc) func _ready(): loading = preload("res://ui/loading.tscn").instance() get_tree().get_root().add_child(loading) var e = $"meta-ai".connect("spawn_player", self, "spawn_player") assert(e == OK) e = $"meta-ai".connect("spawn_npc", self, "spawn_npc") assert(e == OK) # $cam_target/offset/Camera.set_as_toplevel(true) global.set_save_slot(0) e = $dungeon.connect("prepared", self, "start_ai") assert(e == OK) e = quests.connect("new_quest", self, "new_quest") assert(e == OK) var default_meta = { "grabbing": false, "grabbed": false, "smart_object": false, "weapon": false, "busy": false, "action": "", } var player_meta = { "health": 1000, "max_health": 1000, "stamina": 500, "max_stamina": 500, } func start_ai(): print("prepared") $"meta-ai".start() func save(): global.save_characters() $dungeon.save() quests.save() global.save_game() func spawn_player(spawner): print("spawned player") loading.queue_free() var player_sc = load("res://scenes/characters/male.tscn") var player = player_sc.instance() add_child(player) player.global_transform = spawner.global_transform.translated(Vector3(randf() * 0.4, 0.0, randf() * 0.4)) # print("spawn player at: ", player.global_transform.origin) global.player = player $cam_target.global_transform.origin = player.global_transform.origin rpg.create_stats(player) for k in default_meta.keys(): player.set_meta(k, default_meta[k]) player.name = "player" combat.register(player) player.set_meta("spawner", spawner) player.add_to_group("player") $cam_target/cam_rot/offset/Camera.current = true global.start_time() func spawn_npc(spawner): var npc var g if spawner.is_in_group("male"): var npc_sc = load("res://scenes/characters/male.tscn") var male_hair = preload("res://scenes/characters/hair1-male/male_g_2018-short02.mesh") npc = npc_sc.instance() var hair = npc.get_skeleton().get_node("hair") hair.mesh = male_hair g = "male" elif spawner.is_in_group("female"): var npc_sc = load("res://scenes/characters/female.tscn") npc = npc_sc.instance() g = "female" add_child(npc) for k in spawner.get_groups(): if k == "spawn": continue npc.add_to_group(k) spawner.set_meta("npc", npc) npc.set_meta("spawner", spawner) npc.name = "npc_" + g + "_" + str(get_tree().get_nodes_in_group("npc").size()) npc.global_transform = spawner.global_transform.translated(Vector3(randf() * 0.4, 0.0, randf() * 0.4)) npc.add_to_group("npc") if spawner.has_meta("stats"): var stats = spawner.get_meta("stats") for k in stats.keys(): npc.set_meta(k, stats[k]) else: rpg.create_stats(npc) for k in default_meta.keys(): npc.set_meta(k, default_meta[k]) var bb = Blackboard.new() npc.add_child(bb) bb.name = "blackboard" combat.register(npc) if npc.is_in_group("guard"): var guard_suit = preload("res://scenes/characters/guard.escn") var guard_suit_i = guard_suit.instance() var skel = npc.get_skeleton() for k in guard_suit_i.get_node("male_g_2018").get_children(): if k is MeshInstance: k.get_parent().remove_child(k) skel.add_child(k) k.owner = skel.owner guard_suit_i.queue_free() if npc.is_in_group("maid"): var maid_suit = preload("res://scenes/characters/maid.escn") var maid_suit_i = maid_suit.instance() var skel = npc.get_skeleton() for k in maid_suit_i.get_node("female").get_children(): if k is MeshInstance: k.get_parent().remove_child(k) skel.add_child(k) k.owner = skel.owner # npc.skirt_simulation(true) maid_suit_i.queue_free() func can_control(): if global.player.get_meta("smart_object"): return false elif global.player.get_meta("busy"): return false return true var mouse_motion: Vector2 = Vector2() func _unhandled_input(event): if event is InputEventMouseMotion: mouse_motion += event.relative var cam_fixup_cooldown = 0.0 var ai_debug: Node func _process(delta): if Input.is_action_just_pressed("ai_debug"): if !ai_debug: var aid = load("res://scenes/debug/ai_debug.tscn") ai_debug = aid.instance() add_child(ai_debug) else: ai_debug.queue_free() ai_debug = null if global.player: var player_xform = global.player.global_transform # $cam_target.rotate(Vector3(0, 1, 0), 0.2 * delta) $cam_target.global_transform.origin = $cam_target.global_transform.origin.linear_interpolate(global.player.global_transform.origin, delta) # $cam_target/offset/Camera.look_at($cam_target/offset.global_transform.origin, Vector3(0, 1, 0)) var cam_xform = $cam_target/cam_rot/offset/Camera.global_transform cam_xform.basis[0].y = 0 cam_xform.basis[0] = cam_xform.basis[0].normalized() cam_xform.basis[2].y = 0 cam_xform.basis[2] = cam_xform.basis[2].normalized() var up = Vector3(0, 1, 0) cam_xform.basis[1] = up cam_xform = cam_xform.orthonormalized() var lookat_xform_left = player_xform.looking_at(player_xform.origin - cam_xform.basis[0], up) var lookat_xform_right = player_xform.looking_at(player_xform.origin + cam_xform.basis[0], up) var lookat_xform_forward = player_xform.looking_at(player_xform.origin - cam_xform.basis[2], up) var lookat_xform_back = player_xform.looking_at(player_xform.origin + cam_xform.basis[2], up) var player_fwd = player_xform.basis[2] var cam_fwd = cam_xform.basis[2] var walking = false if abs(mouse_motion.x) > 0.1: $cam_target.rotate_y(-mouse_motion.x * 0.7 * delta) cam_fixup_cooldown += 2.0 * delta if cam_fixup_cooldown > 10.0: cam_fixup_cooldown = 10.0 mouse_motion.x = 0.0 if abs(mouse_motion.y) > 0.1: $cam_target/cam_rot.rotate_x(mouse_motion.y * 0.3 * delta) $cam_target/cam_rot.rotation.x = clamp($cam_target/cam_rot.rotation.x, -PI / 3.0, PI / 3.0) mouse_motion.y = 0.0 if can_control(): if Input.is_action_pressed("walk_forward"): global.player.orientation.basis = lookat_xform_forward.basis global.player.do_walk() global.player.set_walk_speed(2.5) walking = true if Input.is_action_pressed("walk_left"): global.player.orientation.basis = lookat_xform_left.basis global.player.do_walk() global.player.set_walk_speed(1.5) walking = true if Input.is_action_pressed("walk_right"): global.player.orientation.basis = lookat_xform_right.basis global.player.do_walk() walking = true global.player.set_walk_speed(1.5) if Input.is_action_pressed("walk_back"): global.player.orientation.basis = lookat_xform_back.basis global.player.do_walk() walking = true global.player.set_walk_speed(1.5) if Input.is_action_pressed("grab"): if !global.player in global.smart_object: var close = [] var xform: Transform = global.player.global_transform for k in get_tree().get_nodes_in_group("npc"): if k.get_meta("smart_object"): print(k.name, " in smart object") continue var npc_pos = k.global_transform.origin if xform.origin.distance_to(npc_pos) < 2.0: if xform.xform_inv(npc_pos).z < 0.0: close.push_back(k) var dst = INF var best = null for k in close: var npc_pos = k.global_transform.origin var xpos = xform.xform_inv(npc_pos) if dst > xpos.length(): dst = xpos.length() best = k if best: print("grabbing ", best.name) if !global.player.get_meta("grabbing"): grabbing.grab_character(global.player, best) else: print("smart object!! ", global.smart_object, " ", global.player) if Input.is_action_pressed("attack"): global.player.do_attack() if can_control(): if !walking: global.player.do_stop() if cam_fixup_cooldown <= 0.0 && global.player && abs(global.player.velocity.z) > 0.001: var v1 = Vector2(player_fwd.x, player_fwd.z) var v2 = Vector2(cam_fwd.x, cam_fwd.z) var angle = v2.angle_to(v1) if abs(angle) > 0.1: $cam_target.rotate_y(-angle * delta) else: cam_fixup_cooldown -= delta if Input.is_action_just_pressed("save_game"): save()