From f1bf455da4ccb7f2659c82fbb574ad9aa3fd0743 Mon Sep 17 00:00:00 2001 From: kedrickfudala Date: Mon, 16 Sep 2024 22:12:50 -0400 Subject: [PATCH 01/10] First Commit/Setup --- .gitattributes | 2 + .gitignore | 61 +------------------------------ icon.svg | 1 + icon.svg.import | 37 +++++++++++++++++++ project.godot | 26 +++++++++++++ source/game_container.gd | 9 +++++ source/game_container.tscn | 6 +++ source/stages/stage_template.tscn | 6 +++ source/stages/world.tscn | 3 ++ 9 files changed, 92 insertions(+), 59 deletions(-) create mode 100644 .gitattributes create mode 100644 icon.svg create mode 100644 icon.svg.import create mode 100644 project.godot create mode 100644 source/game_container.gd create mode 100644 source/game_container.tscn create mode 100644 source/stages/stage_template.tscn create mode 100644 source/stages/world.tscn diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..8ad74f78 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore index 0a046de1..47091836 100644 --- a/.gitignore +++ b/.gitignore @@ -1,59 +1,2 @@ -# This .gitignore file should be placed at the root of your Unity project directory -# -# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore -# -/[Ll]ibrary/ -/[Tt]emp/ -/[Oo]bj/ -/[Bb]uild/ -/[Bb]uilds/ -/[Ll]ogs/ -/[Mm]emoryCaptures/ - -# Never ignore Asset meta data -!/[Aa]ssets/**/*.meta - -# Uncomment this line if you wish to ignore the asset store tools plugin -# /[Aa]ssets/AssetStoreTools* - -# Autogenerated Jetbrains Rider plugin -[Aa]ssets/Plugins/Editor/JetBrains* - -# Visual Studio cache directory -.vs/ - -# Gradle cache directory -.gradle/ - -# Autogenerated VS/MD/Consulo solution and project files -ExportedObj/ -.consulo/ -*.csproj -*.unityproj -*.sln -*.suo -*.tmp -*.user -*.userprefs -*.pidb -*.booproj -*.svd -*.pdb -*.mdb -*.opendb -*.VC.db - -# Unity3D generated meta files -*.pidb.meta -*.pdb.meta -*.mdb.meta - -# Unity3D generated file on crash reports -sysinfo.txt - -# Builds -*.apk -*.unitypackage - -# Crashlytics generated file -crashlytics-build.properties +# Godot 4+ specific ignores +.godot/ diff --git a/icon.svg b/icon.svg new file mode 100644 index 00000000..3fe4f4ae --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 00000000..1f65b4f1 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dekh4a6t8uq3j" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 00000000..6e67c486 --- /dev/null +++ b/project.godot @@ -0,0 +1,26 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Hallow's Thief" +run/main_scene="res://source/game_container.tscn" +config/features=PackedStringArray("4.2", "GL Compatibility") +config/icon="res://icon.svg" + +[layer_names] + +2d_physics/layer_1="Walls" +2d_physics/layer_2="Player" + +[rendering] + +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" diff --git a/source/game_container.gd b/source/game_container.gd new file mode 100644 index 00000000..23d41218 --- /dev/null +++ b/source/game_container.gd @@ -0,0 +1,9 @@ +extends Node2D +class_name GameContainer + +@onready var WorldScene : PackedScene = preload("res://source/stages/world.tscn") + +func _ready(): + RenderingServer.set_default_clear_color(Color("000000")) + pass + diff --git a/source/game_container.tscn b/source/game_container.tscn new file mode 100644 index 00000000..bfba7d10 --- /dev/null +++ b/source/game_container.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://cpeool1ufkioa"] + +[ext_resource type="Script" path="res://source/game_container.gd" id="1_13cro"] + +[node name="GameContainer" type="Node2D"] +script = ExtResource("1_13cro") diff --git a/source/stages/stage_template.tscn b/source/stages/stage_template.tscn new file mode 100644 index 00000000..a7bbdc54 --- /dev/null +++ b/source/stages/stage_template.tscn @@ -0,0 +1,6 @@ +[gd_scene format=3 uid="uid://dfbde6txjyuca"] + +[node name="StageTemplate" type="Node2D"] + +[node name="TileMap" type="TileMap" parent="."] +format = 2 diff --git a/source/stages/world.tscn b/source/stages/world.tscn new file mode 100644 index 00000000..af085532 --- /dev/null +++ b/source/stages/world.tscn @@ -0,0 +1,3 @@ +[gd_scene format=3 uid="uid://bq7lbiloaxa0a"] + +[node name="World" type="Node2D"] From 001c900cbf430a037667abfaa4e742769db2fc4e Mon Sep 17 00:00:00 2001 From: Luke Webb Date: Sat, 21 Sep 2024 14:18:20 -0400 Subject: [PATCH 02/10] working demo --- scenes/player.tscn | 44 ++++++++++++++++++++++++++++++++++++++++++++ scripts/item.gd | 21 +++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 scenes/player.tscn create mode 100644 scripts/item.gd diff --git a/scenes/player.tscn b/scenes/player.tscn new file mode 100644 index 00000000..e6805ef7 --- /dev/null +++ b/scenes/player.tscn @@ -0,0 +1,44 @@ +[gd_scene load_steps=4 format=3 uid="uid://cll66afrhe8br"] + +[sub_resource type="GDScript" id="GDScript_rptgx"] +script/source = "extends CharacterBody2D + + +const SPEED = 300.0 +const JUMP_VELOCITY = -400.0 + + +func _physics_process(delta: float) -> void: + # Add the gravity. + if not is_on_floor(): + velocity += get_gravity() * delta + + # Handle jump. + if Input.is_action_just_pressed(\"ui_accept\") and is_on_floor(): + velocity.y = JUMP_VELOCITY + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var direction := Input.get_axis(\"ui_left\", \"ui_right\") + if direction: + velocity.x = direction * SPEED + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + + move_and_slide() +" + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_1syju"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_wuljl"] + +[node name="Player" type="CharacterBody2D"] +script = SubResource("GDScript_rptgx") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CapsuleShape2D_1syju") + +[node name="MeshInstance2D" type="MeshInstance2D" parent="."] +position = Vector2(1.07288e-06, -0.5) +scale = Vector2(20, 14.5) +mesh = SubResource("CapsuleMesh_wuljl") diff --git a/scripts/item.gd b/scripts/item.gd new file mode 100644 index 00000000..dee4f192 --- /dev/null +++ b/scripts/item.gd @@ -0,0 +1,21 @@ +extends Resource +class_name Item + + +@export var sprite : Texture +@export var name : String + +#base good guy stat boosts/characteristics (passive items + weapons) +@export var health : float +@export var mana : float +@export var speed : float +@export var cooldown : float +@export var value : int +#@export var type : Global.itemType + + + +#weapon stats (weapons only) +@export var damage : float +@export var attackSpeed : float +@export var manaCost : float From 2d33fa2c24c14fd72ef68e151712c2ce2f2610b9 Mon Sep 17 00:00:00 2001 From: kedrickfudala Date: Tue, 24 Sep 2024 22:28:41 -0400 Subject: [PATCH 03/10] Fixed deprecated tilemap --- project.godot | 2 +- source/game_container.gd | 1 - source/stages/stage_template.tscn | 3 +-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/project.godot b/project.godot index 6e67c486..708ea43a 100644 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ config_version=5 config/name="Hallow's Thief" run/main_scene="res://source/game_container.tscn" -config/features=PackedStringArray("4.2", "GL Compatibility") +config/features=PackedStringArray("4.3", "GL Compatibility") config/icon="res://icon.svg" [layer_names] diff --git a/source/game_container.gd b/source/game_container.gd index 23d41218..2abdbea3 100644 --- a/source/game_container.gd +++ b/source/game_container.gd @@ -6,4 +6,3 @@ class_name GameContainer func _ready(): RenderingServer.set_default_clear_color(Color("000000")) pass - diff --git a/source/stages/stage_template.tscn b/source/stages/stage_template.tscn index a7bbdc54..b04eae6a 100644 --- a/source/stages/stage_template.tscn +++ b/source/stages/stage_template.tscn @@ -2,5 +2,4 @@ [node name="StageTemplate" type="Node2D"] -[node name="TileMap" type="TileMap" parent="."] -format = 2 +[node name="TileMapLayer" type="TileMapLayer" parent="."] From 79dd52b57b059e4721733b334072d1982fdb367d Mon Sep 17 00:00:00 2001 From: Luke Webb Date: Thu, 26 Sep 2024 20:04:37 -0400 Subject: [PATCH 04/10] basic player controller, blank demo room added --- project.godot | 25 ++++++++++++++++++++- source/scenes/demo_room.tscn | 9 ++++++++ source/scenes/player.tscn | 18 ++++++++++++++++ source/scripts/player.gd | 42 ++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 source/scenes/demo_room.tscn create mode 100644 source/scenes/player.tscn create mode 100644 source/scripts/player.gd diff --git a/project.godot b/project.godot index 708ea43a..6569ac3f 100644 --- a/project.godot +++ b/project.godot @@ -11,10 +11,33 @@ config_version=5 [application] config/name="Hallow's Thief" -run/main_scene="res://source/game_container.tscn" +run/main_scene="res://source/scenes/demo_room.tscn" config/features=PackedStringArray("4.3", "GL Compatibility") config/icon="res://icon.svg" +[input] + +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,"location":0,"echo":false,"script":null) +] +} +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,"location":0,"echo":false,"script":null) +] +} +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,"location":0,"echo":false,"script":null) +] +} +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,"location":0,"echo":false,"script":null) +] +} + [layer_names] 2d_physics/layer_1="Walls" diff --git a/source/scenes/demo_room.tscn b/source/scenes/demo_room.tscn new file mode 100644 index 00000000..33ba6c57 --- /dev/null +++ b/source/scenes/demo_room.tscn @@ -0,0 +1,9 @@ +[gd_scene load_steps=2 format=3 uid="uid://diprigu67ubnb"] + +[ext_resource type="PackedScene" uid="uid://rgfnpcsvv534" path="res://source/scenes/player.tscn" id="1_uxgo6"] + +[node name="DemoRoom" type="Node2D"] + +[node name="Player" parent="." instance=ExtResource("1_uxgo6")] + +[node name="Camera2D" type="Camera2D" parent="."] diff --git a/source/scenes/player.tscn b/source/scenes/player.tscn new file mode 100644 index 00000000..ec67b5cf --- /dev/null +++ b/source/scenes/player.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=4 format=3 uid="uid://rgfnpcsvv534"] + +[ext_resource type="Script" path="res://source/scripts/player.gd" id="1_ws1a7"] + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_1d7hi"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_tx0kn"] + +[node name="Player" type="CharacterBody2D"] +script = ExtResource("1_ws1a7") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CapsuleShape2D_1d7hi") + +[node name="MeshInstance2D" type="MeshInstance2D" parent="."] +position = Vector2(1.07288e-06, 1.90735e-06) +scale = Vector2(20, 15) +mesh = SubResource("CapsuleMesh_tx0kn") diff --git a/source/scripts/player.gd b/source/scripts/player.gd new file mode 100644 index 00000000..c106dd2c --- /dev/null +++ b/source/scripts/player.gd @@ -0,0 +1,42 @@ +extends CharacterBody2D + +var Speed := 0.0 +var topSpeed := 150.0 +var hDirection := 0.0 +var vDirection := 0.0 + +const SPEED_INC := 15.0 + + + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta) -> void: + handle_move(delta) + + + +func handle_move(delta) -> void: + hDirection = Input.get_axis("Left", "Right") + vDirection = Input.get_axis("Up", "Down") + if hDirection and vDirection: + Speed = move_toward(Speed, topSpeed, SPEED_INC) #slowed velocity's to account for increased movement + velocity.x = hDirection * Speed / 1.4 + velocity.y = vDirection * Speed / 1.4 + elif hDirection: + Speed = move_toward(Speed, topSpeed, SPEED_INC) + velocity.x = hDirection * Speed + velocity.y = move_toward(velocity.y, 0, SPEED_INC) + elif vDirection: + Speed = move_toward(Speed, topSpeed, SPEED_INC) + velocity.y = vDirection * Speed + velocity.x = move_toward(velocity.x, 0, SPEED_INC) + else: + velocity.x = move_toward(velocity.x, 0, SPEED_INC) + velocity.y = move_toward(velocity.y, 0, SPEED_INC) + move_and_slide() From 55ea080414995093544d18b4264a0f269beba8fc Mon Sep 17 00:00:00 2001 From: JoeyGiordano Date: Sat, 28 Sep 2024 11:06:50 -0400 Subject: [PATCH 05/10] Project Settings Added arrow key to movement binds Changed default window settings --- project.godot | 19 ++++++++++++++----- source/scenes/demo_room.tscn | 5 +++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/project.godot b/project.godot index 6569ac3f..ae6e7f66 100644 --- a/project.godot +++ b/project.godot @@ -12,29 +12,38 @@ config_version=5 config/name="Hallow's Thief" run/main_scene="res://source/scenes/demo_room.tscn" -config/features=PackedStringArray("4.3", "GL Compatibility") +config/features=PackedStringArray("4.2", "GL Compatibility") config/icon="res://icon.svg" +[display] + +window/size/mode=2 +window/stretch/mode="canvas_items" + [input] 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,"location":0,"echo":false,"script":null) +"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) +, 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":4194319,"key_label":0,"unicode":0,"echo":false,"script":null) ] } 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,"location":0,"echo":false,"script":null) +"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) +, 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":4194321,"key_label":0,"unicode":0,"echo":false,"script":null) ] } 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,"location":0,"echo":false,"script":null) +"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) +, 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":4194320,"key_label":0,"unicode":0,"echo":false,"script":null) ] } 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,"location":0,"echo":false,"script":null) +"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) +, 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":4194322,"key_label":0,"unicode":0,"echo":false,"script":null) ] } diff --git a/source/scenes/demo_room.tscn b/source/scenes/demo_room.tscn index 33ba6c57..87dbbc09 100644 --- a/source/scenes/demo_room.tscn +++ b/source/scenes/demo_room.tscn @@ -7,3 +7,8 @@ [node name="Player" parent="." instance=ExtResource("1_uxgo6")] [node name="Camera2D" type="Camera2D" parent="."] + +[node name="ColorRect" type="ColorRect" parent="."] +offset_right = 40.0 +offset_bottom = 40.0 +color = Color(1, 0, 1, 1) From 3b58b10eca8f1c2af74e024c50aec40dd4b5afce Mon Sep 17 00:00:00 2001 From: JoeyGiordano Date: Sat, 28 Sep 2024 13:55:54 -0400 Subject: [PATCH 06/10] Item Functionality First Try --- source/item/Stats.gd | 30 ++++++++++++++++++++++++ source/item/base_player_stats.tres | 12 ++++++++++ source/item/item_resource.gd | 28 ++++++++++++++++++++++ source/item/items/item1.tres | 6 +++++ source/item/items/item2.tres | 12 ++++++++++ source/scenes/item_handler.gd | 37 ++++++++++++++++++++++++++++++ source/scenes/player.tscn | 8 ++++++- 7 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 source/item/Stats.gd create mode 100644 source/item/base_player_stats.tres create mode 100644 source/item/item_resource.gd create mode 100644 source/item/items/item1.tres create mode 100644 source/item/items/item2.tres create mode 100644 source/scenes/item_handler.gd diff --git a/source/item/Stats.gd b/source/item/Stats.gd new file mode 100644 index 00000000..c1a332e8 --- /dev/null +++ b/source/item/Stats.gd @@ -0,0 +1,30 @@ +class_name Stats + +var damage : float = 0 +var dmg_mult : float = 0 +var max_health : float = 0 +var strength : float = 0 +var speed : float = 0 + +func add_stats(s : Stats) : + damage += s.damage + dmg_mult += s.dmg_mult + max_health += s.max_health + strength += s.strength + speed += s.speed + +func subtract_stats(s : Stats) : + damage -= s.damage + dmg_mult -= s.dmg_mult + max_health -= s.max_health + strength -= s.strength + speed -= s.speed + +func copy() -> Stats : + var s = Stats.new() + s.damage = damage + s.dmg_mult = dmg_mult + s.max_health = max_health + s.strength = strength + s.speed = speed + return s \ No newline at end of file diff --git a/source/item/base_player_stats.tres b/source/item/base_player_stats.tres new file mode 100644 index 00000000..9d1abe40 --- /dev/null +++ b/source/item/base_player_stats.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://1qjff6n2w5m"] + +[ext_resource type="Script" path="res://source/item/item_resource.gd" id="1_3dkj6"] + +[resource] +script = ExtResource("1_3dkj6") +damage = 5.0 +dmg_mult = 1.0 +max_health = 100.0 +strength = 2.0 +speed = 4.0 +func_name = "" diff --git a/source/item/item_resource.gd b/source/item/item_resource.gd new file mode 100644 index 00000000..7986ed21 --- /dev/null +++ b/source/item/item_resource.gd @@ -0,0 +1,28 @@ +extends Resource + +@export var damage : float = 0 +@export var dmg_mult : float = 0 +@export var max_health : float = 0 +@export var strength : float = 0 +@export var speed : float = 0 +@export var func_name : String = "" + + +func get_stats() -> Stats : + var s = Stats.new() + s.damage = damage + s.dmg_mult = dmg_mult + s.max_health = max_health + s.strength = strength + s.speed = speed + return s + +#################################################################### +###### ITEM FUNCTIONS ######################################## + +static func do_nothing(item_handler : Node) : + print(item_handler.player_stats.damage) + item_handler.player_stats.damage += 2 + print(item_handler.player_stats.damage) + print("nothing") + pass \ No newline at end of file diff --git a/source/item/items/item1.tres b/source/item/items/item1.tres new file mode 100644 index 00000000..9a42d51b --- /dev/null +++ b/source/item/items/item1.tres @@ -0,0 +1,6 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://hxw1lhveewdh"] + +[ext_resource type="Script" path="res://source/item/item_resource.gd" id="1_u47e6"] + +[resource] +script = ExtResource("1_u47e6") diff --git a/source/item/items/item2.tres b/source/item/items/item2.tres new file mode 100644 index 00000000..3c37f9d3 --- /dev/null +++ b/source/item/items/item2.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://wracq7cgo1wj"] + +[ext_resource type="Script" path="res://source/item/item_resource.gd" id="1_hqexa"] + +[resource] +script = ExtResource("1_hqexa") +damage = 0.0 +dmg_mult = 0.0 +max_health = 0.0 +strength = 0.0 +speed = 0.0 +func_name = "" diff --git a/source/scenes/item_handler.gd b/source/scenes/item_handler.gd new file mode 100644 index 00000000..f01a58eb --- /dev/null +++ b/source/scenes/item_handler.gd @@ -0,0 +1,37 @@ +extends Node2D + +var items : Array[Resource] + +@export var base_stats : Resource #base stats +var stats_with_items : Stats = Stats.new() #base stats + stats from items (updated when a new item is picked up) +var player_stats : Stats = Stats.new() #base stats + stats from items + conditional effects from items (updated every frame) + + +func _process(delta): + handle_process_effects() + pass + +func handle_process_effects() : + player_stats = stats_with_items.copy() + for item in items : + call(item.func_name, self) + pass + +func handle_pickup(item : Resource) : + #add the item list of player items + items.append(item) + + #change the player stats (eg if the item has damage +2, the player stats_with_items damage will increase by 2) + stats_with_items.add_stats(item.get_stats()) + + #here we could also add something for a special on pickup function for each item + +func handle_drop(item : Resource) : + #remove the item from the list of player items + items.remove_at(items.find(item)) + + #change the player stats (eg if the item has damage +2, the player stats_with_items damage will decrease by 2) + stats_with_items.subtract_stats(item.get_stats()) + + #here we could also add something for a special on drop function for each item + diff --git a/source/scenes/player.tscn b/source/scenes/player.tscn index ec67b5cf..9d1c949c 100644 --- a/source/scenes/player.tscn +++ b/source/scenes/player.tscn @@ -1,6 +1,8 @@ -[gd_scene load_steps=4 format=3 uid="uid://rgfnpcsvv534"] +[gd_scene load_steps=6 format=3 uid="uid://rgfnpcsvv534"] [ext_resource type="Script" path="res://source/scripts/player.gd" id="1_ws1a7"] +[ext_resource type="Script" path="res://source/scenes/item_handler.gd" id="2_cjdm3"] +[ext_resource type="Resource" uid="uid://1qjff6n2w5m" path="res://source/item/base_player_stats.tres" id="3_0avcd"] [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_1d7hi"] @@ -16,3 +18,7 @@ shape = SubResource("CapsuleShape2D_1d7hi") position = Vector2(1.07288e-06, 1.90735e-06) scale = Vector2(20, 15) mesh = SubResource("CapsuleMesh_tx0kn") + +[node name="ItemHandler" type="Node2D" parent="."] +script = ExtResource("2_cjdm3") +base_stats = ExtResource("3_0avcd") From 9d8f0f4521e653654f38469e5f8e7314d694ed9e Mon Sep 17 00:00:00 2001 From: JoeyGiordano Date: Sat, 28 Sep 2024 16:38:44 -0400 Subject: [PATCH 07/10] Item and Stats Functionality Tested; not thoroughly tested. Added what we were talking about in the meeting today. Left a few things in there that are for testing. Left a ton of comments. I tried to keep it as consolidated and simple as possible --- source/item/Stats.gd | 8 ++-- source/item/base_player_stats.tres | 4 +- source/item/item.gd | 8 ++++ source/item/item_resource.gd | 25 ++++++---- source/item/items/item1.tres | 6 --- source/item/items/item2.tres | 12 ----- source/item/stats_and_item_handler.gd | 42 ++++++++++++++++ source/scenes/demo_room.tscn | 6 ++- source/scenes/item_handler.gd | 37 -------------- source/scenes/player.tscn | 35 +++++++++++--- source/scripts/player.gd | 69 +++++++++++++++------------ source/scripts/quit.gd | 5 ++ 12 files changed, 150 insertions(+), 107 deletions(-) create mode 100644 source/item/item.gd delete mode 100644 source/item/items/item1.tres delete mode 100644 source/item/items/item2.tres create mode 100644 source/item/stats_and_item_handler.gd delete mode 100644 source/scenes/item_handler.gd create mode 100644 source/scripts/quit.gd diff --git a/source/item/Stats.gd b/source/item/Stats.gd index c1a332e8..d16ab9a4 100644 --- a/source/item/Stats.gd +++ b/source/item/Stats.gd @@ -4,21 +4,21 @@ var damage : float = 0 var dmg_mult : float = 0 var max_health : float = 0 var strength : float = 0 -var speed : float = 0 +var top_speed : float = 0 func add_stats(s : Stats) : damage += s.damage dmg_mult += s.dmg_mult max_health += s.max_health strength += s.strength - speed += s.speed + top_speed += s.top_speed func subtract_stats(s : Stats) : damage -= s.damage dmg_mult -= s.dmg_mult max_health -= s.max_health strength -= s.strength - speed -= s.speed + top_speed -= s.top_speed func copy() -> Stats : var s = Stats.new() @@ -26,5 +26,5 @@ func copy() -> Stats : s.dmg_mult = dmg_mult s.max_health = max_health s.strength = strength - s.speed = speed + s.top_speed = top_speed return s \ No newline at end of file diff --git a/source/item/base_player_stats.tres b/source/item/base_player_stats.tres index 9d1abe40..a41d113a 100644 --- a/source/item/base_player_stats.tres +++ b/source/item/base_player_stats.tres @@ -1,4 +1,4 @@ -[gd_resource type="Resource" load_steps=2 format=3 uid="uid://1qjff6n2w5m"] +[gd_resource type="Resource" script_class="Item_Res" load_steps=2 format=3 uid="uid://1qjff6n2w5m"] [ext_resource type="Script" path="res://source/item/item_resource.gd" id="1_3dkj6"] @@ -8,5 +8,5 @@ damage = 5.0 dmg_mult = 1.0 max_health = 100.0 strength = 2.0 -speed = 4.0 +top_speed = 0.0 func_name = "" diff --git a/source/item/item.gd b/source/item/item.gd new file mode 100644 index 00000000..c8c5387b --- /dev/null +++ b/source/item/item.gd @@ -0,0 +1,8 @@ +extends Node2D + +class_name Item + +@export var item_res : Item_Res + +func get_stats() -> Stats : + return item_res.get_stats() \ No newline at end of file diff --git a/source/item/item_resource.gd b/source/item/item_resource.gd index 7986ed21..0c2807ca 100644 --- a/source/item/item_resource.gd +++ b/source/item/item_resource.gd @@ -1,12 +1,15 @@ extends Resource +class_name Item_Res + @export var damage : float = 0 @export var dmg_mult : float = 0 @export var max_health : float = 0 @export var strength : float = 0 -@export var speed : float = 0 +@export var top_speed : float = 0 @export var func_name : String = "" +#note that when adding a stat, a few lines need to be added in stats.gd and in get_stats() in this class func get_stats() -> Stats : var s = Stats.new() @@ -14,15 +17,21 @@ func get_stats() -> Stats : s.dmg_mult = dmg_mult s.max_health = max_health s.strength = strength - s.speed = speed + s.top_speed = top_speed return s #################################################################### -###### ITEM FUNCTIONS ######################################## +###### ITEM SPECIFIC FUNCTIONS ######################################## + +#EXAMPLE +""" +static func amulet_of_fear(player : Player) : + if (player.is_scared) : + player.stats.top_speed += 10 +""" -static func do_nothing(item_handler : Node) : - print(item_handler.player_stats.damage) - item_handler.player_stats.damage += 2 - print(item_handler.player_stats.damage) +#TESTING +static func do_nothing(player : Player) : + player.stats.top_speed += 10 print("nothing") - pass \ No newline at end of file + pass diff --git a/source/item/items/item1.tres b/source/item/items/item1.tres deleted file mode 100644 index 9a42d51b..00000000 --- a/source/item/items/item1.tres +++ /dev/null @@ -1,6 +0,0 @@ -[gd_resource type="Resource" load_steps=2 format=3 uid="uid://hxw1lhveewdh"] - -[ext_resource type="Script" path="res://source/item/item_resource.gd" id="1_u47e6"] - -[resource] -script = ExtResource("1_u47e6") diff --git a/source/item/items/item2.tres b/source/item/items/item2.tres deleted file mode 100644 index 3c37f9d3..00000000 --- a/source/item/items/item2.tres +++ /dev/null @@ -1,12 +0,0 @@ -[gd_resource type="Resource" load_steps=2 format=3 uid="uid://wracq7cgo1wj"] - -[ext_resource type="Script" path="res://source/item/item_resource.gd" id="1_hqexa"] - -[resource] -script = ExtResource("1_hqexa") -damage = 0.0 -dmg_mult = 0.0 -max_health = 0.0 -strength = 0.0 -speed = 0.0 -func_name = "" diff --git a/source/item/stats_and_item_handler.gd b/source/item/stats_and_item_handler.gd new file mode 100644 index 00000000..8c19c0c0 --- /dev/null +++ b/source/item/stats_and_item_handler.gd @@ -0,0 +1,42 @@ +extends Node2D + +@onready var player := get_parent() +@onready var unconditional_stats : Stats = player.base_stats.get_stats().copy() #player base stats + unconditional stats from items (updated when a new item is picked up) + + +func _ready(): + #temp code allowing items to be added before runtime + for item in get_children() : + handle_pickup(item) + +func _process(delta): + handle_process_effects() + pass + +func handle_process_effects() : + #reset the stats to the non-conditional values + player.stats = unconditional_stats.copy() + #add any conditional values + for item in get_children() : + if item.item_res.func_name == "" : continue + item.item_res.call(item.item_res.func_name, player) #calls the item specific function, passes the player + pass + +func handle_pickup(item : Item) : + #add the item node as a child of this node, the children of this node is the list of items the player has + item.reparent(self) + #change the unconditional stats (eg if the item has damage +2, the player unconditional_stats damage will increase by 2) + unconditional_stats.add_stats(item.get_stats()) + #here we could also add something for a special on_pickup() for each item if need be + pass + +func handle_drop(item : Item, destroy : bool) : + #if destroy is false, the item should be reparented + #change the unconditional stats (eg if the item has damage +2, the player unconditional_stats damage will decrease by 2) + unconditional_stats.subtract_stats(item.get_stats()) + #here we could also add something for a special on_drop() for each item if need be + #remove the item from the list of player items + #(queue_free() is temporary, will change later when we know whats actually going to happen with the item) + if destroy : item.queue_free() + pass + diff --git a/source/scenes/demo_room.tscn b/source/scenes/demo_room.tscn index 87dbbc09..81ed9a43 100644 --- a/source/scenes/demo_room.tscn +++ b/source/scenes/demo_room.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=2 format=3 uid="uid://diprigu67ubnb"] +[gd_scene load_steps=3 format=3 uid="uid://diprigu67ubnb"] [ext_resource type="PackedScene" uid="uid://rgfnpcsvv534" path="res://source/scenes/player.tscn" id="1_uxgo6"] +[ext_resource type="Script" path="res://source/scripts/quit.gd" id="2_c3313"] [node name="DemoRoom" type="Node2D"] @@ -12,3 +13,6 @@ offset_right = 40.0 offset_bottom = 40.0 color = Color(1, 0, 1, 1) + +[node name="quit" type="Node2D" parent="."] +script = ExtResource("2_c3313") diff --git a/source/scenes/item_handler.gd b/source/scenes/item_handler.gd deleted file mode 100644 index f01a58eb..00000000 --- a/source/scenes/item_handler.gd +++ /dev/null @@ -1,37 +0,0 @@ -extends Node2D - -var items : Array[Resource] - -@export var base_stats : Resource #base stats -var stats_with_items : Stats = Stats.new() #base stats + stats from items (updated when a new item is picked up) -var player_stats : Stats = Stats.new() #base stats + stats from items + conditional effects from items (updated every frame) - - -func _process(delta): - handle_process_effects() - pass - -func handle_process_effects() : - player_stats = stats_with_items.copy() - for item in items : - call(item.func_name, self) - pass - -func handle_pickup(item : Resource) : - #add the item list of player items - items.append(item) - - #change the player stats (eg if the item has damage +2, the player stats_with_items damage will increase by 2) - stats_with_items.add_stats(item.get_stats()) - - #here we could also add something for a special on pickup function for each item - -func handle_drop(item : Resource) : - #remove the item from the list of player items - items.remove_at(items.find(item)) - - #change the player stats (eg if the item has damage +2, the player stats_with_items damage will decrease by 2) - stats_with_items.subtract_stats(item.get_stats()) - - #here we could also add something for a special on drop function for each item - diff --git a/source/scenes/player.tscn b/source/scenes/player.tscn index 9d1c949c..cd6b74a3 100644 --- a/source/scenes/player.tscn +++ b/source/scenes/player.tscn @@ -1,15 +1,35 @@ -[gd_scene load_steps=6 format=3 uid="uid://rgfnpcsvv534"] +[gd_scene load_steps=9 format=3 uid="uid://rgfnpcsvv534"] [ext_resource type="Script" path="res://source/scripts/player.gd" id="1_ws1a7"] -[ext_resource type="Script" path="res://source/scenes/item_handler.gd" id="2_cjdm3"] -[ext_resource type="Resource" uid="uid://1qjff6n2w5m" path="res://source/item/base_player_stats.tres" id="3_0avcd"] +[ext_resource type="Script" path="res://source/item/stats_and_item_handler.gd" id="3_3yyiq"] +[ext_resource type="Script" path="res://source/item/item.gd" id="4_imn1n"] +[ext_resource type="Script" path="res://source/item/item_resource.gd" id="5_qrgxk"] + +[sub_resource type="Resource" id="Resource_t33mb"] +script = ExtResource("5_qrgxk") +damage = 0.0 +dmg_mult = 0.0 +max_health = 0.0 +strength = 0.0 +top_speed = 10.0 +func_name = "" [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_1d7hi"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_tx0kn"] +[sub_resource type="Resource" id="Resource_qmnsb"] +script = ExtResource("5_qrgxk") +damage = 0.0 +dmg_mult = 0.0 +max_health = 0.0 +strength = 0.0 +top_speed = 3.0 +func_name = "do_nothing" + [node name="Player" type="CharacterBody2D"] script = ExtResource("1_ws1a7") +base_stats = SubResource("Resource_t33mb") [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource("CapsuleShape2D_1d7hi") @@ -19,6 +39,9 @@ position = Vector2(1.07288e-06, 1.90735e-06) scale = Vector2(20, 15) mesh = SubResource("CapsuleMesh_tx0kn") -[node name="ItemHandler" type="Node2D" parent="."] -script = ExtResource("2_cjdm3") -base_stats = ExtResource("3_0avcd") +[node name="StatsAndItemHandler" type="Node2D" parent="."] +script = ExtResource("3_3yyiq") + +[node name="Item" type="Node2D" parent="StatsAndItemHandler"] +script = ExtResource("4_imn1n") +item_res = SubResource("Resource_qmnsb") diff --git a/source/scripts/player.gd b/source/scripts/player.gd index c106dd2c..fe1579e9 100644 --- a/source/scripts/player.gd +++ b/source/scripts/player.gd @@ -1,42 +1,49 @@ extends CharacterBody2D -var Speed := 0.0 -var topSpeed := 150.0 -var hDirection := 0.0 -var vDirection := 0.0 - -const SPEED_INC := 15.0 +class_name Player +var Speed := 0.0 +var movement := Vector2.ZERO +const TOP_SPEED_FACTOR := 15.0 +const ACCELERATION := 15.0 -# Called when the node enters the scene tree for the first time. func _ready() -> void: - pass # Replace with function body. + pass -# Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta) -> void: - handle_move(delta) - - - -func handle_move(delta) -> void: - hDirection = Input.get_axis("Left", "Right") - vDirection = Input.get_axis("Up", "Down") - if hDirection and vDirection: - Speed = move_toward(Speed, topSpeed, SPEED_INC) #slowed velocity's to account for increased movement - velocity.x = hDirection * Speed / 1.4 - velocity.y = vDirection * Speed / 1.4 - elif hDirection: - Speed = move_toward(Speed, topSpeed, SPEED_INC) - velocity.x = hDirection * Speed - velocity.y = move_toward(velocity.y, 0, SPEED_INC) - elif vDirection: - Speed = move_toward(Speed, topSpeed, SPEED_INC) - velocity.y = vDirection * Speed - velocity.x = move_toward(velocity.x, 0, SPEED_INC) - else: - velocity.x = move_toward(velocity.x, 0, SPEED_INC) - velocity.y = move_toward(velocity.y, 0, SPEED_INC) + handle_move() + + +func handle_move() -> void: + movement = Vector2(Input.get_axis("Left", "Right"), Input.get_axis("Up", "Down")).normalized() + if movement.length() : + Speed = move_toward(Speed, stats.top_speed * TOP_SPEED_FACTOR, ACCELERATION) + + if movement.x : + velocity.x = movement.x * Speed + else : + velocity.x = move_toward(velocity.x, 0, ACCELERATION) + + if movement.y : + velocity.y = movement.y * Speed + else : + velocity.y = move_toward(velocity.y, 0, ACCELERATION) + move_and_slide() + +#### item and stats handling (everything else is implemented in the stats_and_item_handler) +@onready var stats_and_item_handler : Node2D = $StatsAndItemHandler +@export var base_stats : Item_Res +var stats : Stats = Stats.new() + +func pickup_item(item : Item) : + stats_and_item_handler.handle_pickup(item) + pass + +func drop_item(item : Item, destroy : bool) : + #if destroy is false, you should be reparenting the item + stats_and_item_handler.handle_drop(item, destroy) + pass \ No newline at end of file diff --git a/source/scripts/quit.gd b/source/scripts/quit.gd new file mode 100644 index 00000000..af9cc95b --- /dev/null +++ b/source/scripts/quit.gd @@ -0,0 +1,5 @@ +extends Node + +func _process(delta): + if Input.is_key_pressed(KEY_Q) : + get_tree().quit() \ No newline at end of file From ba98c8d54bce85917747db3c5c59e8e6c6cb82c4 Mon Sep 17 00:00:00 2001 From: JoeyGiordano Date: Sun, 29 Sep 2024 17:05:47 -0400 Subject: [PATCH 08/10] Item and Stats Manager Refined Ready To Use --- source/item/Stats.gd | 48 ++++++++++++++++----------- source/item/item_resource.gd | 44 +++++++++++++++++------- source/item/stats_and_item_handler.gd | 11 +++--- source/scenes/player.tscn | 33 +++++++----------- source/scripts/player.gd | 2 +- 5 files changed, 77 insertions(+), 61 deletions(-) diff --git a/source/item/Stats.gd b/source/item/Stats.gd index d16ab9a4..f18d4d2a 100644 --- a/source/item/Stats.gd +++ b/source/item/Stats.gd @@ -1,30 +1,38 @@ class_name Stats -var damage : float = 0 -var dmg_mult : float = 0 -var max_health : float = 0 -var strength : float = 0 -var top_speed : float = 0 +var health : float = 0 +var topSpeed : float = 0 +var attackSpeed : float = 0 +var attackDamage : float = 0 +var dashCooldown : float = 0 +var abilityCooldown : float = 0 +var cost : int = 0 func add_stats(s : Stats) : - damage += s.damage - dmg_mult += s.dmg_mult - max_health += s.max_health - strength += s.strength - top_speed += s.top_speed + health += s.health + topSpeed += s.topSpeed + attackSpeed += s.attackSpeed + attackDamage += s.attackDamage + dashCooldown += s.dashCooldown + abilityCooldown += s.abilityCooldown + cost += s.cost func subtract_stats(s : Stats) : - damage -= s.damage - dmg_mult -= s.dmg_mult - max_health -= s.max_health - strength -= s.strength - top_speed -= s.top_speed + health -= s.health + topSpeed -= s.topSpeed + attackSpeed -= s.attackSpeed + attackDamage -= s.attackDamage + dashCooldown -= s.dashCooldown + abilityCooldown -= s.abilityCooldown + cost -= s.cost func copy() -> Stats : var s = Stats.new() - s.damage = damage - s.dmg_mult = dmg_mult - s.max_health = max_health - s.strength = strength - s.top_speed = top_speed + s.health = health + s.topSpeed = topSpeed + s.attackSpeed = attackSpeed + s.attackDamage = attackDamage + s.dashCooldown = dashCooldown + s.abilityCooldown = abilityCooldown + s.cost = cost return s \ No newline at end of file diff --git a/source/item/item_resource.gd b/source/item/item_resource.gd index 0c2807ca..426060e5 100644 --- a/source/item/item_resource.gd +++ b/source/item/item_resource.gd @@ -1,23 +1,43 @@ extends Resource - class_name Item_Res -@export var damage : float = 0 -@export var dmg_mult : float = 0 -@export var max_health : float = 0 -@export var strength : float = 0 -@export var top_speed : float = 0 -@export var func_name : String = "" +enum Rarity { + COMMON, + UNCOMMON, + RARE, + LEGENDARY +} + +#Info +@export var sprite : Texture +@export var name : String +@export var description : String +@export var rarity : Rarity + +#Functions +@export var func_names : Array[String] + +#Stats +@export var health : float +@export var topSpeed : float +@export var attackSpeed : float +@export var attackDamage : float +@export var dashCooldown : float +@export var abilityCooldown : float +@export var cost : int + #note that when adding a stat, a few lines need to be added in stats.gd and in get_stats() in this class func get_stats() -> Stats : var s = Stats.new() - s.damage = damage - s.dmg_mult = dmg_mult - s.max_health = max_health - s.strength = strength - s.top_speed = top_speed + s.health = health + s.topSpeed = topSpeed + s.attackSpeed = attackSpeed + s.attackDamage = attackDamage + s.dashCooldown = dashCooldown + s.abilityCooldown = abilityCooldown + s.cost = cost return s #################################################################### diff --git a/source/item/stats_and_item_handler.gd b/source/item/stats_and_item_handler.gd index 8c19c0c0..e6f7ae02 100644 --- a/source/item/stats_and_item_handler.gd +++ b/source/item/stats_and_item_handler.gd @@ -4,11 +4,6 @@ extends Node2D @onready var unconditional_stats : Stats = player.base_stats.get_stats().copy() #player base stats + unconditional stats from items (updated when a new item is picked up) -func _ready(): - #temp code allowing items to be added before runtime - for item in get_children() : - handle_pickup(item) - func _process(delta): handle_process_effects() pass @@ -18,8 +13,10 @@ func handle_process_effects() : player.stats = unconditional_stats.copy() #add any conditional values for item in get_children() : - if item.item_res.func_name == "" : continue - item.item_res.call(item.item_res.func_name, player) #calls the item specific function, passes the player + #calls the item specific functions, passes the player + for func_name in item.item_res.func_names : + if func_name == "" : continue + item.item_res.call(func_name, player) #this line calls a one of the static functions in the Item_Res class pass func handle_pickup(item : Item) : diff --git a/source/scenes/player.tscn b/source/scenes/player.tscn index cd6b74a3..529e164b 100644 --- a/source/scenes/player.tscn +++ b/source/scenes/player.tscn @@ -1,32 +1,27 @@ -[gd_scene load_steps=9 format=3 uid="uid://rgfnpcsvv534"] +[gd_scene load_steps=7 format=3 uid="uid://rgfnpcsvv534"] [ext_resource type="Script" path="res://source/scripts/player.gd" id="1_ws1a7"] [ext_resource type="Script" path="res://source/item/stats_and_item_handler.gd" id="3_3yyiq"] -[ext_resource type="Script" path="res://source/item/item.gd" id="4_imn1n"] [ext_resource type="Script" path="res://source/item/item_resource.gd" id="5_qrgxk"] [sub_resource type="Resource" id="Resource_t33mb"] script = ExtResource("5_qrgxk") -damage = 0.0 -dmg_mult = 0.0 -max_health = 0.0 -strength = 0.0 -top_speed = 10.0 -func_name = "" +name = "" +description = "" +rarity = 0 +func_names = Array[String]([]) +health = 0.0 +topSpeed = 10.0 +attackSpeed = 0.0 +attackDamage = 0.0 +dashCooldown = 0.0 +abilityCooldown = 0.0 +cost = 0 [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_1d7hi"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_tx0kn"] -[sub_resource type="Resource" id="Resource_qmnsb"] -script = ExtResource("5_qrgxk") -damage = 0.0 -dmg_mult = 0.0 -max_health = 0.0 -strength = 0.0 -top_speed = 3.0 -func_name = "do_nothing" - [node name="Player" type="CharacterBody2D"] script = ExtResource("1_ws1a7") base_stats = SubResource("Resource_t33mb") @@ -41,7 +36,3 @@ mesh = SubResource("CapsuleMesh_tx0kn") [node name="StatsAndItemHandler" type="Node2D" parent="."] script = ExtResource("3_3yyiq") - -[node name="Item" type="Node2D" parent="StatsAndItemHandler"] -script = ExtResource("4_imn1n") -item_res = SubResource("Resource_qmnsb") diff --git a/source/scripts/player.gd b/source/scripts/player.gd index fe1579e9..a079c472 100644 --- a/source/scripts/player.gd +++ b/source/scripts/player.gd @@ -20,7 +20,7 @@ func _process(delta) -> void: func handle_move() -> void: movement = Vector2(Input.get_axis("Left", "Right"), Input.get_axis("Up", "Down")).normalized() if movement.length() : - Speed = move_toward(Speed, stats.top_speed * TOP_SPEED_FACTOR, ACCELERATION) + Speed = move_toward(Speed, stats.topSpeed * TOP_SPEED_FACTOR, ACCELERATION) if movement.x : velocity.x = movement.x * Speed From 9bdf7f84a734929f4a702d92b57253d4ea2de5f2 Mon Sep 17 00:00:00 2001 From: Arti-Dev Date: Thu, 3 Oct 2024 19:15:43 -0400 Subject: [PATCH 09/10] Bump project version from 4.2 to 4.3 --- project.godot | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/project.godot b/project.godot index ae6e7f66..bba8654f 100644 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ config_version=5 config/name="Hallow's Thief" run/main_scene="res://source/scenes/demo_room.tscn" -config/features=PackedStringArray("4.2", "GL Compatibility") +config/features=PackedStringArray("4.3", "GL Compatibility") config/icon="res://icon.svg" [display] @@ -24,26 +24,26 @@ window/stretch/mode="canvas_items" 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) -, 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":4194319,"key_label":0,"unicode":0,"echo":false,"script":null) +"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,"location":0,"echo":false,"script":null) +, 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":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } 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) -, 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":4194321,"key_label":0,"unicode":0,"echo":false,"script":null) +"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,"location":0,"echo":false,"script":null) +, 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":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } 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) -, 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":4194320,"key_label":0,"unicode":0,"echo":false,"script":null) +"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,"location":0,"echo":false,"script":null) +, 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":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } 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) -, 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":4194322,"key_label":0,"unicode":0,"echo":false,"script":null) +"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,"location":0,"echo":false,"script":null) +, 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":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } From 43524cfb66d7552a9d219b757597ce6adca2a5cf Mon Sep 17 00:00:00 2001 From: 3amBEANS Date: Sun, 6 Oct 2024 16:22:03 -0400 Subject: [PATCH 10/10] Created a Character Select Scene Created a character select scene that takes four inputs and returns an integer array of what each player chose as their character, numbered 0-3 --- global_data.gd | 3 + project.godot | 4 + scenes/SelectionScene.tscn | 128 ++++++++++++++++++ scenes/background.png | Bin 0 -> 68904 bytes scenes/background.png.import | 34 +++++ scenes/character_select.gd | 71 ++++++++++ .../frankenstein_idle/Frankenstein.png | Bin 0 -> 357 bytes .../frankenstein_idle/Frankenstein.png.import | 34 +++++ source/scripts/player.gd | 15 +- 9 files changed, 287 insertions(+), 2 deletions(-) create mode 100644 global_data.gd create mode 100644 scenes/SelectionScene.tscn create mode 100644 scenes/background.png create mode 100644 scenes/background.png.import create mode 100644 scenes/character_select.gd create mode 100644 source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png create mode 100644 source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png.import diff --git a/global_data.gd b/global_data.gd new file mode 100644 index 00000000..b4a9172e --- /dev/null +++ b/global_data.gd @@ -0,0 +1,3 @@ +extends Node + +var playerCharPath: String diff --git a/project.godot b/project.godot index bba8654f..bebea2df 100644 --- a/project.godot +++ b/project.godot @@ -15,6 +15,10 @@ run/main_scene="res://source/scenes/demo_room.tscn" config/features=PackedStringArray("4.3", "GL Compatibility") config/icon="res://icon.svg" +[autoload] + +GlobalData="*res://global_data.gd" + [display] window/size/mode=2 diff --git a/scenes/SelectionScene.tscn b/scenes/SelectionScene.tscn new file mode 100644 index 00000000..ff964f8f --- /dev/null +++ b/scenes/SelectionScene.tscn @@ -0,0 +1,128 @@ +[gd_scene load_steps=4 format=3 uid="uid://bnhxjlp8dqds7"] + +[ext_resource type="Script" path="res://scenes/character_select.gd" id="1_dir6u"] +[ext_resource type="Texture2D" uid="uid://dekh4a6t8uq3j" path="res://icon.svg" id="2_cfkum"] +[ext_resource type="Texture2D" uid="uid://dwyj1uva3h3ys" path="res://scenes/background.png" id="2_d8l8v"] + +[node name="CharacterSelect" type="Node2D" node_paths=PackedStringArray("button1", "button2", "button3", "button4", "sprite1", "sprite2", "sprite3", "sprite4")] +script = ExtResource("1_dir6u") +button1 = NodePath("Player1/Button1") +button2 = NodePath("Player2/Button2") +button3 = NodePath("Player3/Button3") +button4 = NodePath("Player4/Button4") +sprite1 = NodePath("Player1/Sprite1") +sprite2 = NodePath("Player2/Sprite2") +sprite3 = NodePath("Player3/Sprite3") +sprite4 = NodePath("Player4/Sprite4") + +[node name="TextureRect" type="TextureRect" parent="."] +offset_left = -34.0 +offset_right = 1886.0 +offset_bottom = 1080.0 +scale = Vector2(0.639999, 0.64) +texture = ExtResource("2_d8l8v") + +[node name="Player1" type="Node2D" parent="."] +position = Vector2(114, -2) +scale = Vector2(2.5, 2.5) + +[node name="Button1" type="Button" parent="Player1"] +offset_left = 16.0 +offset_top = 81.0 +offset_right = 72.0 +offset_bottom = 89.0 +text = "Frankenstein" + +[node name="Sprite1" type="Sprite2D" parent="Player1"] +position = Vector2(45, 52) +scale = Vector2(0.255, 0.255) +texture = ExtResource("2_cfkum") +hframes = 4 + +[node name="Label" type="Label" parent="Player1"] +offset_left = 13.6 +offset_right = 98.6 +offset_bottom = 23.0 +text = "Player One" + +[node name="Player2" type="Node2D" parent="."] +position = Vector2(560, 0) +scale = Vector2(2.5, 2.5) + +[node name="Button2" type="Button" parent="Player2"] +offset_left = 16.0 +offset_top = 81.0 +offset_right = 72.0 +offset_bottom = 89.0 +text = "Frankenstein" + +[node name="Sprite2" type="Sprite2D" parent="Player2"] +position = Vector2(45, 52) +scale = Vector2(0.255, 0.255) +texture = ExtResource("2_cfkum") +hframes = 4 + +[node name="Label" type="Label" parent="Player2"] +offset_left = 28.0 +offset_top = -2.4 +offset_right = 113.0 +offset_bottom = 20.6 +text = "Player Two" + +[node name="Player3" type="Node2D" parent="."] +position = Vector2(126, 346) +scale = Vector2(2.5, 2.5) + +[node name="Button3" type="Button" parent="Player3"] +offset_left = 16.0 +offset_top = 81.0 +offset_right = 72.0 +offset_bottom = 89.0 +text = "Frankenstein" + +[node name="Sprite3" type="Sprite2D" parent="Player3"] +position = Vector2(45, 52) +scale = Vector2(0.255, 0.255) +texture = ExtResource("2_cfkum") +hframes = 4 + +[node name="Label" type="Label" parent="Player3"] +offset_left = 17.2 +offset_top = 1.2207e-05 +offset_right = 115.2 +offset_bottom = 23.0 +text = "Player Three" + +[node name="Player4" type="Node2D" parent="."] +position = Vector2(589, 348) +scale = Vector2(2.5, 2.5) + +[node name="Button4" type="Button" parent="Player4"] +offset_left = 16.0 +offset_top = 81.0 +offset_right = 72.0 +offset_bottom = 89.0 +text = "Frankenstein" + +[node name="Sprite4" type="Sprite2D" parent="Player4"] +position = Vector2(45, 52) +scale = Vector2(0.255, 0.255) +texture = ExtResource("2_cfkum") +hframes = 4 + +[node name="Label" type="Label" parent="Player4"] +offset_left = 23.2 +offset_top = -1.2207e-05 +offset_right = 111.2 +offset_bottom = 23.0 +text = "Player Four +" + +[node name="Button" type="Button" parent="."] +offset_left = 449.0 +offset_top = 294.0 +offset_right = 512.0 +offset_bottom = 325.0 +scale = Vector2(2.48121, 1.80882) +text = "Lock In +" diff --git a/scenes/background.png b/scenes/background.png new file mode 100644 index 0000000000000000000000000000000000000000..1e05c0b6cf43b5291ca6d2a2d0b3bb253b82ba3c GIT binary patch literal 68904 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�%yHA}6858&1MD9;9Qn#ii{Kk- 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 literal 0 HcmV?d00001 diff --git a/scenes/background.png.import b/scenes/background.png.import new file mode 100644 index 00000000..3ce480b4 --- /dev/null +++ b/scenes/background.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dwyj1uva3h3ys" +path="res://.godot/imported/background.png-d201997fe82dd443c9b8318e3f2fc828.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/background.png" +dest_files=["res://.godot/imported/background.png-d201997fe82dd443c9b8318e3f2fc828.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 diff --git a/scenes/character_select.gd b/scenes/character_select.gd new file mode 100644 index 00000000..2b9695c8 --- /dev/null +++ b/scenes/character_select.gd @@ -0,0 +1,71 @@ +extends Node2D + +@export var button1: Button +@export var button2: Button +@export var button3: Button +@export var button4: Button +@export var submit: Button + +@export var sprite1: Sprite2D +@export var sprite2: Sprite2D +@export var sprite3: Sprite2D +@export var sprite4: Sprite2D + +var player1Char = 0 +var player2Char = 0 +var player3Char = 0 +var player4Char = 0 + +var characters = ["Frankenstein","Pumpkin", "Witch", "Ghost"] + +func onButton1Press(): + if(player1Char == 3): + player1Char = 0 + else: + player1Char += 1 + sprite1.frame = player1Char + button1.text = characters[player1Char] + +func onButton2Press(): + if(player2Char == 3): + player2Char = 0 + else: + player2Char += 1 + sprite2.frame = player2Char + button2.text = characters[player2Char] + +func onButton3Press(): + if(player3Char == 3): + player3Char = 0 + else: + player3Char += 1 + sprite3.frame = player3Char + button3.text = characters[player3Char] + +func onButton4Press(): + if(player4Char == 3): + player4Char = 0 + else: + player4Char += 1 + sprite4.frame = player4Char + button4.text = characters[player4Char] + + + +func _ready(): + button1.connect("pressed", onButton1Press) + button2.connect("pressed", onButton2Press) + button3.connect("pressed", onButton3Press) + button4.connect("pressed", onButton4Press) + submit.connect("pressed", getPlayerRoles) + + +func getPlayerRoles() -> Array[int]: + var intArray = [] + intArray.append(player1Char) + intArray.append(player2Char) + intArray.append(player3Char) + intArray.append(player4Char) + return intArray + + diff --git a/source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png b/source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png new file mode 100644 index 0000000000000000000000000000000000000000..0c0c84e9fe8aaf8a1e62fd1f7e80cdf710b29f28 GIT binary patch literal 357 zcmV-r0h<1aP)Px$A4x<(R9Hvtms=8pFbGA>j=L0hoK7+(MdWdz&Dan9bb=htu zHu?rb%i)z_2>_oB9D?dV0)Pfjv;(y1`2hT723on6>cA7>1CY+Z7{OMHF1ri(W#mmj zcTqSFKw`|^gvi=-J3!ZicDEb*;AJ1s7FTa08a|M%SkxZb3!1OXj|~doc7~(_;KC{q zfE5s701+Y?eQ$zj2Bs!hdii%~t+h&Yn=AlOUhK#lTo`g8-Ax3000000NkvXXu0mjf DH@uP% literal 0 HcmV?d00001 diff --git a/source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png.import b/source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png.import new file mode 100644 index 00000000..9126062b --- /dev/null +++ b/source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://3sh3w0lbgb2i" +path="res://.godot/imported/Frankenstein.png-39c61ee2f92fc8da04e6291a8c0d268a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png" +dest_files=["res://.godot/imported/Frankenstein.png-39c61ee2f92fc8da04e6291a8c0d268a.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 diff --git a/source/scripts/player.gd b/source/scripts/player.gd index a079c472..cc5bcf94 100644 --- a/source/scripts/player.gd +++ b/source/scripts/player.gd @@ -8,9 +8,20 @@ var movement := Vector2.ZERO const TOP_SPEED_FACTOR := 15.0 const ACCELERATION := 15.0 +enum PlayerType { FRANKENSTEIN, PUMPKIN, WITCH, GHOST, MPUMPKIN, MFRANKENSTEIN, MWITCH, MGHOST} +@export var type: PlayerType + +@onready var sprite = $Sprite2D + +const sprite_settings = [{"texture": "res://source/assets/character/frankenstein/frankenstein_idle/Frankenstein.png", + "color": Color8(255, 254, 176, 255), "size": 1}, + {"texture": "res://objects/lights/candelabra.png", + "color": Color8(255, 100, 100, 255), "size": 1.5}, + {"texture": "res://objects/lights/lantern.png", + "color": Color8(100, 255, 100, 255), "size": 2}] func _ready() -> void: - pass + sprite.texture = load(sprite_settings[type]["texture"]) func _process(delta) -> void: @@ -46,4 +57,4 @@ func pickup_item(item : Item) : func drop_item(item : Item, destroy : bool) : #if destroy is false, you should be reparenting the item stats_and_item_handler.handle_drop(item, destroy) - pass \ No newline at end of file + pass