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 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): if health > 0: var hunger_timer = $"%hunger_timer" var stomach = $"%stomachs".get_child(health - 1) stomach.material.set_shader_param("percent", 1.0 - hunger_timer.time_left / hunger_timer.wait_time) 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): 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)