142 lines
3.9 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")
func consume_food(item : Resource):
set_health(MAX_HEALTH)
print("player: Hunger Satisfied! Ate %s" % item.name)
func can_afford(item_name, item_amount):
assert(item_amount > 0)
var current_amount : int = 0
if(inventory.has(item_name)):
current_amount = 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()