Compare commits

..

No commits in common. '6ecbd2e5a2c084d6905cd7245f69b3a868221ee7' and 'eb7cbf97d9b03be16a348755cc429c6015b2d73f' have entirely different histories.

4
.gitignore vendored

@ -1,6 +1,2 @@
# Godot 4+ specific ignores
.godot/
assets/binary files/elements_core_pack_2.14.24/
*.zip

@ -0,0 +1,21 @@
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()

@ -0,0 +1,18 @@
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")

@ -0,0 +1,6 @@
[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")

@ -0,0 +1,6 @@
[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")

@ -0,0 +1,6 @@
[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")

@ -0,0 +1,47 @@
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

@ -0,0 +1,51 @@
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 = ""

@ -0,0 +1,38 @@
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

@ -0,0 +1,6 @@
extends Node
class_name CombatantController
func init_combat(stats):
push_warning("Base init_combat method called")

@ -0,0 +1,6 @@
[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")

@ -0,0 +1,12 @@
[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")]

@ -0,0 +1,43 @@
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

@ -0,0 +1,17 @@
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)

@ -0,0 +1,217 @@
[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"]

@ -0,0 +1,25 @@
[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"]

@ -0,0 +1,7 @@
extends Sprite2D
@onready var Combantant = $Combatant
@onready var Controller = $Combatant/PlayerCombatantController
func _ready():
pass

@ -0,0 +1,14 @@
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()

@ -0,0 +1,6 @@
[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")

@ -0,0 +1,42 @@
[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"]

File diff suppressed because one or more lines are too long

@ -0,0 +1,16 @@
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)

@ -1,3 +0,0 @@
class_name EnemyCharacter
extends Node2D

@ -1,4 +0,0 @@
class_name Alex
extends PlayerCharacter

@ -1,139 +0,0 @@
[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"

@ -1,99 +0,0 @@
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.

@ -1,34 +0,0 @@
[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.

@ -1,34 +0,0 @@
[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.

@ -1,34 +0,0 @@
[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.

@ -1,34 +0,0 @@
[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.

@ -1,34 +0,0 @@
[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.

@ -1,34 +0,0 @@
[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

BIN
assets/art/character sprites/alex.png (Stored with Git LFS)

Binary file not shown.

@ -1,34 +0,0 @@
[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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,3 +0,0 @@
The first four frames are idle, the next four walk.
Each block is in the size 32x48.

@ -1,14 +0,0 @@
>>> 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.

@ -1,23 +0,0 @@
# @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

@ -11,7 +11,7 @@ config_version=5
[application]
config/name="RPG Prototype"
run/main_scene="res://testing/sandbox.tscn"
run/main_scene="res://Test Scenes/sandbox.tscn"
config/features=PackedStringArray("4.2", "Forward Plus")
config/icon="res://icon.svg"
@ -23,31 +23,5 @@ window/size/viewport_height=720
[file_customization]
folder_colors={
"res://actors/": "blue",
"res://assets/": "orange",
"res://systems/": "teal",
"res://testing/": "gray"
}
[input]
Move_Left={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null)
]
}
Move_Right={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null)
]
}
Move_Up={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null)
]
}
Move_Down={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null)
]
"res://Systems/Combat/": "teal"
}

@ -1,3 +0,0 @@
class_name CombatAction
extends Resource

@ -1,20 +0,0 @@
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()

@ -1,40 +0,0 @@
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

@ -1,25 +0,0 @@
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

@ -1,39 +0,0 @@
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

@ -1,27 +0,0 @@
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

@ -1,30 +0,0 @@
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)

@ -1,20 +0,0 @@
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)
Loading…
Cancel
Save