Compare commits
2 Commits
eb7cbf97d9
...
6ecbd2e5a2
| Author | SHA1 | Date |
|---|---|---|
|
|
6ecbd2e5a2 | 1 year ago |
|
|
3cf39c7135 | 1 year ago |
@ -1,2 +1,6 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
|
||||
assets/binary files/elements_core_pack_2.14.24/
|
||||
|
||||
*.zip
|
||||
@ -1,21 +0,0 @@
|
||||
|
||||
class_name Attack
|
||||
extends CombatAction
|
||||
|
||||
|
||||
func _ready():
|
||||
ActionName = "Attack"
|
||||
|
||||
var timer
|
||||
func execute():
|
||||
timer = Timer.new()
|
||||
timer.timeout.connect(done)
|
||||
timer.wait_time = 1
|
||||
add_child(timer)
|
||||
timer.start()
|
||||
print("Executing Attack!")
|
||||
|
||||
func done():
|
||||
timer.queue_free()
|
||||
action_finished.emit()
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
|
||||
class_name CombatAction
|
||||
extends Node
|
||||
|
||||
|
||||
@export var ActionName = "NONE"
|
||||
@export var ActionText = ""
|
||||
|
||||
var ActionIndex = 0
|
||||
|
||||
signal action_finished
|
||||
|
||||
func _ready():
|
||||
if ActionName == "NONE":
|
||||
push_warning("Actions has NONE name")
|
||||
|
||||
func execute():
|
||||
push_warning("Base Action execute method called")
|
||||
@ -1,6 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bbbyup8pp6uam"]
|
||||
|
||||
[ext_resource type="Script" path="res://Systems/Combat/Actions/Scripts/attack.gd" id="1_nmi0m"]
|
||||
|
||||
[node name="attack" type="Node"]
|
||||
script = ExtResource("1_nmi0m")
|
||||
@ -1,6 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://djn8b685adlak"]
|
||||
|
||||
[ext_resource type="Script" path="res://Systems/Combat/Actions/Scripts/combat_action.gd" id="1_sqc33"]
|
||||
|
||||
[node name="action" type="Node"]
|
||||
script = ExtResource("1_sqc33")
|
||||
@ -1,6 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://ch1sc85jxy1r7"]
|
||||
|
||||
[ext_resource type="Script" path="res://Systems/Combat/Scripts/Combatant.gd" id="1_4hh5d"]
|
||||
|
||||
[node name="Combatant" type="Node"]
|
||||
script = ExtResource("1_4hh5d")
|
||||
@ -1,47 +0,0 @@
|
||||
extends Node
|
||||
class_name Combatant
|
||||
|
||||
# @export var Behavior:
|
||||
|
||||
@export var Controller: CombatantController
|
||||
@export var Stats: CombatStats
|
||||
@export var ATBSpeedCoeffecient = 25
|
||||
|
||||
#@onready var ATB = $battle_menu/ATB
|
||||
|
||||
var is_init = false
|
||||
var ATBCurrent = 0
|
||||
|
||||
signal atb_update(atb_current)
|
||||
|
||||
func _ready():
|
||||
Controller.init_combat(Stats)
|
||||
|
||||
|
||||
func next_turn():
|
||||
ATBCurrent = 0
|
||||
|
||||
# TODO: Tick status effects
|
||||
|
||||
func tick_atb(delta):
|
||||
|
||||
if ATBCurrent >= 100:
|
||||
ATBCurrent = 100
|
||||
return
|
||||
|
||||
ATBCurrent += Stats.Speed * delta * ATBSpeedCoeffecient
|
||||
atb_update.emit(ATBCurrent)
|
||||
|
||||
#ATB.value = ATBCurrent
|
||||
|
||||
|
||||
func _process(delta):
|
||||
|
||||
tick_atb(delta)
|
||||
#
|
||||
#func init():
|
||||
# for action in Actions:
|
||||
# print("Action: %s" % action.ActionName)
|
||||
# Menu.add_action(action)
|
||||
#
|
||||
# is_init = true
|
||||
@ -1,51 +0,0 @@
|
||||
extends CombatantController
|
||||
|
||||
@export var Name = "NONE"
|
||||
@export var TeamPosition = 0
|
||||
|
||||
@onready var Menu = $battle_menu
|
||||
|
||||
func init_combat(stats):
|
||||
Menu.init_state(Name, stats, TeamPosition)
|
||||
|
||||
func on_atb_update(new):
|
||||
Menu.ATB.value = new
|
||||
|
||||
|
||||
#@export var SpecialActions: Array[Action] = []
|
||||
#
|
||||
#@onready var ATB = $battle_menu/ATB
|
||||
#@onready var ActionState = $battle_menu/ActionPanel/ActionState
|
||||
#@onready var Actions = $Combatant/Actions
|
||||
#var NextAction
|
||||
#var ActionReady = false
|
||||
#
|
||||
#
|
||||
#func _process(delta):
|
||||
#
|
||||
# var combatant = $Combatant
|
||||
# if ActionReady and ATB.value == 100:
|
||||
# NextAction.execute()
|
||||
# ActionState.text = "Action Executing: %s" % NextAction.ActionName
|
||||
# combatant.ATBCurrent = 0
|
||||
# ATB.value = 0
|
||||
# ActionReady = false
|
||||
# return
|
||||
#
|
||||
#
|
||||
# combatant.tick_atb(delta)
|
||||
#
|
||||
#
|
||||
#func do_action(a):
|
||||
#
|
||||
# var action = Actions.get_node(a)
|
||||
# if !action:
|
||||
# push_error("Unknown battle action: %s" % a)
|
||||
# return
|
||||
#
|
||||
# ActionState.text = "Action Queued: %s" % action.ActionName
|
||||
# NextAction = action
|
||||
# ActionReady = true
|
||||
#
|
||||
#func action_done():
|
||||
# ActionState.text = ""
|
||||
@ -1,38 +0,0 @@
|
||||
extends Resource
|
||||
class_name CombatStats
|
||||
|
||||
# Health
|
||||
@export var MaxHP = 10
|
||||
var HP = MaxHP
|
||||
|
||||
# Needed to use physical techniques
|
||||
@export var MaxPhysicalStamina = 10
|
||||
var PhysicalStamina = MaxPhysicalStamina
|
||||
|
||||
# Needed to use magic
|
||||
@export var MaxMentalStamina = 10
|
||||
var MentalStamina = MaxMentalStamina
|
||||
|
||||
# Physical Attack Power
|
||||
@export var Strength = 1
|
||||
|
||||
# Magic Offense
|
||||
@export var Wisdom = 1
|
||||
|
||||
# Physical Defense
|
||||
@export var Constitution = 1
|
||||
|
||||
# Magic Defense
|
||||
@export var Willpower = 1
|
||||
|
||||
# Battle turn order or ATB time
|
||||
@export var Speed = 1
|
||||
|
||||
# Critical hit chance
|
||||
@export var Focus = 1
|
||||
|
||||
# Chance to hit
|
||||
@export var Accuracy = 1
|
||||
|
||||
# Chance to dodge
|
||||
@export var Agility = 1
|
||||
@ -1,6 +0,0 @@
|
||||
extends Node
|
||||
class_name CombatantController
|
||||
|
||||
|
||||
func init_combat(stats):
|
||||
push_warning("Base init_combat method called")
|
||||
@ -1,6 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dokn6d31y1bxv"]
|
||||
|
||||
[ext_resource type="Script" path="res://Systems/Combat/Scripts/combatant_controller.gd" id="1_kxwx8"]
|
||||
|
||||
[node name="CombatantController" type="Node"]
|
||||
script = ExtResource("1_kxwx8")
|
||||
@ -1,12 +0,0 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://b0swegor2jejg"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dokn6d31y1bxv" path="res://Systems/Combat/combatant_controller.tscn" id="1_f3a3l"]
|
||||
[ext_resource type="Script" path="res://Systems/Combat/Scripts/PlayerCombatantController.gd" id="2_rhclm"]
|
||||
[ext_resource type="PackedScene" uid="uid://cl5d768roh8ir" path="res://Systems/UI/Menu System/battle_menu.tscn" id="3_7ys45"]
|
||||
|
||||
[node name="PlayerCombatantController" instance=ExtResource("1_f3a3l")]
|
||||
script = ExtResource("2_rhclm")
|
||||
Name = "NONE"
|
||||
TeamPosition = 0
|
||||
|
||||
[node name="battle_menu" parent="." index="0" instance=ExtResource("3_7ys45")]
|
||||
@ -1,43 +0,0 @@
|
||||
extends Control
|
||||
class_name BattleMenu
|
||||
|
||||
@onready var BasePanel = $Panel
|
||||
@onready var Name = $Panel/InfoPanel/Name
|
||||
@onready var HP = $Panel/InfoPanel/HP
|
||||
@onready var MStam = $Panel/InfoPanel/MentalStamina
|
||||
@onready var PStam = $Panel/InfoPanel/PhysicalStamina
|
||||
|
||||
@onready var ATB = $Panel/InfoPanel/ATB
|
||||
|
||||
var top_margin = 100
|
||||
var item_padding = 10
|
||||
|
||||
enum ACTION { ATTACK, DEFEND, ITEM }
|
||||
|
||||
signal action_selected(action)
|
||||
|
||||
func init_state(name, stats, team_position):
|
||||
offset_top = 300
|
||||
offset_left = BasePanel.size.x * team_position
|
||||
Name.text = name
|
||||
HP.text = "HP: %s/%s" % [stats.HP, stats.MaxHP]
|
||||
MStam.text = "M Stam: %s/%s" % [stats.MentalStamina, stats.MaxMentalStamina]
|
||||
PStam.text = "P Stam: %s/%s" % [stats.PhysicalStamina, stats.MaxPhysicalStamina]
|
||||
|
||||
# TODO Set the rest of the stats
|
||||
|
||||
|
||||
func _on_attack_pressed():
|
||||
action_selected.emit("attack")
|
||||
|
||||
|
||||
func _on_defend_pressed():
|
||||
action_selected.emit("defend")
|
||||
|
||||
|
||||
func _on_item_pressed():
|
||||
pass # GO TO SUBMENU HERE
|
||||
|
||||
|
||||
func _on_tech_pressed():
|
||||
pass # GO TO SUBMENU HERE
|
||||
@ -1,17 +0,0 @@
|
||||
extends Control
|
||||
class_name MenuItem
|
||||
|
||||
@export var label = ""
|
||||
@export var action: CombatAction
|
||||
|
||||
@onready var button = $Button
|
||||
|
||||
signal action_selected(action: CombatAction)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
button.text = label
|
||||
|
||||
|
||||
func _on_button_pressed():
|
||||
emit_signal("action_selected", action)
|
||||
@ -1,217 +0,0 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://cl5d768roh8ir"]
|
||||
|
||||
[ext_resource type="Script" path="res://Systems/UI/Menu System/Scripts/battle_menu.gd" id="1_fije1"]
|
||||
[ext_resource type="Texture2D" uid="uid://dqf1p1mfki3vc" path="res://assets/art/ui/bar_under.png" id="2_ayq4q"]
|
||||
[ext_resource type="Texture2D" uid="uid://bnp5t7o26kb0c" path="res://assets/art/ui/bar_over.png" id="3_s7h0n"]
|
||||
|
||||
[node name="battle_menu" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_fije1")
|
||||
|
||||
[node name="Panel" type="Panel" parent="."]
|
||||
layout_mode = 1
|
||||
offset_right = 190.0
|
||||
offset_bottom = 408.0
|
||||
|
||||
[node name="InfoPanel" type="Panel" parent="Panel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -85.0
|
||||
offset_right = 85.0
|
||||
offset_bottom = 148.0
|
||||
grow_horizontal = 2
|
||||
|
||||
[node name="ATB" type="TextureProgressBar" parent="Panel/InfoPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 7
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -85.0
|
||||
offset_top = -29.0
|
||||
offset_right = 185.0
|
||||
offset_bottom = 21.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
scale = Vector2(0.63, 0.403)
|
||||
value = 50.0
|
||||
texture_under = ExtResource("2_ayq4q")
|
||||
texture_progress = ExtResource("3_s7h0n")
|
||||
texture_progress_offset = Vector2(16, 8)
|
||||
|
||||
[node name="Name" type="Label" parent="Panel/InfoPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -52.5
|
||||
offset_right = 52.5
|
||||
offset_bottom = 26.0
|
||||
grow_horizontal = 2
|
||||
text = "Fighter Name
|
||||
"
|
||||
|
||||
[node name="HP" type="Label" parent="Panel/InfoPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -71.5
|
||||
offset_top = 26.0
|
||||
offset_right = 71.5
|
||||
offset_bottom = 52.0
|
||||
grow_horizontal = 2
|
||||
text = "CurrentHP/MaxHP
|
||||
"
|
||||
|
||||
[node name="MentalStamina" type="Label" parent="Panel/InfoPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -71.5
|
||||
offset_top = 52.0
|
||||
offset_right = 71.5
|
||||
offset_bottom = 78.0
|
||||
grow_horizontal = 2
|
||||
text = "Current/Max
|
||||
"
|
||||
|
||||
[node name="PhysicalStamina" type="Label" parent="Panel/InfoPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -71.5
|
||||
offset_top = 78.0
|
||||
offset_right = 71.5
|
||||
offset_bottom = 104.0
|
||||
grow_horizontal = 2
|
||||
text = "Current/Max
|
||||
"
|
||||
|
||||
[node name="Label" type="Label" parent="Panel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -56.0
|
||||
offset_top = 159.0
|
||||
offset_right = 57.0
|
||||
offset_bottom = 188.0
|
||||
grow_horizontal = 2
|
||||
text = "Battle Menu"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="MenuPanel" type="Panel" parent="Panel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -72.0
|
||||
offset_top = 190.0
|
||||
offset_right = 75.0
|
||||
offset_bottom = 373.0
|
||||
grow_horizontal = 2
|
||||
|
||||
[node name="Attack" type="Button" parent="Panel/MenuPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -35.0
|
||||
offset_top = 6.0
|
||||
offset_right = 35.0
|
||||
offset_bottom = 37.0
|
||||
grow_horizontal = 2
|
||||
text = "Attack
|
||||
"
|
||||
|
||||
[node name="Tech" type="Button" parent="Panel/MenuPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -35.0
|
||||
offset_top = 41.0
|
||||
offset_right = 35.0
|
||||
offset_bottom = 72.0
|
||||
grow_horizontal = 2
|
||||
text = "Tech"
|
||||
|
||||
[node name="Defend" type="Button" parent="Panel/MenuPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -35.0
|
||||
offset_top = 76.0
|
||||
offset_right = 35.0
|
||||
offset_bottom = 107.0
|
||||
grow_horizontal = 2
|
||||
text = "Defend"
|
||||
|
||||
[node name="Item" type="Button" parent="Panel/MenuPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -35.5
|
||||
offset_top = 111.0
|
||||
offset_right = 34.5
|
||||
offset_bottom = 142.0
|
||||
grow_horizontal = 2
|
||||
text = "Item"
|
||||
|
||||
[node name="Rest" type="Button" parent="Panel/MenuPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -35.5
|
||||
offset_top = 146.0
|
||||
offset_right = 34.5
|
||||
offset_bottom = 177.0
|
||||
grow_horizontal = 2
|
||||
text = "Rest"
|
||||
|
||||
[node name="ActionPanel" type="Panel" parent="Panel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 12
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = -33.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
|
||||
[node name="ActionState" type="Label" parent="Panel/ActionPanel"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -85.0
|
||||
offset_top = -13.0
|
||||
offset_right = 85.0
|
||||
offset_bottom = 13.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_font_sizes/font_size = 10
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[connection signal="pressed" from="Panel/MenuPanel/Attack" to="." method="_on_attack_pressed"]
|
||||
[connection signal="pressed" from="Panel/MenuPanel/Tech" to="." method="_on_tech_pressed"]
|
||||
[connection signal="pressed" from="Panel/MenuPanel/Defend" to="." method="_on_defend_pressed"]
|
||||
[connection signal="pressed" from="Panel/MenuPanel/Item" to="." method="_on_item_pressed"]
|
||||
[connection signal="pressed" from="Panel/MenuPanel/Rest" to="." method="_on_item_pressed"]
|
||||
@ -1,25 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://l1bdgx07seai"]
|
||||
|
||||
[ext_resource type="Script" path="res://Systems/UI/Menu System/Scripts/menu_item.gd" id="1_paamu"]
|
||||
|
||||
[node name="MenuItem" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_paamu")
|
||||
|
||||
[node name="Button" type="Button" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -36.0
|
||||
offset_right = 36.0
|
||||
offset_bottom = 34.0
|
||||
grow_horizontal = 2
|
||||
text = "TEST"
|
||||
|
||||
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
|
||||
@ -1,7 +0,0 @@
|
||||
extends Sprite2D
|
||||
|
||||
@onready var Combantant = $Combatant
|
||||
@onready var Controller = $Combatant/PlayerCombatantController
|
||||
|
||||
func _ready():
|
||||
pass
|
||||
@ -1,14 +0,0 @@
|
||||
extends Action
|
||||
|
||||
var timer
|
||||
func execute():
|
||||
timer = Timer.new()
|
||||
timer.timeout.connect(done)
|
||||
timer.wait_time = 1
|
||||
add_child(timer)
|
||||
timer.start()
|
||||
print("Executing Spin Attack!")
|
||||
|
||||
func done():
|
||||
timer.queue_free()
|
||||
action_finished.emit()
|
||||
@ -1,6 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bmot4y61f1r8f"]
|
||||
|
||||
[ext_resource type="Script" path="res://Test Scenes/Test Player Actions/Scripts/spin_attack.gd" id="1_ywj48"]
|
||||
|
||||
[node name="spin_attack" type="Node"]
|
||||
script = ExtResource("1_ywj48")
|
||||
@ -1,42 +0,0 @@
|
||||
[gd_scene load_steps=8 format=3 uid="uid://b2iq5inxeoe82"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://dedauf4ntkthu" path="res://icon.svg" id="1_d15px"]
|
||||
[ext_resource type="Script" path="res://Test Scenes/Player.gd" id="2_8b3bs"]
|
||||
[ext_resource type="PackedScene" uid="uid://ch1sc85jxy1r7" path="res://Systems/Combat/Combatant.tscn" id="4_w3vb5"]
|
||||
[ext_resource type="PackedScene" uid="uid://bbbyup8pp6uam" path="res://Systems/Combat/Actions/Standard Actions/attack.tscn" id="5_17k7n"]
|
||||
[ext_resource type="PackedScene" uid="uid://b0swegor2jejg" path="res://Systems/Combat/player_combatant_controller.tscn" id="6_fabcu"]
|
||||
[ext_resource type="Script" path="res://Systems/Combat/Scripts/combat_stats.gd" id="7_ynhjd"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_28c5l"]
|
||||
script = ExtResource("7_ynhjd")
|
||||
MaxHP = 10
|
||||
MaxPhysicalStamina = 10
|
||||
MaxMentalStamina = 10
|
||||
Strength = 1
|
||||
Wisdom = 1
|
||||
Constitution = 1
|
||||
Willpower = 1
|
||||
Speed = 1
|
||||
Focus = 1
|
||||
Accuracy = 1
|
||||
Agility = 1
|
||||
|
||||
[node name="Player" type="Sprite2D"]
|
||||
position = Vector2(553, 219)
|
||||
texture = ExtResource("1_d15px")
|
||||
script = ExtResource("2_8b3bs")
|
||||
|
||||
[node name="Combatant" parent="." node_paths=PackedStringArray("Controller") instance=ExtResource("4_w3vb5")]
|
||||
Controller = NodePath("PlayerCombatantController")
|
||||
Stats = SubResource("Resource_28c5l")
|
||||
|
||||
[node name="Actions" type="Node" parent="Combatant"]
|
||||
|
||||
[node name="attack" parent="Combatant/Actions" instance=ExtResource("5_17k7n")]
|
||||
|
||||
[node name="PlayerCombatantController" parent="Combatant" instance=ExtResource("6_fabcu")]
|
||||
Name = "TEST_DUDE"
|
||||
TeamPosition = 1
|
||||
|
||||
[connection signal="atb_update" from="Combatant" to="Combatant/PlayerCombatantController" method="on_atb_update"]
|
||||
[connection signal="action_finished" from="Combatant/Actions/attack" to="." method="action_done"]
|
||||
@ -1,16 +0,0 @@
|
||||
extends Node2D
|
||||
|
||||
@onready var Combat = $Combatant
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
if Input.is_key_pressed(KEY_1):
|
||||
Combat.execute_action(0)
|
||||
|
||||
if Input.is_key_pressed(KEY_2):
|
||||
Combat.execute_action(1)
|
||||
@ -0,0 +1,3 @@
|
||||
|
||||
class_name EnemyCharacter
|
||||
extends Node2D
|
||||
@ -0,0 +1,4 @@
|
||||
|
||||
class_name Alex
|
||||
extends PlayerCharacter
|
||||
|
||||
@ -0,0 +1,139 @@
|
||||
[gd_scene load_steps=16 format=3 uid="uid://d1nq0efa53wra"]
|
||||
|
||||
[ext_resource type="Script" path="res://actors/player chars/player_character.gd" id="1_l60p5"]
|
||||
[ext_resource type="Texture2D" uid="uid://cs6uqgpyvwy7r" path="res://assets/art/character sprites/alex.png" id="2_2yoh5"]
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_u1hru"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(48, 144, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xioqy"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(48, 0, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_fdxoe"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(48, 48, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_mya52"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(0, 144, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_0mev0"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(48, 144, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_6b3k6"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(96, 144, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_gymxu"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(0, 0, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_fddh6"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(48, 0, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_p4xmj"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(96, 0, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_igt71"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(0, 48, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_bf443"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(48, 48, 48, 48)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ucyt6"]
|
||||
atlas = ExtResource("2_2yoh5")
|
||||
region = Rect2(96, 48, 48, 48)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_vu5b1"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_u1hru")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"Idle_North",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_xioqy")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"Idle_South",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_fdxoe")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"Idle_West",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_mya52")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_0mev0")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_6b3k6")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_0mev0")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"Walk_North",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_gymxu")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_fddh6")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_p4xmj")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_fddh6")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"Walk_South",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_igt71")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_bf443")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ucyt6")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_bf443")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"Walk_West",
|
||||
"speed": 5.0
|
||||
}]
|
||||
|
||||
[node name="Alex" type="Node2D" node_paths=PackedStringArray("sprite")]
|
||||
script = ExtResource("1_l60p5")
|
||||
char_name = "Alex"
|
||||
sprite = NodePath("AnimatedSprite2D")
|
||||
|
||||
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
|
||||
sprite_frames = SubResource("SpriteFrames_vu5b1")
|
||||
animation = &"Idle_West"
|
||||
@ -0,0 +1,99 @@
|
||||
|
||||
class_name PlayerCharacter
|
||||
extends Node2D
|
||||
|
||||
enum FacingDirection
|
||||
{
|
||||
NORTH,
|
||||
SOUTH,
|
||||
EAST,
|
||||
WEST
|
||||
}
|
||||
|
||||
@export var char_name: String = "Unnamed Player Character"
|
||||
@export var sprite: AnimatedSprite2D
|
||||
|
||||
var facing_direction = FacingDirection.NORTH
|
||||
|
||||
var _follow_target: PlayerCharacter = null
|
||||
var _is_moving = false
|
||||
var _was_moving = false
|
||||
var warned = false
|
||||
|
||||
func _ready():
|
||||
_validate_animations()
|
||||
|
||||
func _process(_delta):
|
||||
if _follow_target:
|
||||
# TODO: Implement the player char following system
|
||||
if !warned:
|
||||
push_warning("%s is set to follow %s, but following is not yet implemented!" % [char_name, _follow_target.char_name])
|
||||
warned = true
|
||||
else:
|
||||
_process_input()
|
||||
|
||||
func _validate_animations():
|
||||
var expected_animations = [
|
||||
"Idle_North",
|
||||
"Idle_South",
|
||||
"Idle_West",
|
||||
"Walk_North",
|
||||
"Walk_South",
|
||||
"Walk_West",
|
||||
]
|
||||
|
||||
for anim in expected_animations:
|
||||
if !sprite.sprite_frames.has_animation(anim):
|
||||
push_warning("Missing animation: %s, on player char: %s" %[anim, char_name])
|
||||
|
||||
func _process_input():
|
||||
if Input.is_action_just_pressed("Move_Down"):
|
||||
_is_moving = true
|
||||
_was_moving = true
|
||||
facing_direction = FacingDirection.SOUTH
|
||||
sprite.play("Walk_South")
|
||||
|
||||
if Input.is_action_just_pressed("Move_Up"):
|
||||
_is_moving = true
|
||||
_was_moving = true
|
||||
facing_direction = FacingDirection.NORTH
|
||||
sprite.play("Walk_North")
|
||||
|
||||
if Input.is_action_just_pressed("Move_Left"):
|
||||
_is_moving = true
|
||||
_was_moving = true
|
||||
facing_direction = FacingDirection.WEST
|
||||
sprite.play("Walk_West")
|
||||
sprite.flip_h = false
|
||||
|
||||
if Input.is_action_just_pressed("Move_Right"):
|
||||
_is_moving = true
|
||||
_was_moving = true
|
||||
facing_direction = FacingDirection.EAST
|
||||
sprite.play("Walk_West")
|
||||
sprite.flip_h = true
|
||||
|
||||
if Input.is_action_just_released("Move_Down") \
|
||||
|| Input.is_action_just_released("Move_Up") \
|
||||
|| Input.is_action_just_released("Move_Left") \
|
||||
|| Input.is_action_just_released("Move_Right"):
|
||||
_is_moving = false
|
||||
|
||||
|
||||
if !_is_moving && _was_moving:
|
||||
print("DIRECTION: %s" % facing_direction)
|
||||
_was_moving = false
|
||||
if facing_direction == FacingDirection.NORTH:
|
||||
sprite.play("Idle_North")
|
||||
|
||||
if facing_direction == FacingDirection.SOUTH:
|
||||
sprite.play("Idle_South")
|
||||
|
||||
if facing_direction == FacingDirection.WEST:
|
||||
sprite.play("Idle_West")
|
||||
sprite.flip_h = false
|
||||
|
||||
if facing_direction == FacingDirection.EAST:
|
||||
sprite.play("Idle_West")
|
||||
sprite.flip_h = true
|
||||
|
||||
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://uvm83t4gchb7"
|
||||
path="res://.godot/imported/Female1.png-751b04120ba1352265921310378ca8c2.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/art/character sprites/Szadi NPCs/Female1.png"
|
||||
dest_files=["res://.godot/imported/Female1.png-751b04120ba1352265921310378ca8c2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cgc15eklb3nu"
|
||||
path="res://.godot/imported/Female2.png-c21c085d5b87f05b39035afefe476932.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/art/character sprites/Szadi NPCs/Female2.png"
|
||||
dest_files=["res://.godot/imported/Female2.png-c21c085d5b87f05b39035afefe476932.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://4h8n71pv0rte"
|
||||
path="res://.godot/imported/Male1.png-7e24926694ba397cd822ce2fe47dd922.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/art/character sprites/Szadi NPCs/Male1.png"
|
||||
dest_files=["res://.godot/imported/Male1.png-7e24926694ba397cd822ce2fe47dd922.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://daq5hi7v0qbys"
|
||||
path="res://.godot/imported/Male2.png-383cd63349d8e1441ed489d992446ce6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/art/character sprites/Szadi NPCs/Male2.png"
|
||||
dest_files=["res://.godot/imported/Male2.png-383cd63349d8e1441ed489d992446ce6.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cj13x130gdhv3"
|
||||
path="res://.godot/imported/Male3.png-30f6f69b4fbf36e0cd2cc492c4dbe0f2.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/art/character sprites/Szadi NPCs/Male3.png"
|
||||
dest_files=["res://.godot/imported/Male3.png-30f6f69b4fbf36e0cd2cc492c4dbe0f2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://biv828180br3o"
|
||||
path="res://.godot/imported/Male4.png-4f84124cbebb5fd4c9ec637846a7c80c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/art/character sprites/Szadi NPCs/Male4.png"
|
||||
dest_files=["res://.godot/imported/Male4.png-4f84124cbebb5fd4c9ec637846a7c80c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cs6uqgpyvwy7r"
|
||||
path="res://.godot/imported/alex.png-d2fbd360031d0aeabb7ca94deee40098.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/art/character sprites/alex.png"
|
||||
dest_files=["res://.godot/imported/alex.png-d2fbd360031d0aeabb7ca94deee40098.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@ -0,0 +1 @@
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
The first four frames are idle, the next four walk.
|
||||
|
||||
Each block is in the size 32x48.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,14 @@
|
||||
>>> License for Everyone.
|
||||
|
||||
You can use the Licensed Asset to create Public domain and free to use, personal or commercial.
|
||||
|
||||
You can use the Licensed Asset:
|
||||
(a) edit and modify, cut and change the asset used for commercial purposes;
|
||||
(b) sell works created with the assets;
|
||||
(c) publish on websites related to graphics, games and similar.
|
||||
|
||||
>>> A Licence does not allow the Purchaser to:
|
||||
(d) Use the Licensed Asset or Derivative Works in a logo, trademark or service mark
|
||||
(e) Resell it, original or modified; Credit is not required but appreciated.
|
||||
|
||||
Credit is not required but appreciated.
|
||||
@ -0,0 +1,23 @@
|
||||
# @tool
|
||||
# class_name (PascalCase)
|
||||
# extends
|
||||
# # docstring
|
||||
#
|
||||
# signals (snake_case)
|
||||
# enums (PascalCase, members are CONSTANT_CASE)
|
||||
# constants (CONSTANT_CASE)
|
||||
# @export variables (snake_case)
|
||||
# public variables (non-underscore-prefixed snake_case)
|
||||
# private variables (underscore-prefixed _snake_case)
|
||||
# @onready variables (snake_case)
|
||||
#
|
||||
# optional built-in virtual _init method
|
||||
# optional built-in virtual _enter_tree() method
|
||||
# built-in virtual _ready method
|
||||
# remaining built-in virtual methods (underscore-prefixed _snake_case)
|
||||
# public methods (non-underscore-prefixed snake_case)
|
||||
# private methods (underscore-prefixed _snake_case)
|
||||
# subclasses (PascalCase)
|
||||
|
||||
|
||||
var stop_empty_file_warning = 0
|
||||
@ -0,0 +1,3 @@
|
||||
|
||||
class_name CombatAction
|
||||
extends Resource
|
||||
@ -0,0 +1,20 @@
|
||||
|
||||
class_name CombatState
|
||||
extends GameState
|
||||
|
||||
## The combat state controls/manages combat
|
||||
|
||||
var teams: Array[CombatTeam] = []
|
||||
|
||||
|
||||
func state_enter(_params: Dictionary):
|
||||
pass
|
||||
|
||||
func state_exit():
|
||||
pass
|
||||
|
||||
func state_process(delta):
|
||||
for team in teams:
|
||||
team.tick_atb(delta)
|
||||
team.process_ready_actions()
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
|
||||
class_name CombatStats
|
||||
extends Resource
|
||||
## Stats that every combatant must have
|
||||
##
|
||||
## These stats don't change during combat but
|
||||
## status effects may override or offset them.
|
||||
|
||||
# Health
|
||||
@export var max_hp = 10
|
||||
|
||||
# Needed to use physical techniques
|
||||
@export var max_physical_stamina = 10
|
||||
|
||||
# Needed to use magic
|
||||
@export var max_mental_stamina = 10
|
||||
|
||||
# Physical Attack Power
|
||||
@export var strength = 1
|
||||
|
||||
# Magic Offense
|
||||
@export var wisdom = 1
|
||||
|
||||
# Physical Defense
|
||||
@export var constitution = 1
|
||||
|
||||
# Magic Defense
|
||||
@export var willpower = 1
|
||||
|
||||
# Battle turn order or ATB time
|
||||
@export var speed = 1
|
||||
|
||||
# Critical hit chance
|
||||
@export var focus = 1
|
||||
|
||||
# Chance to hit
|
||||
@export var accuracy = 1
|
||||
|
||||
# Chance to dodge
|
||||
@export var aabbgility = 1
|
||||
@ -0,0 +1,25 @@
|
||||
|
||||
class_name CombatTeam
|
||||
extends Node
|
||||
## Manages a team of combatants
|
||||
##
|
||||
##
|
||||
|
||||
var team: Array[Combatant] = []
|
||||
|
||||
|
||||
func is_defeated():
|
||||
for combatant in team:
|
||||
if !combatant.is_defeated():
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
func tick_atb(delta):
|
||||
for combatant in team:
|
||||
combatant.tick_atb(delta)
|
||||
|
||||
func process_ready_actions():
|
||||
# TODO: Implement process_ready_actions()
|
||||
pass
|
||||
@ -0,0 +1,39 @@
|
||||
|
||||
class_name Combatant
|
||||
extends Node
|
||||
|
||||
## This class/component represents anything that can particpate in combat
|
||||
##
|
||||
## This class is responsible for things like combat animations,
|
||||
## tracking combat stats, executing combat actions, etc.
|
||||
## Anything that can take a turn in combat needs to use this component:
|
||||
## Player characters, enemys, allies, neutral units, etc.
|
||||
|
||||
@export var combat_stats: CombatStats
|
||||
@export var actions: Array[CombatAction] = []
|
||||
|
||||
# current state
|
||||
var hp: int = 0 # Health Points
|
||||
var ps: int = 0 # Physical Stamina
|
||||
var ms: int = 0 # Mental Stamina
|
||||
var atb: float = 0 # ATB Timer - counts down, turn is ready at 0
|
||||
|
||||
func is_defeated():
|
||||
|
||||
# TODO: add checks for status conditions
|
||||
# that cause this combantant to be
|
||||
# considered defeated (like stone)
|
||||
return hp <= 0
|
||||
|
||||
func is_turn_ready():
|
||||
return atb <= 0
|
||||
|
||||
func tick_atb(delta):
|
||||
if atb <= 0:
|
||||
return
|
||||
|
||||
atb -= delta
|
||||
|
||||
# Override these methods in child classes
|
||||
func take_damage(source: DamageSource):
|
||||
hp -= source.amount
|
||||
@ -0,0 +1,27 @@
|
||||
|
||||
class_name DamageSource
|
||||
extends Resource
|
||||
|
||||
|
||||
enum Type
|
||||
{
|
||||
BLUNT,
|
||||
CUTTING,
|
||||
PIERCING,
|
||||
MAGIC,
|
||||
}
|
||||
|
||||
enum Element
|
||||
{
|
||||
PHYSICAL,
|
||||
LIGHTNING,
|
||||
FIRE,
|
||||
WATER,
|
||||
BIO,
|
||||
}
|
||||
|
||||
|
||||
var attacker: Combatant = null
|
||||
var amount: int = 0
|
||||
var type: Type = Type.BLUNT
|
||||
var element: Element = Element.PHYSICAL
|
||||
@ -0,0 +1,30 @@
|
||||
|
||||
class_name GameState
|
||||
extends Node
|
||||
### The base game state.
|
||||
|
||||
# signals (snake_case)
|
||||
# enums (PascalCase, members are CONSTANT_CASE)
|
||||
# constants (CONSTANT_CASE)
|
||||
# @export variables (snake_case)
|
||||
# public variables (non-underscore-prefixed snake_case)
|
||||
# private variables (underscore-prefixed _snake_case)
|
||||
# @onready variables (snake_case)
|
||||
#
|
||||
# optional built-in virtual _init method
|
||||
# optional built-in virtual _enter_tree() method
|
||||
# built-in virtual _ready method
|
||||
# remaining built-in virtual methods (underscore-prefixed _snake_case)
|
||||
# public methods (non-underscore-prefixed snake_case)
|
||||
func state_enter(_params: Dictionary):
|
||||
push_warning("Base GameState state_enter method called")
|
||||
|
||||
func state_exit():
|
||||
push_warning("Base GameState state_exit method called")
|
||||
|
||||
func state_process(_delta):
|
||||
push_warning("Base GameState state_process method called")
|
||||
|
||||
|
||||
# private methods (underscore-prefixed _snake_case)
|
||||
# subclasses (PascalCase)
|
||||
@ -0,0 +1,20 @@
|
||||
|
||||
extends Node2D
|
||||
|
||||
|
||||
@export var player_team: Array[PlayerCharacter] = []
|
||||
@export var enemy_team: Array[EnemyCharacter] = []
|
||||
|
||||
@onready var game_state: GameState = $CombatState
|
||||
|
||||
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
game_state.state_enter({})
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
game_state.state_process(delta)
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue