Raise-Your-Wand/Scripts/combatant.gd

191 lines
5.4 KiB
GDScript3
Raw Normal View History

class_name Combatant extends Node2D
signal healthChanged(health: float)
signal stunned
@onready var renderer: AnimatedSprite2D = $AnimatedSprite2D
@onready var healthbar: HealthBar = $HealthBar
2024-05-10 13:33:08 -04:00
@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
var defending: Array[Spell]
# 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():
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
defending.append(spell)
_finishedCasting()
return
else:
attemptCast()
else:
alterHealth(-spell.backfireStrength, true, spell.element)
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
defending.append(spell)
_finishedCasting()
return
else:
attemptCast()
else:
alterHealth(-spell.backfireStrength, true, spell.element)
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
defending.append(spell)
_finishedCasting()
return
else:
attemptCast()
else:
alterHealth(-spell.backfireStrength, true, spell.element)
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
defending.append(spell)
_finishedCasting()
return
else:
attemptCast()
func alterHealth(change: float, stun: bool, element: Data.Element) -> void:
for spel in defending:
change *= spel.blockStrength[element]
print("Blocking with spell " + spel.name)
health += change
if stun:
casting = false
renderer.play("hit")
if player:
stunned.emit()
else:
failCast()
healthChanged.emit(health)
2024-05-02 14:28:44 -04:00
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:
defending.erase(spell)
if (player):
data.opponent.alterHealth(-finish.damage, finish.stunning, finish.element)
else:
data.player.alterHealth(-finish.damage, finish.stunning, finish.element)