-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfighter.gd
211 lines (179 loc) · 6.03 KB
/
fighter.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
extends KinematicBody2D
export(int, "1", "2") var player_id
const speed = 200.0
const punch_damage = 10
const kick_damage = 30
const throw_speed = 1000.0
var action_left: String
var action_right: String
var action_hit: String
var action_block: String
var action_grab: String
var controller_id: int
signal deal_damage(target, damage)
var damage_dealt_sound = preload("res://resources/audio/impact1.wav")
var rng = RandomNumberGenerator.new()
onready var character: Node2D = get_node("character")
onready var juice_center: Node2D = character.find_node("juice_center")
onready var fist: Node2D = character.find_node("fist")
onready var smileface: Node2D = character.find_node("smileface")
onready var happyface: Node2D = character.find_node("happyface")
onready var cryface: Node2D = character.find_node("cryface")
var hit_targets: Array = []
enum EMOTION {smile, happy, cry}
export(EMOTION) var emotion = EMOTION.smile setget _on_emotion_set
var init_position
var init_transform
onready var animation_state = get_node("character").find_node("animation")
const juice_scene = preload("res://juice.tscn")
const juice_big_scene = preload("res://juice_big.tscn")
var target: Node = null
func is_blocking() -> bool:
return get_state() == "block" and fist.action_active
func get_state() -> String:
return animation_state.get_current_node()
func reset():
self.transform = init_transform
func _ready():
$impact.stream = damage_dealt_sound
animation_state.connect("animation_changed", self, "_on_animation_changed")
self.connect("deal_damage", self, "_on_deal_damage")
fist.connect("hit", self, "_on_fist_hit")
fist.connect("kick", self, "_on_kick")
fist.monitoring = false
init_transform = self.transform
var gamepads : Array = Input.get_connected_joypads()
print("gamepads:", gamepads)
if player_id == 0:
action_left = "player1_left"
action_right = "player1_right"
action_hit = "player1_hit"
action_block = "player1_block"
action_grab = "player1_grab"
controller_id = 0
elif player_id == 1:
action_left = "player2_left"
action_right = "player2_right"
action_hit = "player2_hit"
action_block = "player2_block"
action_grab = "player2_grab"
controller_id = 1
else:
assert(false, "Invalid player_id")
func _process(_delta):
match get_state():
"dummy":
animation_state.travel("idle")
"idle":
if Input.is_action_just_pressed(action_hit):
hit_targets.clear()
animation_state.travel("punch")
$punch.pitch_scale = rng.randf_range(0.9, 1.1)
$punch.play()
elif Input.is_action_just_pressed(action_block):
animation_state.travel("block")
$blocktry.pitch_scale = rng.randf_range(1.7, 2.0)
$blocktry.play()
elif Input.is_action_just_pressed(action_grab):
hit_targets.clear()
animation_state.travel("grab")
$grab.pitch_scale = rng.randf_range(0.3, 0.5)
$grab.play()
func _on_fist_hit(area: Area2D) -> void:
match get_state():
"punch":
if area.name == "hitbox":
var fighter = area.owner.get_parent()
if not hit_targets.has(fighter):
hit_targets.append(fighter)
if not fighter == self:
if fighter.is_blocking():
fist.reset_action()
animation_state.travel("stun")
fighter.blocksuccess()
else:
emit_signal("deal_damage", fighter, punch_damage)
$impact.pitch_scale = rng.randf_range(0.5, 3.0)
$impact.play()
fighter.interrupt()
"grab":
if area.name == "hitbox":
var fighter = area.owner.get_parent()
if not hit_targets.has(fighter):
hit_targets.append(fighter)
if not fighter == self and target == null:
target = fighter
target.getgrabbed()
animation_state.travel("kick")
$grabsuccess.pitch_scale = rng.randf_range(0.8, 1.2)
$grabsuccess.play()
_:
print("Hit callback called but not in a matching state.")
func _physics_process(delta):
if get_state() == "kicked":
var dir
if player_id == 0:
dir = -1.0
else:
dir = 1.0
move_and_collide(Vector2(dir * delta * throw_speed, 0))
elif get_state() != "stun" and get_state() != "grabbed" and get_state() != "kicked":
var velocity = 0.0
if Input.is_action_pressed(action_left):
velocity -= delta * speed
if Input.is_action_pressed(action_right):
velocity += delta * speed
move_and_collide(Vector2(velocity, 0))
func _on_kick() -> void:
emit_signal("deal_damage", target, kick_damage)
target.throw()
target = null
$kick.pitch_scale = rng.randf_range(0.8, 1.2)
$kick.play()
func throw() -> void:
animation_state.travel("kicked")
func getgrabbed() -> void:
animation_state.travel("grabbed")
func interrupt() -> void:
if get_state() == "grab":
fist.reset_action()
animation_state.travel("stun")
func blocksuccess() -> void:
fist.reset_action()
animation_state.travel("dummy")
$block.pitch_scale = rng.randf_range(0.8, 1.2)
$block.play()
func on_suffer(amount: float) -> void: # does not actually deal the damage, just for visuals
if amount == punch_damage:
var juice = juice_scene.instance()
juice_center.add_child(juice)
juice.emitting = true
elif amount == kick_damage:
var juice_big = juice_big_scene.instance()
juice_center.add_child(juice_big)
juice_big.emitting = true
elif amount == 1:
var juice = juice_scene.instance()
juice_center.add_child(juice)
juice.emitting = true
Input.start_joy_vibration(controller_id, 0, 1, 0.15)
$suffer.pitch_scale = rng.randf_range(1.5, 2.0)
$suffer.play()
else:
assert("No animation for that amount of damage.")
func _on_emotion_set(emotion) -> void:
smileface.visible = emotion == EMOTION.smile
happyface.visible = emotion == EMOTION.happy
cryface.visible = emotion == EMOTION.cry
func _on_animation_changed(old_anim: String, new_anim: String) -> void:
match new_anim:
"grabbed", "stun", "kicked":
self.emotion = EMOTION.cry
Input.start_joy_vibration(controller_id, 1, 0, 1)
"punch", "grab":
self.emotion = EMOTION.happy
_:
self.emotion = EMOTION.smile
func _on_deal_damage(target, damage) -> void:
Input.start_joy_vibration(controller_id, 0, 1, 0.15)
Input.start_joy_vibration(target.controller_id, 1, 1, damage/50.0)