241 lines
7.9 KiB
GDScript
241 lines
7.9 KiB
GDScript
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()
|