Skip to content

Commit d3721df

Browse files
committed
New combat anims mostly working
1 parent 636a6cb commit d3721df

17 files changed

Lines changed: 377 additions & 136 deletions

Attacks/PlayerOnly/RamPCAttack.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func getAnticipationText(_attacker, _receiver):
4444
return "{attacker.name} lunges forward and tries to kick you"
4545

4646
func getAttackSoloAnimation():
47-
return "shove"
47+
return "charge"
4848

4949
func getExperience():
5050
return [[Skill.Combat, 10]]

Game/BaseCharacter.gd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3943,3 +3943,6 @@ func calculatePowerScore(ignoreCurrentState:bool = false) -> float:
39433943
finalScore *= (1.0 - getStaminaLevel()*0.5)
39443944

39453945
return finalScore
3946+
3947+
func getCombatStance() -> int:
3948+
return CombatStance.STANCE_COMBAT_DEFAULT

Player/Player.gd

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ var tfHolder:TFHolder
3333

3434
var dynamicPersonality: bool = false
3535

36+
var combatStance:int = CombatStance.STANCE_COMBAT_DEFAULT
37+
3638
func _init():
3739
initialDodgeChance = 0.05 # Player has a small chance to dodge anything
3840

@@ -427,6 +429,7 @@ func saveData():
427429
"pickedSkinRColor": pickedSkinRColor.to_html(),
428430
"pickedSkinGColor": pickedSkinGColor.to_html(),
429431
"pickedSkinBColor": pickedSkinBColor.to_html(),
432+
"combatStance": combatStance,
430433
}
431434

432435
data["bodyparts"] = {}
@@ -481,6 +484,7 @@ func loadData(data):
481484
pickedSkinRColor = Color(SAVE.loadVar(data, "pickedSkinRColor", "ffffff"))
482485
pickedSkinGColor = Color(SAVE.loadVar(data, "pickedSkinGColor", "cccccc"))
483486
pickedSkinBColor = Color(SAVE.loadVar(data, "pickedSkinBColor", "999999"))
487+
combatStance = SAVE.loadVar(data, "combatStance", CombatStance.STANCE_COMBAT_DEFAULT)
484488

485489
resetSlots()
486490
var loadedBodyparts = SAVE.loadVar(data, "bodyparts", {})
@@ -1017,3 +1021,9 @@ func isSlaveTo(_charID:String) -> bool:
10171021
if(theSpecial.id == "SoftSlavery"):
10181022
return true
10191023
return false
1024+
1025+
func getCombatStance() -> int:
1026+
return combatStance
1027+
1028+
func switchToNextCombatStance():
1029+
combatStance = Util.getNextInArray(CombatStance.getAllPlayerCanChoose(), combatStance)

Player/Player3D/CombatAnims/CombatAnimApplier.gd

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,31 @@ func applyCombatAnims():
88
var theAnim:CombatAnimBase = GlobalRegistry.combatAnims[theID]
99

