]> purplebirdman git - frog-ninja.git/blob - asset/character/model/character_model.gd
Added shaders to projectile
[frog-ninja.git] / asset / character / model / character_model.gd
1 extends Node3D
2 class_name CharacterModel
3 ## The base model class for any input-driven character
4 ##
5 ## Drives all the logical features of a character, including the states
6 ##
7
8
9 @onready var player: Player = $".."
10 @onready var skeleton: AnimatedSkeleton3D = $Skeleton3D
11 @onready var animator: AnimationPlayer = $AnimationPlayer
12
13 # TODO: these should be discovered dynamically, and their attack states 
14 #       should be discovered at the same time
15 @onready var weapon_r: Weapon = $RightHand/hand_socket_R/Sword
16 @onready var weapon_l: Weapon = $LeftHand/hand_socket_L/Gun
17 @onready var hitbox: Hitbox = $Root/Hitbox
18 @onready var shield: Node3D = $Shield
19
20
21 var states: Dictionary = {}
22 var current_state: State
23
24
25 func _ready() -> void:
26         assemble_character_states()
27         set_weapon_collision()
28         set_hitbox_collision()
29         assign_current_state("Idle")
30
31
32 func set_hitbox_collision():
33         hitbox.collision_layer = player.collision_layer
34         hitbox.collision_mask = player.collision_mask
35
36
37 func set_weapon_collision():
38         # make sure hurtbox collision layers and mask are same as player's
39         for w in [weapon_r, weapon_l]:
40                 if w is Weapon:
41                         w.equipped_by = player
42                         w.collision_layer = player.collision_layer
43                         w.collision_mask = player.collision_mask
44
45
46 func assemble_character_states():
47         for node in $States.get_children():
48                 if node is State:
49                         states[node.name] = node
50                         node.player = player
51                         node.states = states
52         print("Found states for " + player.name + ": " + str(states.keys()))
53
54
55 func translate_combat_actions_to_states(input: InputPacket):
56         for w in [weapon_r, weapon_l]:
57                 if w is Weapon:
58                         input.player_actions.append_array(w.translate_combat_actions_to_states(input))
59
60
61 func update(input: InputPacket, delta: float):
62         if not player.is_on_floor():
63                 input.player_actions.append("Fall")
64
65         # translate weapon layer into action states
66         translate_combat_actions_to_states(input)
67         var new_state_name := current_state.should_enter(input)
68         
69         # check combos for states to queue
70         if current_state.ok_to_queue_next_state():
71                 current_state.check_combos(input)
72
73         # a queued state will always override an action list state
74         if current_state.has_queued_state and current_state.ok_to_transition_to_queued_state():
75                 current_state.has_queued_state = false
76                 new_state_name = current_state.queued_state_name
77         
78         # switch to appropriate state
79         if states.has(new_state_name):
80                 # TODO: transition to same state!
81                 if states[new_state_name] != current_state:
82                         if states[new_state_name].get_remaining_cooldown_time() == 0:
83                                 if player.stamina_points > 0:
84                                         player.stamina_points -= states[new_state_name].stamina_toll
85                                         switch_to(new_state_name)
86                 current_state.update(input, delta)
87         else:
88                 print_debug("Requested input state not found: " + new_state_name)
89
90
91 func switch_to(state_name: String):
92         animator.animation_started.disconnect(current_state._when_animation_started)
93         animator.animation_finished.disconnect(current_state._when_animation_finished)
94         current_state.on_exit_state()
95         current_state.mark_exit_state()
96         assign_current_state(state_name)
97         
98         
99 func assign_current_state(state_name: String):
100         current_state = states[state_name]
101         current_state.mark_enter_state()
102         current_state.on_enter_state()
103         player.state_name = current_state.name
104         
105         animator.animation_started.connect(current_state._when_animation_started)
106         animator.animation_finished.connect(current_state._when_animation_finished)
107         animator.play_section(current_state.animation_name, 0.0, -1, -1, current_state.animation_speed_scale)