161 lines
4.4 KiB
GDScript
161 lines
4.4 KiB
GDScript
extends KinematicBody
|
|
|
|
signal starved_to_death
|
|
|
|
const StateDefault = preload("res://scripts/player/state/default.gd")
|
|
const StateInteracting = preload("res://scripts/player/state/interacting.gd")
|
|
const StateSleeping = preload("res://scripts/player/state/sleeping.gd")
|
|
const StatePlayingRoverGame = preload("res://scripts/player/state/playing_rover_game.gd")
|
|
|
|
const SPEED = 10.0
|
|
const MAX_HEALTH = 4
|
|
|
|
export var hunger_tick_time = 30.0
|
|
export var inventory = {}
|
|
|
|
var health: int = 4 setget set_health
|
|
var item_in_hand
|
|
var move_enabled: bool = true
|
|
|
|
onready var anim_tree = $model_transform/DungMan/AnimationTree
|
|
onready var move_playback = anim_tree["parameters/Move/playback"]
|
|
onready var hunger_timer = $"%hunger_timer"
|
|
|
|
var state = null
|
|
|
|
func _ready():
|
|
$hitbox.set_meta("owner", self)
|
|
move_playback.travel("idle")
|
|
hunger_timer.wait_time = hunger_tick_time
|
|
hunger_timer.start()
|
|
state = StateDefault.new()
|
|
state.ctx = self
|
|
state.enter_from(null)
|
|
print("player: NULL -> ", state.NAME)
|
|
|
|
func change_state(new_state):
|
|
print("player: ", state.NAME, " -> ", new_state.NAME)
|
|
new_state.ctx = self
|
|
state.exit_to(new_state)
|
|
new_state.enter_from(state)
|
|
state = new_state
|
|
|
|
func _process(delta):
|
|
var hunger_timer = $"%hunger_timer"
|
|
for i in $"%stomachs".get_child_count():
|
|
var stomach = $"%stomachs".get_child(i)
|
|
if i == health - 1:
|
|
stomach.material.set_shader_param("percent", 1.0 - hunger_timer.time_left / hunger_timer.wait_time)
|
|
else:
|
|
stomach.material.set_shader_param("percent", 0.0)
|
|
|
|
func _physics_process(delta):
|
|
state.physics_process(delta)
|
|
|
|
func _on_hunger_timer_timeout():
|
|
set_health(health - 1)
|
|
print("player: lost health to hunger tick")
|
|
|
|
func set_health(new_value):
|
|
var hunger_timer = $"%hunger_timer"
|
|
hunger_timer.start()
|
|
health = min(new_value, MAX_HEALTH)
|
|
for child in $"%stomachs".get_children():
|
|
child.visible = child.get_index() < health
|
|
if health <= 0:
|
|
emit_signal("starved_to_death")
|
|
hunger_timer.stop()
|
|
|
|
func consume_food(item : Resource):
|
|
set_health(MAX_HEALTH)
|
|
print("player: Hunger Satisfied! Ate %s" % item.name)
|
|
|
|
func get_item_from_inventory(var item_name : String):
|
|
var current_amount : int = 0
|
|
if(inventory.has(item_name)):
|
|
current_amount = inventory[item_name]
|
|
return current_amount
|
|
|
|
func can_afford(item_name, item_amount):
|
|
assert(item_amount > 0)
|
|
var current_amount : int = get_item_from_inventory(item_name)
|
|
return current_amount >= item_amount
|
|
|
|
func modify_inventory(item_name, item_amount):
|
|
if item_amount == 0:
|
|
return true
|
|
|
|
var is_op_valid : bool = true
|
|
|
|
# Note(asr): check if you can afford the item if we are removing
|
|
# for item grants op is always valid
|
|
if item_amount < 0:
|
|
is_op_valid = can_afford(item_name, abs(item_amount))
|
|
|
|
if not is_op_valid:
|
|
return false
|
|
|
|
var current_amount : int = 0
|
|
if inventory.has(item_name):
|
|
current_amount = inventory[item_name]
|
|
# Note(asr): clamp to 0. can't have negative items
|
|
var new_amount : int = max(current_amount + item_amount, 0)
|
|
inventory[item_name] = new_amount
|
|
print("inventory updated: ", item_name, " : ", new_amount)
|
|
return true
|
|
|
|
func _unhandled_input(event):
|
|
state.unhandled_input(event)
|
|
|
|
func drop_item_in_hand():
|
|
print("player dropped ", item_in_hand.item_name)
|
|
var item_dropped = item_in_hand
|
|
$"%ItemSpawn".remove_child(item_in_hand)
|
|
item_in_hand = null
|
|
return item_dropped
|
|
|
|
func pick_up_item(item):
|
|
var item_dropped = null
|
|
if item_in_hand != null:
|
|
item_dropped = drop_item_in_hand()
|
|
item_in_hand = item
|
|
$"%ItemSpawn".add_child(item_in_hand)
|
|
print("player picked up ", item_in_hand.item_name)
|
|
return item_dropped
|
|
|
|
func has_item() -> bool:
|
|
return item_in_hand != null
|
|
|
|
func get_item_in_hand():
|
|
var item_to_return = null
|
|
if item_in_hand != null:
|
|
item_to_return = drop_item_in_hand()
|
|
return item_to_return
|
|
|
|
func _on_blink_timer_timeout():
|
|
anim_tree["parameters/Blink/active"] = true
|
|
$"%blink_timer".wait_time = rand_range(0.5, 3.0)
|
|
|
|
func sleep(made_it_to_bed: bool, hop_position: Spatial):
|
|
state.on_sleep(made_it_to_bed, hop_position)
|
|
|
|
func start_playing_rover_game():
|
|
state.on_start_playing_rover_game()
|
|
|
|
func stop_playing_rover_game():
|
|
state.on_stop_playing_rover_game()
|
|
|
|
func _on_TriggerVolume_area_entered(area):
|
|
var owner = area
|
|
if owner.has_meta("owner"):
|
|
owner = area.get_meta("owner")
|
|
if owner.has_method("on_player_focus_enter"):
|
|
owner.on_player_focus_enter()
|
|
|
|
func _on_TriggerVolume_area_exited(area):
|
|
var owner = area
|
|
if owner.has_meta("owner"):
|
|
owner = area.get_meta("owner")
|
|
if owner.has_method("on_player_focus_exit"):
|
|
owner.on_player_focus_exit()
|