1010
if(!theAnim.animName.empty()):
11-
var newAnimNode:AnimationNodeAnimation = AnimationNodeAnimation.new()
12-
newAnimNode.animation = theAnim.animName
13-
14-
theCombatAnimTree.add_node(theAnim.animName, newAnimNode)
15-
16-
addTransition("IDLE", theAnim.animName, theAnim.fadeIn)
17-
addTransition(theAnim.animName, "IDLE", theAnim.fadeOut, !theAnim.isLooped)
18-
11+
if(theCombatAnimTree.has_node(theAnim.animName)):
12+
if(!theAnim.allowStateReuse):
13+
Log.printerr("ANIM STATE "+theAnim.animName+" ALREADY EXISTS")
14+
else:
15+
var newAnimNode:AnimationNodeAnimation = AnimationNodeAnimation.new()
16+
newAnimNode.animation = theAnim.animName
17+
18+
theCombatAnimTree.add_node(theAnim.animName, newAnimNode)
19+
20+
addTransition("IDLE", theAnim.animName, theAnim.fadeIn)
21+
addTransition(theAnim.animName, "IDLE", theAnim.fadeOut, !theAnim.isLooped)
22+
1923
if(!theAnim.animNameKnockedDown.empty()):
20-
var newAnimNode:AnimationNodeAnimation = AnimationNodeAnimation.new()
21-
newAnimNode.animation = theAnim.animNameKnockedDown
22-
23-
theCombatAnimTree.add_node(theAnim.animNameKnockedDown, newAnimNode)
24-
25-
addTransition("KnockedDown-loop", theAnim.animNameKnockedDown, theAnim.fadeIn)
26-
addTransition(theAnim.animNameKnockedDown, "KnockedDown-loop", theAnim.fadeOut, !theAnim.isLooped)
27-
24+
if(theCombatAnimTree.has_node(theAnim.animNameKnockedDown)):
25+
if(!theAnim.allowStateReuse):
26+
Log.printerr("KNOCKED DOWN ANIM STATE "+theAnim.animNameKnockedDown+" ALREADY EXISTS")
27+
else:
28+
var newAnimNode:AnimationNodeAnimation = AnimationNodeAnimation.new()
29+
newAnimNode.animation = theAnim.animNameKnockedDown
30+
31+
theCombatAnimTree.add_node(theAnim.animNameKnockedDown, newAnimNode)
32+
33+
addTransition("KnockedDown-loop", theAnim.animNameKnockedDown, theAnim.fadeIn)
34+
addTransition(theAnim.animNameKnockedDown, "KnockedDown-loop", theAnim.fadeOut, !theAnim.isLooped)
35+
2836

2937
func addTransition(_from:String, _to:String, _time:float, _autoAdvance:bool = false):
3038
var theTrans := AnimationNodeStateMachineTransition.new()

Player/Player3D/CombatAnims/CombatAnimBase.gd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ var weaponLeft:String = ""
2323
var weaponRight:String = ""
2424

2525
var weaponOverrideLeft:bool = false
26+
27+
var allowStateReuse:bool = false

Player/Player3D/CombatAnims/CombatAnimPack.gd

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,94 @@ func _init():
1111
static func frames(_num:int) -> float:
1212
return float(_num)/24.0
1313

