extends Actor export var player_number: int = 1 onready var player_inventory :InventoryManager = InventoryManager.new() onready var stamina_component = $"%Stamina_Component" onready var health_component = $"%Health_Component" onready var hitbox_component = $Hitbox_Component onready var hurtbox_component = $Hurtbox_Component const state_stamina_cost :Dictionary = { "jump": 10, "attack_sword":20, "attack_punch":10, #"roll":40, "roll":4, "ledge_climb":10 } const state_damage_amount :Dictionary = { "attack_sword":30, "attack_punch":10, } const state_to_item_map :Dictionary = { "sword": "attack_sword" , "gun": "attack_shoot", "punch" : "attack_punch", "mushroom" : "attack_shoot" } var player_info_index :int var player_data :PlayerData ## Temp Modifier to test movement modifier (getting tired) var tired_debuff_modifier = StateModifierMovement.new() # attack_sword = StateModifierAnimatedActor.new() # attack_sword.setup('sword_drawn',StateModifier.TYPE.ANIMATION_SUFFIX,2.0) # add_child(attack_sword.timeout) # #attack_sword.animation_name = 'PoopenStein' # attack_sword.animation_suffix = 'attack-sword' # add_state_modifier.call_func(attack_sword) # Called when the node enters the scene tree for the first time. func _ready(): # I think we only want to do this for network master players now if is_network_master(): player_info_index = PlayerInfo.register_player() if debug_actor: print ("Registered as player: ", player_info_index) player_data = PlayerInfo.get_player_data(player_info_index) PlayerInfo.get_player_data(player_info_index).player_health = health_component.health player_data.player_inventory = player_inventory player_data.player_stamina = stamina_component.stamina else: ## puppets cannot get hurt, only network master. hurtbox_component.hurtbox_entered_function = '' # Set initial player position in world. global_position = LevelInfo.player_start_position ## Give player punch ability at start. var punch_item :Item = preload("res://assets/items/punch.tres") player_inventory.add_to_inventory(punch_item) player_inventory.select_primary(punch_item) movement_component.state_stamina_cost = state_stamina_cost tired_debuff_modifier.setup('so_tired', StateModifierMovement.SUB_TYPE.NEGATIVE_CONSTRAINT) tired_debuff_modifier.speed_start = Vector2(-40,0) tired_debuff_modifier.horizontal_speed = -40 tired_debuff_modifier.only_grounded = true movement_state_machine.push_state_modifier(tired_debuff_modifier) #var stamina_recovery :float = 0.0 # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): if is_network_master(): ## Update position and stamina in player data player_data.player_position = global_position.round() player_data.player_stamina = stamina_component.stamina match movement_state_machine.current_state.name: "idle": if Input.is_action_just_released("switch_primary_item_" + str(player_number)): var _selected_item = player_inventory.switch_primary() if _selected_item: print("Switched Primary item to: ", _selected_item.name) elif Input.is_action_just_released("switch_secondary_item_" + str(player_number)): var _selected_item = player_inventory.switch_secondary() if _selected_item: print("Switched Secondary item to: ", _selected_item.name) # Adjust hitbox damage to current states or default ##TODO: well I'm not sure I like this but making a whole state receiver is silly if state_damage_amount.has(movement_state_machine.current_state.name): hitbox_component.damage_amount = state_damage_amount[movement_state_machine.current_state.name] else: hitbox_component.damage_amount = 10 if stamina_component.stamina < 20 and tired_debuff_modifier.is_active == false: tired_debuff_modifier.activate() if stamina_component.stamina > 20 and tired_debuff_modifier.is_active == true: tired_debuff_modifier.deactivate() func hit_Receiver(damage): hurtbox_component.set_hurtbox(false) health_component.take_damage(damage) if health_component.health > 0: movement_state_machine.change_to_known_state('hurt') #PlayerInfo.player_health = health_component.health player_data.player_health = health_component.health print ("Got Hurt, What happend: " , PlayerInfo.get_player_data(player_info_index).player_health, " vs ", player_data.player_health) if health_component.health <= 0: return yield( get_tree().create_timer(2 + movement_state_machine.get_state_reference('hurt').timeout_seconds), "timeout") hurtbox_component.set_hurtbox(true) ## Interactable Receiver callback function. Anything touched goes here. func touch_the_thing(the_thing: Interactable) -> bool: print("You see! a THING...", the_thing.name) if the_thing is HealthPickup: # Do some healthy stuff. the_thing.trigger_interaction() return false if the_thing is LevelTransition: if movement_state_machine.current_state.name != 'enter_right': if the_thing._transition_type == 'door_right': # Make sure we're facing right. transform.x.x = movement_component.RIGHT movement_state_machine.change_to_known_state('enter_right') elif the_thing._transition_type == 'door_left': transform.x.x = movement_component.LEFT movement_state_machine.change_to_known_state('enter_right') the_thing.trigger_interaction() if the_thing is ItemPickup: player_inventory.add_to_inventory(the_thing.item, the_thing.count) #player_inventory.select_secondary(the_thing.item) the_thing.trigger_interaction() return true func enough_stamina_for(_state_name :String) -> bool: if state_stamina_cost.has(_state_name): if stamina_component.stamina >= state_stamina_cost[_state_name]: return true else: return false ## Return true by default because we don't have a cost for this move return true ##DONE: We need to find a way to 'use' the item. func use_primary_item() -> String: if player_inventory.primary_selection != null: # Have to make sure we even have a second var _item_name :String = player_inventory.primary_selection.name if state_to_item_map.has(_item_name): var state_name = state_to_item_map[_item_name] ## This item state has a cost associated with it. if enough_stamina_for(state_name): #print("Yup: ", state_stamina_cost[state_name], "<=", stamina_component.stamina) player_inventory.remove_from_inventory(player_inventory.primary_selection) return state_to_item_map[_item_name] else: ##TODO: maybe some sort of 'fail' animation state #print("Nope: ", state_stamina_cost[state_name], "<=", stamina_component.stamina) return '' ## you can't use this ## use item even if no stamina usage needed for it. player_inventory.remove_from_inventory(player_inventory.primary_selection) return state_to_item_map[_item_name] return '' func use_secondary_item() -> String: if player_inventory.secondary_selection != null: # Have to make sure we even have a second var _item_name :String = player_inventory.secondary_selection.name if state_to_item_map.has(_item_name): var state_name = state_to_item_map[_item_name] if enough_stamina_for(state_name): player_inventory.remove_from_inventory(player_inventory.secondary_selection) return state_to_item_map[_item_name] else: ## TODO: maybe some sort of 'fail' animation state return '' ## use item even if no stamina usage needed for it. player_inventory.remove_from_inventory(player_inventory.secondary_selection) return state_to_item_map[_item_name] return '' func _on_Movement_StateMachine_state_changed(old_state_name, new_state): ## Reduce stamina if this state has a cost if state_stamina_cost.has(new_state.name): stamina_component.reduce_stamina(state_stamina_cost[new_state.name]) func _on_Health_Component_health_depleted(): movement_state_machine.change_to_known_state('death') NetworkManager.end_game()