root/3d/nyoron/pfrend.gd

extends Spatial
const ItemSprite = preload("res://3d/item_sprite/item_sprite.tscn")

var needs
var navigation : Navigation = null
onready var thought_bubble = $thought_bubble
onready var animation = $AnimationPlayer
const speed = 0.1

onready var body = $body
onready var head = $body/head

export(bool) var look_at_camera = false setget set_look_at_camera
export(bool) var body_facing_camera = false setget set_body_facing_camera
export(float) var walking = 0.0 # hint for cylinders to rotate
var scene = null
var path = null
var y_offset = 0
var rotation_target = 0.0

class EventLog:
	var time_occured = 0
	var type = "hungry"
	var during_playtime = true
	func _init(time, type_arg, dp):
		time_occured = time
		type = type_arg
		during_playtime = dp

var event_history = []
var active_event = null
onready var body_default_transform = body.transform
onready var head_default_transform = head.transform

func _ready():
	if not pause_mode == PAUSE_MODE_STOP:
		link_nodes()
	#	fix_broken_parenting()
		needs.food.value = 50
		animation.connect("animation_finished", self, "on_animation_ended")
		equip_clothing()
		y_offset = self.transform.origin.y

func equip_clothing():
	var model = load("res://3d/nyoron/outfits/pants.glb").instance()
	for c in model.get_children():
		if c.name.begins_with("body_arm_l_"):
			Global.reparent(c, body.get_node("body_arm_l"), false)
		if c.name.begins_with("body_arm_r_"):
			Global.reparent(c, body.get_node("body_arm_r"), false)
		if c.name.begins_with("body_leg_l_"):
			Global.reparent(c, body.get_node("body_leg_l"), false)
		if c.name.begins_with("body_leg_r_"):
			Global.reparent(c, body.get_node("body_leg_r"), false)
		if c.name.begins_with("head_"):
			Global.reparent(c, head, false)
		if c.name.begins_with("body_"):
			Global.reparent(c, body, false)

func link_nodes():
	needs = $"./needs"

func _process(_delta):
	if pause_mode == PAUSE_MODE_STOP:
		return
	if scene:
		if scene.scene_type == 2:
			walking = lerp(walking, 1.0, 0.01)
		else:
			walking = lerp(walking, 0.0, 0.01)
			
	
	if body_facing_camera:
		if Global.current_camera:
			body.look_at(Global.current_camera.global_transform.origin, Vector3(0,1.0,0))
			body.transform = body.transform.rotated(Vector3(0.0,1.0,0.0), PI)
	elif look_at_camera:
		if Global.current_camera:
			head.look_at(Global.current_camera.global_transform.origin, Vector3(0,1.0,0))
			head.transform = head.transform.rotated(Vector3(0.0,1.0,0.0), PI)
#
	if not active_event:
		check_for_new_events()
		
	if path and not path.empty():
		var next_node = path[0]
		var start = self.global_transform.origin
		next_node.y += y_offset
		var distance = start.distance_to(next_node)
		var diff = start - next_node
		self.rotation_target = PI+(atan2(diff.x, diff.z))
		self.rotation = Vector3(0,lerp_angle(self.rotation.y,rotation_target,0.1),0)
		if distance < speed:
			self.global_transform.origin = next_node
			path.remove(0)
			if path.empty():
				path = null
		else:
			var new_pos = lerp(start, next_node, speed/max(0.01,distance))
			self.global_transform.origin = new_pos
			
		
		
		
		
		
func set_body_facing_camera(value):
	body_facing_camera = value
	if not value:
		body.transform = body_default_transform
		
func set_look_at_camera(value):
	look_at_camera = value
	if not value and head:
		head.transform = head_default_transform

func check_for_new_events():
	if needs.food.value < 75:
		if needs.food.value > 70:
			event_timed("slightly_hungry", Global.MINUTE*20)
		if needs.food.is_ok():
			event_timed("hungry", Global.MINUTE*7)
		else:
			event_timed("very_hungry", Global.MINUTE*2)
		
		
func do_event(type):
	if type == "slightly_hungry":
		thought_bubble.open_with_icon("food")
	elif type == "hungry":
		thought_bubble.open_with_icon("food")
		animation.play("hungry")
	elif type == "very_hungry":
		$sounds/stomach.play(0)
		thought_bubble.open_with_icon("food")
		animation.play("hungry")
		
		
	
	
func event_timed(type, max_distance):
	var now = OS.get_unix_time()
	for e in event_history:
		if e.time_occured > (now - max_distance):
			if e.type == type:
				# already did this event recently
				return false
		else:
			break
	var event_log = EventLog.new(now, type, true)
	event_history.push_front(event_log)
	if event_history.size() > 128:
		event_history.pop_front()
	do_event(type)
		
func receive_item(name):
	var item = $body/body_arm_r/hold_position/item_sprite
	item.set_icon(name)
	animation.play("receive_food", 1.0)
#	var item = ItemSprite.instance()
#	item.set_icon(name)
#	$body/body_arm_r/hold_position.add_child(item)

func on_animation_ended(name):
	if name == "receive_food":
		self.needs.food.value.modify(25)
	idle_activity()
	
func idle_activity():
	if scene.scene_type != 2:
		if navigation:
			var random_point = Vector3(
				rand_range(-5.0, 0.0),
				rand_range(0, 0),
				rand_range(0.0, 5.0)
			)
			random_point.y = y_offset
			var start = navigation.get_closest_point(self.global_transform.origin)
			var end = navigation.get_closest_point(random_point)
			var new_path = navigation.get_simple_path(start, end, true)
			for i in new_path.size():
				new_path[i] = new_path[i] + navigation.global_transform.origin
			self.path = new_path
			
			
	
	animation.play("idle")