14+
const HD := 3 # Hit delay offset
15+
const HDD := 3 # Hit delay knocked down
16+
1417
func doAdd():
1518
if(true):
1619
var theAnim := CombatAnimBase.new()
1720
theAnim.id = "bite"
1821
theAnim.animName = "Bite"
22+
theAnim.hitDelay = frames(25 -HD)
1923
theAnim.animNameKnockedDown = "KnockedDownBite"
24+
theAnim.hitDelayKnockedDown = frames(16 -HDD)
2025
anims[theAnim.id] = theAnim
2126
if(true):
2227
var theAnim := CombatAnimBase.new()
2328
theAnim.id = "punch"
2429
theAnim.animName = "Punch"
30+
theAnim.hitDelay = frames(19 -HD)
2531
theAnim.animNameKnockedDown = "KnockedDownPunch"
32+
theAnim.hitDelayKnockedDown = frames(12 -HDD)
2633
theAnim.fists = true
2734
anims[theAnim.id] = theAnim
2835
if(true):
2936
var theAnim := CombatAnimBase.new()
3037
theAnim.id = "kick"
3138
theAnim.animName = "Kick"
39+
theAnim.hitDelay = frames(21 -HD)
3240
theAnim.animNameKnockedDown = "KnockedDownKick"
41+
theAnim.hitDelayKnockedDown = frames(14 -HDD)
3342
anims[theAnim.id] = theAnim
3443
if(true):
3544
var theAnim := CombatAnimBase.new()
3645
theAnim.id = "shove"
3746
theAnim.animName = "Shove"
47+
theAnim.hitDelay = frames(22 -HD)
3848
theAnim.animNameKnockedDown = "KnockedDownShove"
49+
theAnim.hitDelayKnockedDown = frames(7 -HDD)
3950
anims[theAnim.id] = theAnim
4051
if(true):
4152
var theAnim := CombatAnimBase.new()
4253
theAnim.id = "stunbaton"
4354
theAnim.animName = "WeaponSwing"
55+
theAnim.hitDelay = frames(16 -HD)
4456
theAnim.animNameKnockedDown = "KnockedDownWeaponSwing"
57+
theAnim.hitDelayKnockedDown = frames(13 -HDD)
4558
theAnim.fists = true
4659
theAnim.weaponRight = "res://Inventory/UnriggedModels/StunBaton/StunBaton.tscn"
4760
theAnim.weaponOverrideLeft = false
4861
anims[theAnim.id] = theAnim
62+
if(true):
63+
var theAnim := CombatAnimBase.new()
64+
theAnim.id = "throw"
65+
theAnim.animName = "WeaponThrow"
66+
theAnim.hitDelay = frames(22 -HD)
67+
theAnim.animNameKnockedDown = "KnockedDownThrow"
68+
theAnim.hitDelayKnockedDown = frames(18 -HDD)
69+
theAnim.fists = true
70+
#theAnim.weaponRight = "res://Inventory/UnriggedModels/StunBaton/StunBaton.tscn"
71+
theAnim.weaponOverrideLeft = false
72+
anims[theAnim.id] = theAnim
73+
if(true):
74+
var theAnim := CombatAnimBase.new()
75+
theAnim.id = "shiv"
76+
theAnim.animName = "WeaponShiv"
77+
theAnim.hitDelay = frames(18 -HD)
78+
theAnim.animNameKnockedDown = "KnockedDownWeaponShiv"
79+
theAnim.hitDelayKnockedDown = frames(20 -HDD)
80+
theAnim.fists = true
81+
theAnim.weaponRight = "res://Inventory/UnriggedModels/Shiv/Shiv.tscn"
82+
theAnim.weaponOverrideLeft = false
83+
anims[theAnim.id] = theAnim
84+
if(true):
85+
var theAnim := CombatAnimBase.new()
86+
theAnim.id = "firepistol"
87+
theAnim.animName = "WeaponGunShootCombat"
88+
theAnim.hitDelay = frames(11 -HD)
89+
theAnim.animNameKnockedDown = "KnockedDownPistolFire"
90+
theAnim.hitDelayKnockedDown = frames(12 -HDD)
91+
theAnim.fists = true
92+
theAnim.weaponLeft = "res://Inventory/UnriggedModels/EnergyPistol/EnergyPistolBlue.tscn"
93+
theAnim.weaponOverrideLeft = true
94+
anims[theAnim.id] = theAnim
95+
if(true):
96+
var theAnim := CombatAnimBase.new()
97+
theAnim.id = "charge"
98+
theAnim.animName = "AttackCharge"
99+
theAnim.hitDelay = frames(9 -HD)
100+
theAnim.animNameKnockedDown = "KnockedDownShove" # No unique knocked down version
101+
theAnim.hitDelayKnockedDown = frames(7 -HDD)
102+
theAnim.allowStateReuse = true
103+
#theAnim.fists = true
104+
anims[theAnim.id] = theAnim

Player/Player3D/CombatAnims/CombatAnimPlayer.gd

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ func addChar(_id:int):
3232
theChar.connect("playAnim", self, "onCharPlayAnim")
3333
chars[_id] = theChar
3434

35-
func playAnimRaw(_charID:int, _animStanding:String, _animKnockedDown:String = ""):
35+
func playAnimRaw(_charID:int, _animStanding:String, _animKnockedDown:String = "", _customWeapon:String = "", _customWeaponRight:String = "", _fists:bool = false):
3636
queue.append([
37-
QUEUE_ANIMRAW, _charID, _animStanding, _animKnockedDown,
37+
QUEUE_ANIMRAW, _charID, _animStanding, _animKnockedDown, _customWeapon, _customWeaponRight, _fists,
3838
])
3939

40-
func addAttackPayload(_attackID:String, _attackerID:int, _attackerStatus:int, _defenderStatus:int):
41-
playAttack(_attackID, _attackerID, _attackerStatus, _defenderStatus)
40+
func addAttackPayload(_attackID:String, _attackerID:int, _attackerStatus:int, _defenderStatus:int, _customWeapon:String = ""):
41+
playAttack(_attackID, _attackerID, _attackerStatus, _defenderStatus, _customWeapon)
4242
playAttackReaction(_attackID, 1-_attackerID, _attackerStatus, _defenderStatus)
4343
addBarrierNotBusy()
4444

