Raise-Your-Wand/Scripts/combatant.gd
nc5432 847a41eaad Animations and bug fixes
- Converted the rock throw animation to the new system
- Converted the fireball animation to the new system (needs to be inverted still)
- Spell variable now get set to null after use or they get interrupted
- Made some code more readable
2024-05-13 22:38:17 -04:00

186 lines
5.1 KiB
GDScript

class_name Combatant extends Node2D
signal healthChanged(health: float)
signal stunned
@onready var renderer: AnimatedSprite2D = $AnimatedSprite2D
@onready var healthbar: HealthBar = $HealthBar
@onready var data: Data = get_node("/root/Root/Data")
@export var spellbook: Spellbook
@export var maxHealth: float = 10
@export var health: float = maxHealth
@export var player: bool = false
var spell: Spell
var spellIndex: int
var anim: AnimationBase
var casting: bool = false
var castCooldown: float = 0
var castProgress: int = 0
# Called when the node enters the scene tree for the first time.
func _ready():
renderer.animation_finished.connect(animationFinished)
renderer.play("idle")
healthbar.maxHealth = maxHealth
if !player:
spellbook.initCooldowns()
for spel: Spell in spellbook.spells:
if (spel == null): continue
if !data.animations.has(spel.animation):
data.animations[spel.animation] = load(spel.animation)
data.opponent = self
renderer.flip_h = true
healthbar.position.x *= -1
_finishedCasting()
else:
data.player = self
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if !player && !casting:
timing(delta)
func _finishedCasting() -> void:
casting = false
match data.difficulty:
Data.Difficulty.EASY: castCooldown = randf_range(2.7, 3.3)
Data.Difficulty.NORMAL: castCooldown = randf_range(0.8, 1.3)
Data.Difficulty.HARD: castCooldown = randf_range(0.3, 0.7)
Data.Difficulty.GAMER: castCooldown = 0
func timing(delta) -> void:
castCooldown -= delta
if castCooldown <= 0:
cast()
func cast() -> void:
casting = true
match data.difficulty:
Data.Difficulty.EASY:
spellIndex = randi_range(0, spellbook.spells.size() - 1)
Data.Difficulty.NORMAL:
spellIndex = randi_range(0, spellbook.spells.size() - 1)
Data.Difficulty.HARD:
spellIndex = randi_range(0, spellbook.spells.size() - 1)
Data.Difficulty.GAMER:
spellIndex = randi_range(0, spellbook.spells.size() - 1)
spell = spellbook.spells[spellIndex]
anim = data.animations[spell.animation].instantiate()
anim.setProgress(0, spell.castCombo.size())
anim.inverted = true
anim.spell = spell
anim.connect("animationFinished", finalizeSpell)
get_node("/root").add_child(anim)
attemptCast()
func attemptCast():
#if (!casting):
#_finishedCasting()
#return
match data.difficulty:
Data.Difficulty.EASY:
await get_tree().create_timer(randf_range(0.75, 1.75)).timeout
if (spell == null): return
if randi_range(0, 99) < 90:
castProgress += 1
if (is_instance_valid(anim)): anim.setProgress(castProgress)
if (castProgress == spell.castCombo.size()):
casting = false
castProgress = 0
renderer.play("attack1")
spellbook.cooldowns[spellIndex] = spell.cooldown
_finishedCasting()
return
else:
attemptCast()
else:
alterHealth(-spell.backfireStrength, true)
failCast()
return
Data.Difficulty.NORMAL:
await get_tree().create_timer(randf_range(0.6, 1.2)).timeout
if (spell == null): return
if randi_range(0, 99) < 95:
castProgress += 1
if (is_instance_valid(anim)): anim.setProgress(castProgress)
if (castProgress == spell.castCombo.size()):
casting = false
castProgress = 0
renderer.play("attack1")
spellbook.cooldowns[spellIndex] = spell.cooldown
_finishedCasting()
return
else:
attemptCast()
else:
alterHealth(-spell.backfireStrength, true)
failCast()
Data.Difficulty.HARD:
await get_tree().create_timer(randf_range(0.3, 0.75)).timeout
if (spell == null): return
if randi_range(0, 99) < 98:
castProgress += 1
if (is_instance_valid(anim)): anim.setProgress(castProgress)
if (castProgress == spell.castCombo.size()):
casting = false
castProgress = 0
renderer.play("attack1")
spellbook.cooldowns[spellIndex] = spell.cooldown
_finishedCasting()
return
else:
attemptCast()
else:
alterHealth(-spell.backfireStrength, true)
failCast()
Data.Difficulty.GAMER:
await get_tree().create_timer(.2).timeout
if (spell == null): return
castProgress += 1
if (is_instance_valid(anim)): anim.setProgress(castProgress)
if (castProgress == spell.castCombo.size()):
casting = false
castProgress = 0
renderer.play("attack1")
spellbook.cooldowns[spellIndex] = spell.cooldown
data.player.alterHealth(-spell.damage, false)
_finishedCasting()
return
else:
attemptCast()
func alterHealth(change: float, stun: bool) -> void:
health += change
if stun:
casting = false
renderer.play("hit")
if player:
stunned.emit()
else:
failCast()
healthChanged.emit(health)
func failCast() -> void:
casting = false
if (is_instance_valid(anim)): anim.castFailed()
castProgress = 0
if (spell != null): spellbook.cooldowns[spellIndex] = spell.cooldown * (float(castProgress) / float(spell.castCombo.size()))
spell = null
_finishedCasting()
return
func animationFinished() -> void:
renderer.play("idle")
func finalizeSpell(finish: Spell) -> void:
if (player):
data.opponent.alterHealth(-finish.damage, finish.stunning)
else:
data.player.alterHealth(-finish.damage, finish.stunning)