@@ -51,9 +51,9 @@ func addStatusCheckPayload(_attackerStatus:int, _defenderStatus:int):
5151
])
5252
addBarrierNotBusy()
5353

54-
func playAttack(_attackID:String, _attackerID:int, _attackerStatus:int, _defenderStatus:int):
54+
func playAttack(_attackID:String, _attackerID:int, _attackerStatus:int, _defenderStatus:int, _customWeapon:String = ""):
5555
queue.append([
56-
QUEUE_ATTACK, _attackID, _attackerID, _attackerStatus, _defenderStatus,
56+
QUEUE_ATTACK, _attackID, _attackerID, _attackerStatus, _defenderStatus, _customWeapon,
5757
])
5858

5959
func playAttackReaction(_attackID:String, _receiver:int, _attackerStatus:int, _defenderStatus:int):
@@ -85,17 +85,40 @@ func processQueue(_dt:float):
8585
return
8686

8787
elif(theType == QUEUE_ANIMRAW): # Support for fists/weapons would be nice
88+
var theAttackAnim:String = theEntry[2]
8889
var theAttackerID:int = theEntry[1]
90+
var theCustomWeapon:String = theEntry[4]
8991
var theChar:CombatAnimPlayerChar = chars[theAttackerID]
9092
var _isKnockedDown:bool = theChar.knockedDown
91-
if(!_isKnockedDown):
92-
var theAnim:String = theEntry[2]
93-
if(!theAnim.empty()):
94-
theChar.addAnim(theAnim)
95-
else:
96-
var theAnim:String = theEntry[3]
97-
if(!theAnim.empty()):
98-
theChar.addAnim(theAnim)
93+
94+
if(GlobalRegistry.combatAnims.has(theAttackAnim)):
95+
var theAttack:CombatAnimBase = GlobalRegistry.getCombatAnim(theAttackAnim)
96+
var theWeaponLeft:String = theAttack.weaponLeft
97+
var theWeaponRight:String = theAttack.weaponRight
98+
var theFists:bool = theAttack.fists
99+
if(!theCustomWeapon.empty()):
100+
if(theAttack.weaponOverrideLeft):
101+
theWeaponLeft = theCustomWeapon
102+
else:
103+
theWeaponRight = theCustomWeapon
104+
if(!_isKnockedDown):
105+
theChar.addAnim(theAttack.animName, [theFists, theWeaponLeft, theWeaponRight])
106+
else:
107+
theChar.addAnim(theAttack.animNameKnockedDown, [theFists, theWeaponLeft, theWeaponRight])
108+
else: # Just a normal anim
109+
var theCustomWeaponRight:String = theEntry[5]
110+
var theFists:bool = theEntry[6]
111+
if(!theCustomWeapon.empty() || !theCustomWeaponRight.empty()):
112+
theFists = true
113+
114+
if(!_isKnockedDown):
115+
var theAnim:String = theEntry[2]
116+
if(!theAnim.empty()):
117+
theChar.addAnim(theAnim, [theFists, theCustomWeapon, theCustomWeaponRight])
118+
else:
119+
var theAnim:String = theEntry[3]
120+
if(!theAnim.empty()):
121+
theChar.addAnim(theAnim, [theFists, theCustomWeapon, theCustomWeaponRight])
99122

100123
elif(theType == QUEUE_STATUSCHECK):
101124
var theAttackerID:int = theEntry[1]
@@ -110,21 +133,35 @@ func processQueue(_dt:float):
110133
theChar.knockedDown = _shouldBeKnockedDown
111134

112135
elif(theType == QUEUE_ATTACK):
113-
var theAttack:CombatAnimBase = GlobalRegistry.getCombatAnim(theEntry[1])
136+
var theAttackID:String = theEntry[1]
137+
if(theAttackID.empty()):
138+
queue.pop_front()
139+
return
140+
var theAttack:CombatAnimBase = GlobalRegistry.getCombatAnim(theAttackID)
114141
if(!theAttack):
115142
queue.pop_front()
116143
return
117144
var theAttackerID:int = theEntry[2]
118145
var _theAttackerStatus:int = theEntry[3]
146+
var theCustomWeapon:String = theEntry[5]
119147
var theChar:CombatAnimPlayerChar = chars[theAttackerID]
120148

121149
var _shouldBeKnockedDown:bool = _theAttackerStatus & ST_KNOCKEDDOWN
122150
var _isKnockedDown:bool = theChar.knockedDown
123151

152+
var theWeaponLeft:String = theAttack.weaponLeft
153+
var theWeaponRight:String = theAttack.weaponRight
154+
var theFists:bool = theAttack.fists
155+
if(!theCustomWeapon.empty()):
156+
if(theAttack.weaponOverrideLeft):
157+
theWeaponLeft = theCustomWeapon
158+
else:
159+
theWeaponRight = theCustomWeapon
160+
124161
if(!_isKnockedDown):
125-
theChar.addAnim(theAttack.animName, [theAttack.fists, theAttack.weaponLeft, theAttack.weaponRight])
162+
theChar.addAnim(theAttack.animName, [theFists, theWeaponLeft, theWeaponRight])
126163
else:
127-
theChar.addAnim(theAttack.animNameKnockedDown, [theAttack.fists, theAttack.weaponLeft, theAttack.weaponRight])
164+
theChar.addAnim(theAttack.animNameKnockedDown, [theFists, theWeaponLeft, theWeaponRight])
128165

129166
if(_isKnockedDown && !_shouldBeKnockedDown):
130167
theChar.addAnim("KnockedDownToStanding")
@@ -134,7 +171,11 @@ func processQueue(_dt:float):
134171
theChar.knockedDown = _shouldBeKnockedDown
135172

136173
elif(theType == QUEUE_ATTACKREACTION):
137-
var theAttack:CombatAnimBase = GlobalRegistry.getCombatAnim(theEntry[1])
174+
var theAttackID:String = theEntry[1]
175+
if(theAttackID.empty()):
176+
queue.pop_front()
177+
return
178+
var theAttack:CombatAnimBase = GlobalRegistry.getCombatAnim(theAttackID)
138179
if(!theAttack):
139180
queue.pop_front()
140181
return
@@ -152,12 +193,12 @@ func processQueue(_dt:float):
152193
var theHitDelay:float = theAttack.hitDelay if !_shouldAttackerBeKnockedDown else theAttack.hitDelayKnockedDown
153194

154195
if(_theReceiverStatus & ST_DODGING):
155-
# Don't need any delay here
196+
theChar.addWait(theHitDelay-0.2)
156197
if(!_isKnockedDown):
157198
theChar.addAnim("Dodge")
158199
elif(_theReceiverStatus & ST_BLOCKING):
159200
# Somehow guess the delay?
160-
theChar.addWait(theHitDelay-0.3)
201+
theChar.addWait(theHitDelay-0.4)
161202
if(!_isKnockedDown):
162203
theChar.addAnim("Block", [true])
163204
else:
@@ -171,7 +212,12 @@ func processQueue(_dt:float):
171212
theChar.addAnim("KnockedDownGetHit")
172213
# ADD MORE HIT REACTIONS HERE IF YOU NEED THEM
173214

174-
if(_isKnockedDown && !_shouldBeKnockedDown):
215+
if(_theReceiverStatus & ST_DEFEATED):
216+
if(_isKnockedDown):
217+
theChar.addAnim("KnockedDownDefeat")
218+
else:
219+
theChar.addAnim("Defeat")
220+
elif(_isKnockedDown && !_shouldBeKnockedDown):
175221
theChar.addAnim("KnockedDownToStanding")
176222
if(!_isKnockedDown && _shouldBeKnockedDown):
177223
theChar.addAnim("StandingToKnockedDown")

Player/Player3D/CombatAnims/CombatAnimPlayerChar.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func addAnimNoWait(_anim:String, _args:Array = []):
1919

2020
func addAnim(_anim:String, _args:Array = []):
2121
queue.append([DO_ANIM, _anim, _args])
22-
addWait(getAnimLen(_anim))
22+
addWait(getAnimLen(_anim)+0.01)
2323

2424
func isBusy() -> bool:
2525
return !queue.empty()

0 commit comments

Comments
 (0)