diff --git a/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/.gitignore b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/.gitignore
new file mode 100644
index 0000000..7fd11af
--- /dev/null
+++ b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/modules.xml
+/.idea.COMP250_1_2101327_AI.iml
+/projectSettingsUpdater.xml
+/contentModel.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/encodings.xml b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/indexLayout.xml b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/misc.xml b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/misc.xml
new file mode 100644
index 0000000..30bab2a
--- /dev/null
+++ b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/vcs.xml b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/COMP250_1_2101327_AI/.idea/.idea.COMP250_1_2101327_AI.dir/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/COMP250_1_2101327_AI/COMP250_1_2101327_AI.uproject.DotSettings b/COMP250_1_2101327_AI/COMP250_1_2101327_AI.uproject.DotSettings
new file mode 100644
index 0000000..2323d1b
--- /dev/null
+++ b/COMP250_1_2101327_AI/COMP250_1_2101327_AI.uproject.DotSettings
@@ -0,0 +1,4 @@
+
+ True
+ True
+ True
\ No newline at end of file
diff --git a/COMP250_1_2101327_AI/Config/DefaultEngine.ini b/COMP250_1_2101327_AI/Config/DefaultEngine.ini
index a3ed5c6..5d28da9 100644
--- a/COMP250_1_2101327_AI/Config/DefaultEngine.ini
+++ b/COMP250_1_2101327_AI/Config/DefaultEngine.ini
@@ -1,6 +1,6 @@
[/Script/EngineSettings.GameMapsSettings]
-GameDefaultMap=/Game/ThirdPerson/Maps/ThirdPersonMap.ThirdPersonMap
-EditorStartupMap=/Game/ThirdPerson/Maps/ThirdPersonMap.ThirdPersonMap
+GameDefaultMap=/Game/Main.Main
+EditorStartupMap=/Game/Main.Main
GlobalDefaultGameMode="/Script/COMP250_1_2101327_AI.COMP250_1_2101327_AIGameMode"
[/Script/Engine.RendererSettings]
diff --git a/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/BP_TurnBaseCombatV2.uasset b/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/BP_TurnBaseCombatV2.uasset
new file mode 100644
index 0000000..87fba1e
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/BP_TurnBaseCombatV2.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:585c803cd12ca9653d6899f40409bda8eaafdd13d720961e153b492aecd27647
+size 18145
diff --git a/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/Combat_UI.uasset b/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/Combat_UI.uasset
new file mode 100644
index 0000000..9b8859b
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/Combat_UI.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1e5ff8ab0d0ff280651a377665160589f56e36bd674db3c6034f753aa15a4a35
+size 69723
diff --git a/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/NS_GunEffect.uasset b/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/NS_GunEffect.uasset
new file mode 100644
index 0000000..a1e258f
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Blueprints/Combat_UI/NS_GunEffect.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c5378fff1cf66743fc8fa02bc27d7f753bf0f4548638efe8e0fab47a75516bdc
+size 1204155
diff --git a/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_DamageOverTime.uasset b/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_DamageOverTime.uasset
new file mode 100644
index 0000000..e965c36
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_DamageOverTime.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9258011884ace274348fbb3d91c741979051d2f2d78cc40b884ac21e3b898753
+size 6237
diff --git a/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_HealOverTime.uasset b/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_HealOverTime.uasset
new file mode 100644
index 0000000..572d950
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_HealOverTime.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ab7b99da71ed1d90b5852d3ae7d7d9f240a83f2a14ea7a25f2d2c40d3ab67ce8
+size 5702
diff --git a/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_Thorns.uasset b/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_Thorns.uasset
new file mode 100644
index 0000000..e2fc662
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Blueprints/StatusEffects/BP_Thorns.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5a82e1946fb542ea7136deec176e5c11615578072ed594673be532d6c78f8819
+size 6012
diff --git a/COMP250_1_2101327_AI/Content/BungeeMan/CR_BungeeMan.uasset b/COMP250_1_2101327_AI/Content/BungeeMan/CR_BungeeMan.uasset
new file mode 100644
index 0000000..18e4994
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/BungeeMan/CR_BungeeMan.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7a96ee5a55891d7dfe71e0f2ea4b9764df8d60332b776568adcb6379166a70cc
+size 11994526
diff --git a/COMP250_1_2101327_AI/Content/BungeeMan/LS_BungeeManCycle.uasset b/COMP250_1_2101327_AI/Content/BungeeMan/LS_BungeeManCycle.uasset
new file mode 100644
index 0000000..c6d550a
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/BungeeMan/LS_BungeeManCycle.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:59c050c70e3c96812b684f87652314f544c978d2d26d5fa47c1e092f0782ad48
+size 173034
diff --git a/COMP250_1_2101327_AI/Content/BungeeMan/LS_BungeeMan_Poses.uasset b/COMP250_1_2101327_AI/Content/BungeeMan/LS_BungeeMan_Poses.uasset
new file mode 100644
index 0000000..f708e6e
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/BungeeMan/LS_BungeeMan_Poses.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cea24349357ff9b3f8a57e0d28c40090a5720ecc08860c2ec468e9360ce0ccf8
+size 481634
diff --git a/COMP250_1_2101327_AI/Content/BungeeMan/Main.umap b/COMP250_1_2101327_AI/Content/BungeeMan/Main.umap
new file mode 100644
index 0000000..ca03f2a
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/BungeeMan/Main.umap
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:788bf7be105418ff05aedc7841e9f38d24b3f490d2c017e34e4c10d9c951f782
+size 43811
diff --git a/COMP250_1_2101327_AI/Content/BungeeMan/Mat_BungeeMan_Body.uasset b/COMP250_1_2101327_AI/Content/BungeeMan/Mat_BungeeMan_Body.uasset
new file mode 100644
index 0000000..b3bba10
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/BungeeMan/Mat_BungeeMan_Body.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c78714d9aa373a8e45f8abfdaa0b8188eee81803eb12800d3933e26b71bb7f74
+size 7666
diff --git a/COMP250_1_2101327_AI/Content/BungeeMan/Mat_BungeeMan_Rubber.uasset b/COMP250_1_2101327_AI/Content/BungeeMan/Mat_BungeeMan_Rubber.uasset
new file mode 100644
index 0000000..0f2c361
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/BungeeMan/Mat_BungeeMan_Rubber.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:341ed4c6b8ce50e66ba34b9fbf109165d4ca690a2642c47663298ac04152b33b
+size 6267
diff --git a/COMP250_1_2101327_AI/Content/BungeeMan/SKM_BungeeMan.uasset b/COMP250_1_2101327_AI/Content/BungeeMan/SKM_BungeeMan.uasset
new file mode 100644
index 0000000..60b3bab
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/BungeeMan/SKM_BungeeMan.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f978fb57c5965e27f134e9f348c67c8b0fba07620a0782527ec260fe985792d1
+size 3221298
diff --git a/COMP250_1_2101327_AI/Content/BungeeMan/SK_BungeeMan.uasset b/COMP250_1_2101327_AI/Content/BungeeMan/SK_BungeeMan.uasset
new file mode 100644
index 0000000..971dbab
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/BungeeMan/SK_BungeeMan.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ff16057b454e15c6e3bdab8d98177d4e630d58386e22ec0908155d81ce2dc602
+size 25890
diff --git a/COMP250_1_2101327_AI/Content/Fonts/Adistro-8MePB.uasset b/COMP250_1_2101327_AI/Content/Fonts/Adistro-8MePB.uasset
new file mode 100644
index 0000000..65248f6
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Fonts/Adistro-8MePB.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:00ab65a18f453fc46c3f380fa032fa1dae51f9845fc55ad9b00f5be898409f5a
+size 29696
diff --git a/COMP250_1_2101327_AI/Content/Fonts/Adistro-8MePB_Font.uasset b/COMP250_1_2101327_AI/Content/Fonts/Adistro-8MePB_Font.uasset
new file mode 100644
index 0000000..5a4448f
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Fonts/Adistro-8MePB_Font.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:60906b75cf616ee7db577450744c591d150d12b5e7f61969512df497d291f9f1
+size 6639
diff --git a/COMP250_1_2101327_AI/Content/Fonts/Adistro-Font.uasset b/COMP250_1_2101327_AI/Content/Fonts/Adistro-Font.uasset
new file mode 100644
index 0000000..a7b7ac7
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Fonts/Adistro-Font.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2c0cbeb552bd7553086fa73e8747a04a605e5758e04419fa4ac9bcb47c05f34b
+size 29697
diff --git a/COMP250_1_2101327_AI/Content/Fonts/Adistro_Font.uasset b/COMP250_1_2101327_AI/Content/Fonts/Adistro_Font.uasset
new file mode 100644
index 0000000..99e135f
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Fonts/Adistro_Font.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4c7aa15be377800461709d76336e387c4d8c180ccb77e828578a43920ea49171
+size 3765
diff --git a/COMP250_1_2101327_AI/Content/Fonts/Hachicro.uasset b/COMP250_1_2101327_AI/Content/Fonts/Hachicro.uasset
new file mode 100644
index 0000000..3506e69
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Fonts/Hachicro.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:28f600cb3bf0bf34d819e1f512d02ee76385276c8890c3a48fa29ca987339d03
+size 19087
diff --git a/COMP250_1_2101327_AI/Content/Fonts/Hachicro_Font.uasset b/COMP250_1_2101327_AI/Content/Fonts/Hachicro_Font.uasset
new file mode 100644
index 0000000..21c738d
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Fonts/Hachicro_Font.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e72c1f19f8b487d1dffb1f54548a7db565f6f29a38e88188d8eeb189d0f1c2c1
+size 6904
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/attack_boost.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/attack_boost.uasset
new file mode 100644
index 0000000..ab6566c
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/attack_boost.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae90ffc66753102177f26c6f4adfd6b4089acb6443ee95e9e9d2ddd363d8ea66
+size 8220
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/attack_speed_boost.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/attack_speed_boost.uasset
new file mode 100644
index 0000000..528a607
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/attack_speed_boost.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aa65e9ce03b6018fe7232dc80ca16f498a2e8d52031d61e6ae797cb2a18039a1
+size 8355
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/critical_boost.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/critical_boost.uasset
new file mode 100644
index 0000000..e58ab12
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/critical_boost.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ecc23c0754a937fd8fda3659ac49ee40f932ecfe5aa95583770573e0bbd4189e
+size 8323
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/defense_boost.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/defense_boost.uasset
new file mode 100644
index 0000000..5b0f5f5
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/defense_boost.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e0419ab6f6c84a38abd3ba63ebd8f9ec16d2c399449aa8c5aa4e23ced38bdb01
+size 8264
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/element_boost.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/element_boost.uasset
new file mode 100644
index 0000000..bca4c6f
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/element_boost.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b1e19813baf82d1b59337705b9f36608718763fc3aa8d14f0d7733a0ed88ed46
+size 8344
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/enemy_spawn_down.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/enemy_spawn_down.uasset
new file mode 100644
index 0000000..68bc81c
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/enemy_spawn_down.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9b46e118a8d805fa8cf5ddc1027e63fbd90bd1f3e790fc85736003a0b3372ae2
+size 8347
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/exp_boost.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/exp_boost.uasset
new file mode 100644
index 0000000..1d06208
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/exp_boost.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:026a40d6f7eb94de3d5ff55003eae17081739eccfa63b396ecddcb1c1af93f14
+size 8200
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/ghost_form__physical_damage_immunity_.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/ghost_form__physical_damage_immunity_.uasset
new file mode 100644
index 0000000..c45f443
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/ghost_form__physical_damage_immunity_.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:195c0b0ac92c2f526dd4b2aded8c4f6f1a47c6668c9aa8602e7150e63a72e489
+size 8776
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/glow.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/glow.uasset
new file mode 100644
index 0000000..f19dca0
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/glow.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:520c020adf723bdf5412e46594be059b120334f4d08660ed805137767297a717
+size 8019
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/knockback_boost.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/knockback_boost.uasset
new file mode 100644
index 0000000..89868d3
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/knockback_boost.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ec208a4a64f60f39fb65cedb41eee2fc11f6870fc06d2cab21b3ddc7620394ec
+size 8314
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/knockback_resistance.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/knockback_resistance.uasset
new file mode 100644
index 0000000..031cc7d
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/knockback_resistance.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:80deeb9a1b2cd3ff9d4102cb3d3a03abffea854a4ea83998df21d3442b6c6c06
+size 8369
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/lucky_boost.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/lucky_boost.uasset
new file mode 100644
index 0000000..8f9206e
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/lucky_boost.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d4a5bbf1c98647bb71775e5a4b325cce29dddb7a6ba0790fe6954f3e1f078d64
+size 8339
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/magic_amplification.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/magic_amplification.uasset
new file mode 100644
index 0000000..ae47831
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/magic_amplification.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c2e777dfb23fa939d48e1ba920053448628a9215cd353c0740e57819a7dcef28
+size 8434
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/negative_status_resistance.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/negative_status_resistance.uasset
new file mode 100644
index 0000000..dee9b21
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/negative_status_resistance.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d711d75f3d65452ebb9b8e6c74bc66f224f448bf2b962ab9eeafdfe75b30455a
+size 8523
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/regeneration.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/regeneration.uasset
new file mode 100644
index 0000000..0e0e998
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/regeneration.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:89b5065ae07ebbf19bf820f50344d2136978275f7674cac47bce490a09ec0504
+size 8262
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Buffs/swiftness.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/swiftness.uasset
new file mode 100644
index 0000000..3cff89d
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Buffs/swiftness.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:08da0ba3cc9d1bfa96093b0b54e94b2e342cd773773839c08cb5085210b777c0
+size 8189
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/attack_down.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/attack_down.uasset
new file mode 100644
index 0000000..7cda57c
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/attack_down.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:949ed416bf44fa31f1414322061138d6197a8c03e7e6b5b37c3f1c75eeeba9a8
+size 8252
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/bleeding.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/bleeding.uasset
new file mode 100644
index 0000000..428cdf8
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/bleeding.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:98cca39e7a383a9f6cc544253f83b9fbd429b66864e7163dd58dfc8b0a11c3e2
+size 8144
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/blinded.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/blinded.uasset
new file mode 100644
index 0000000..fdfcabb
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/blinded.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fec639bcfd64dbd2ca65695a3552b2bc2015ec45c0b1224d92bec1c4cd5cf53e
+size 8157
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/confused.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/confused.uasset
new file mode 100644
index 0000000..e09497d
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/confused.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6e7d3bb45efb7f7ea91bf6d3de304abeb4376507fde7a451ba7c7e300891052a
+size 8099
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/cursed__disarmed+silenced_.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/cursed__disarmed+silenced_.uasset
new file mode 100644
index 0000000..ee2c97d
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/cursed__disarmed+silenced_.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:372017f761b45ecf65aee06a50b904c3932f6b17b480071a6689358a7c6dafc9
+size 8577
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/defense_down.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/defense_down.uasset
new file mode 100644
index 0000000..b7c4954
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/defense_down.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f298f4ce376dbed722e903e15c87baee1198a2cdd2e992c308255b30c1feec5f
+size 8306
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/disarmed.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/disarmed.uasset
new file mode 100644
index 0000000..2b42b59
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/disarmed.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a8ea8cc856926d197ec27e948c7d8161387aebefee6d831c7417a4d657ba5da0
+size 8167
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/frozen.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/frozen.uasset
new file mode 100644
index 0000000..c7c9e8c
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/frozen.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:85ad7c282049383d72cde3fbc4ded8145a19893327e3b2d2e5440363bf21a32a
+size 8206
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/hungry.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/hungry.uasset
new file mode 100644
index 0000000..2056d81
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/hungry.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ab1a6d1a37b964767938588cc1d80eb56eeb269c3699122d3e7a3f1deb0067f0
+size 8107
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/on_fire__burning_.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/on_fire__burning_.uasset
new file mode 100644
index 0000000..54cf767
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/on_fire__burning_.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b1b2ed7ced64f121fcb17d05ab99fb5268c8773ccf4310a36dc20f19d146dde8
+size 8424
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/paralyzed.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/paralyzed.uasset
new file mode 100644
index 0000000..b390eaa
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/paralyzed.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:51e5d7503a4082ae6b1112f6280e49017c37b9b132e678b7171ac5d51949775a
+size 8157
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/poisoned.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/poisoned.uasset
new file mode 100644
index 0000000..edf7b16
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/poisoned.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:028decf63f1dce1b2d9c2e6016e2aa07c2cf495b83ae308b4bfebbed8c58fe52
+size 8134
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/silenced.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/silenced.uasset
new file mode 100644
index 0000000..3c4451f
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/silenced.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4f8015b60a53f50bb8b36bb0106a738f101eb38f4e3e7c62fbe3c1cdface8aba
+size 8098
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/sleeping.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/sleeping.uasset
new file mode 100644
index 0000000..6144a62
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/sleeping.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2b80c5ca31c41bbecab89d37632617ea66a52aee5563662fae61aae26a8a803d
+size 8158
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/slowed.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/slowed.uasset
new file mode 100644
index 0000000..e9753ef
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/slowed.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:61ddb2570530f9806147185cc461f8d6bff78156013e60c8f287d8665c07b58d
+size 8136
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/stunned.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/stunned.uasset
new file mode 100644
index 0000000..8be22b4
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Debuffs/stunned.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4ed9f1207a5f25ebc063aca68cd8ca39a9fafb0249776d81e1959f8a1acd9b48
+size 8147
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/blinding_light_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/blinding_light_spell.uasset
new file mode 100644
index 0000000..fd4cba2
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/blinding_light_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2ad1f19186d9d08a5643ff15de97b024ba83f9486740b8a670a98cd9d0719e40
+size 8455
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/counterspell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/counterspell.uasset
new file mode 100644
index 0000000..aa7f1e6
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/counterspell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f865c436a56bb822841df7204e3a6c5fee07022f641e528e8a166de8372afdf0
+size 8262
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/divine_protection_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/divine_protection_spell.uasset
new file mode 100644
index 0000000..ab20301
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/divine_protection_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3c61f0861043bd969c81a2ddad68fc6863e74072ced943d3bf4224b80ede6605
+size 8541
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/fire_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/fire_spell.uasset
new file mode 100644
index 0000000..95386a5
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/fire_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d1d933840519c36c31898604c306255ca15697d22b349584b47a495c7aa6dca3
+size 8205
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/fire_spell_2.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/fire_spell_2.uasset
new file mode 100644
index 0000000..7d13b5c
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/fire_spell_2.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3b7bd60c3548b5092b63ed45b401c6993171d0bf73786b2e07de537c6c824038
+size 8234
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/fortify_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/fortify_spell.uasset
new file mode 100644
index 0000000..f94bb25
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/fortify_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7de6452182330ea8eefb90e8ae3594945fcec2cb386b0b42e2d7823dcec62cc4
+size 8285
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/frenzy_spell__critical_booster_.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/frenzy_spell__critical_booster_.uasset
new file mode 100644
index 0000000..351815c
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/frenzy_spell__critical_booster_.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9b6816f81dc15add40f8dce3e39819148d8e6b9126e1c31ee7483d0261eba854
+size 8634
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/healing_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/healing_spell.uasset
new file mode 100644
index 0000000..bd9289c
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/healing_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a5f4deccdd31b55b272f4818fdc03b90d15709990cae2cd1a5df4883fc080293
+size 8361
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/ice_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/ice_spell.uasset
new file mode 100644
index 0000000..6e38e12
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/ice_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5e3ce6f7300a3923ee31ff87e4a087fba3e4497910b69bb1af52881607c9b389
+size 8260
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/lightning_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/lightning_spell.uasset
new file mode 100644
index 0000000..7cba2cc
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/lightning_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cdeec173209b63dbe28a34928c5adc2eb1feac4b39f9cb4ba376a7418515cff8
+size 8316
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/mana_replenish.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/mana_replenish.uasset
new file mode 100644
index 0000000..813b6c3
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/mana_replenish.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bc35f7283a1864bb031bc1cf643671dd959c80dfd1acf5fc6fb1a68ba4949615
+size 8293
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/poison_dagger.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/poison_dagger.uasset
new file mode 100644
index 0000000..8c20be8
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/poison_dagger.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6a5dd9cb118472f8dd8b861770819e0b5fc8110c75986277ed5ec0042440c273
+size 8303
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/summoning_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/summoning_spell.uasset
new file mode 100644
index 0000000..f8d2c2a
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/summoning_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0f11cf4941ffb2e8687d84c44a391bcd0faf167daee5d9f1f5e20d579213a28d
+size 8221
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/teleportation_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/teleportation_spell.uasset
new file mode 100644
index 0000000..e295011
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/teleportation_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1343c19521f6c0bc13fffbc988e6bef6857122dfa00c82f3395ae2b99ad6fbf5
+size 8445
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/thorn_vine_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/thorn_vine_spell.uasset
new file mode 100644
index 0000000..fa33506
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/thorn_vine_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:16f2b50d6663024a2382cce110f667f960ed9a21f0ba3411241048ce44cf9ead
+size 8359
diff --git a/COMP250_1_2101327_AI/Content/Images/Status/Spells/water_spell.uasset b/COMP250_1_2101327_AI/Content/Images/Status/Spells/water_spell.uasset
new file mode 100644
index 0000000..6a1c832
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Images/Status/Spells/water_spell.uasset
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:72e49257c406621f360829d205b2a3e7dc5972c2199ac6229426dc7fc71025d8
+size 8223
diff --git a/COMP250_1_2101327_AI/Content/Main.umap b/COMP250_1_2101327_AI/Content/Main.umap
new file mode 100644
index 0000000..5164b53
--- /dev/null
+++ b/COMP250_1_2101327_AI/Content/Main.umap
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:31de49eac503c3e1fda877ed49a3e964be4843d2d8cc0524fd00d8bc12b3ba79
+size 36123
diff --git a/COMP250_1_2101327_AI/Content/StarterContent/Architecture/Floor_400x400.uasset b/COMP250_1_2101327_AI/Content/StarterContent/Architecture/Floor_400x400.uasset
index 80f4e48..dbc8014 100644
--- a/COMP250_1_2101327_AI/Content/StarterContent/Architecture/Floor_400x400.uasset
+++ b/COMP250_1_2101327_AI/Content/StarterContent/Architecture/Floor_400x400.uasset
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1c6e2e377e3ebfb45e88716d23a72df949e487c1d40312aae81c2bd62e03f010
-size 14806
+oid sha256:1e2c98917101ce51951b0dcfdff82038b16b8f5fed288983d6ff54dc61bb054a
+size 14831
diff --git a/COMP250_1_2101327_AI/Platforms/HoloLens/Config/HoloLensEngine.ini b/COMP250_1_2101327_AI/Platforms/HoloLens/Config/HoloLensEngine.ini
new file mode 100644
index 0000000..d5ebb91
--- /dev/null
+++ b/COMP250_1_2101327_AI/Platforms/HoloLens/Config/HoloLensEngine.ini
@@ -0,0 +1,32 @@
+
+
+[/Script/HoloLensPlatformEditor.HoloLensTargetSettings]
+bBuildForEmulation=False
+bBuildForDevice=True
+bUseNameForLogo=True
+bBuildForRetailWindowsStore=False
+bAutoIncrementVersion=False
+bShouldCreateAppInstaller=False
+AppInstallerInstallationURL=
+HoursBetweenUpdateChecks=0
+bEnablePIXProfiling=False
+TileBackgroundColor=(B=64,G=0,R=0,A=255)
+SplashScreenBackgroundColor=(B=64,G=0,R=0,A=255)
++PerCultureResources=(CultureId="",Strings=(PackageDisplayName="",PublisherDisplayName="",PackageDescription="",ApplicationDisplayName="",ApplicationDescription=""),Images=())
+TargetDeviceFamily=Windows.Holographic
+MinimumPlatformVersion=
+MaximumPlatformVersionTested=10.0.18362.0
+MaxTrianglesPerCubicMeter=500.000000
+SpatialMeshingVolumeSize=20.000000
+CompilerVersion=Default
+Windows10SDKVersion=10.0.18362.0
++CapabilityList=internetClientServer
++CapabilityList=privateNetworkClientServer
++Uap2CapabilityList=spatialPerception
+bSetDefaultCapabilities=False
+SpatializationPlugin=
+SourceDataOverridePlugin=
+ReverbPlugin=
+OcclusionPlugin=
+SoundCueCookQualityIndex=-1
+
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/COMP250_1_2101327_AI.Build.cs b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/COMP250_1_2101327_AI.Build.cs
index 7c97a39..c808232 100644
--- a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/COMP250_1_2101327_AI.Build.cs
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/COMP250_1_2101327_AI.Build.cs
@@ -8,6 +8,8 @@ public class COMP250_1_2101327_AI : ModuleRules
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
- PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "EnhancedInput" });
+ PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "EnhancedInput", "Niagara", "UMG", "AIModule" });
+
+ PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
}
}
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/Player/PlayerCharacter.cpp b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/Player/PlayerCharacter.cpp
new file mode 100644
index 0000000..574df9e
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/Player/PlayerCharacter.cpp
@@ -0,0 +1,32 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "PlayerCharacter.h"
+
+
+// Sets default values
+APlayerCharacter::APlayerCharacter()
+{
+ // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
+ PrimaryActorTick.bCanEverTick = true;
+}
+
+// Called when the game starts or when spawned
+void APlayerCharacter::BeginPlay()
+{
+ Super::BeginPlay();
+
+}
+
+// Called every frame
+void APlayerCharacter::Tick(float DeltaTime)
+{
+ Super::Tick(DeltaTime);
+}
+
+// Called to bind functionality to input
+void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
+{
+ Super::SetupPlayerInputComponent(PlayerInputComponent);
+}
+
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/Player/PlayerCharacter.h b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/Player/PlayerCharacter.h
new file mode 100644
index 0000000..c6951b5
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/Player/PlayerCharacter.h
@@ -0,0 +1,31 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "GameFramework/Character.h"
+#include "PlayerCharacter.generated.h"
+
+UCLASS()
+class COMP250_1_2101327_AI_API APlayerCharacter : public ACharacter
+{
+ GENERATED_BODY()
+
+public:
+ // Sets default values for this character's properties
+ APlayerCharacter();
+
+ UPROPERTY(BlueprintReadWrite, EditAnywhere)
+ float Health = 100.0f;
+
+protected:
+ // Called when the game starts or when spawned
+ virtual void BeginPlay() override;
+
+public:
+ // Called every frame
+ virtual void Tick(float DeltaTime) override;
+
+ // Called to bind functionality to input
+ virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
+};
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffect.cpp b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffect.cpp
new file mode 100644
index 0000000..931ac87
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffect.cpp
@@ -0,0 +1,59 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "StatusEffect.h"
+
+#include "StatusSystem.h"
+#include "Kismet/GameplayStatics.h"
+#include "TurnBaseCombatV2.h"
+#include "Components/TextBlock.h"
+
+void UStatusEffect::Invoke(AActor* Character, float TimeOfInit)
+{
+ GetWorld()->GetTimerManager().SetTimer(ExpiryTimerHandle, [this, Character, TimeOfInit] { CheckForExpiry(TimeOfInit, Character); }, 1, true, 0);
+}
+
+void UStatusEffect::OnExpiry(AActor* Character)
+{
+ GetWorld()->GetTimerManager().ClearTimer(ExpiryTimerHandle);
+ UStatusSystem* StatusSystem = Cast(Character->GetComponentByClass(UStatusSystem::StaticClass()));
+ if (StatusSystem->GetActiveStatusEffect(this).StatusIcon == nullptr) return;
+ StatusSystem->GetActiveStatusEffect(this).StatusIcon->RemoveFromParent();
+ StatusSystem->RemoveStatusEffect(this);
+ ATurnBaseCombatV2* CombatSystem = Cast(GetWorld()->GetGameState());
+ CombatSystem->OnPlayerTurn.Remove(OnPlayerTurnDelegateHandle);
+ CombatSystem->OnEnemyTurn.Remove(OnEnemyTurnDelegateHandle);
+}
+
+void UStatusEffect::OnPlayerTurn(AActor* Character, AActor* Enemy)
+{
+ return;
+}
+
+void UStatusEffect::OnEnemyTurn(AActor* Enemy, AActor* Character)
+{
+ TickDown(Character);
+}
+
+void UStatusEffect::OnStatusEffectAdd(AActor* Character)
+{
+ ATurnBaseCombatV2* CombatSystem = Cast(GetWorld()->GetGameState());
+ OnPlayerTurnDelegateHandle = CombatSystem->OnPlayerTurn.AddUObject(this, &UStatusEffect::OnPlayerTurn);
+ OnEnemyTurnDelegateHandle = CombatSystem->OnEnemyTurn.AddUObject(this, &UStatusEffect::OnEnemyTurn);
+}
+
+void UStatusEffect::TickDown(AActor* Character)
+{
+ UStatusSystem* StatusSystem = Cast(Character->GetComponentByClass(UStatusSystem::StaticClass()));
+ UTextBlock* StatusText = Cast(StatusSystem->GetActiveStatusEffect(this).StatusIcon->GetWidgetFromName(TEXT("DurationText")));
+ StatusText->SetText(FText::FromString(FString::FromInt(BaseDuration)));
+}
+
+void UStatusEffect::CheckForExpiry(const float TimeOfExpiry, AActor* Character)
+{
+ if (TimeOfExpiry <= UGameplayStatics::GetRealTimeSeconds(GetWorld())) OnExpiry(Character);
+ UStatusSystem* StatusSystem = Cast(Character->GetComponentByClass(UStatusSystem::StaticClass()));
+ if (StatusSystem->GetActiveStatusEffect(this).StatusIcon == nullptr) return;
+ UTextBlock* StatusText = Cast(StatusSystem->GetActiveStatusEffect(this).StatusIcon->GetWidgetFromName(TEXT("DurationText")));
+ StatusText->SetText(FText::FromString(FString::FromInt(TimeOfExpiry - UGameplayStatics::GetRealTimeSeconds(GetWorld()))));
+}
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffect.h b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffect.h
new file mode 100644
index 0000000..a6bdf69
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffect.h
@@ -0,0 +1,53 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "UObject/NoExportTypes.h"
+#include "StatusEffect.generated.h"
+
+/**
+ *
+ */
+UCLASS(Abstract, Blueprintable)
+class COMP250_1_2101327_AI_API UStatusEffect : public UObject
+{
+ GENERATED_BODY()
+
+public:
+ UPROPERTY(EditAnywhere, BlueprintReadWrite)
+ FString Name;
+ UPROPERTY(EditAnywhere, BlueprintReadWrite)
+ FString Description;
+ UPROPERTY(EditAnywhere, BlueprintReadWrite)
+ bool IsForCombatOnly = false;
+ UPROPERTY(EditAnywhere, BlueprintReadWrite)
+ float BaseDuration;
+ UPROPERTY(EditAnywhere, BlueprintReadWrite)
+ UTexture2D* Icon;
+
+ UFUNCTION()
+ virtual void Invoke(AActor* Character, float TimeOfExpiry);
+ UFUNCTION()
+ virtual void OnExpiry(AActor* Character);
+
+ UFUNCTION()
+ virtual void OnPlayerTurn(AActor* Character, AActor* Enemy);
+ UFUNCTION()
+ virtual void OnEnemyTurn(AActor* Enemy, AActor* Character);
+
+ UFUNCTION()
+ virtual void OnStatusEffectAdd(AActor* Character);
+
+ UFUNCTION()
+ virtual void TickDown(AActor* Character);
+
+protected:
+ UPROPERTY()
+ FTimerHandle ExpiryTimerHandle;
+ UFUNCTION()
+ void CheckForExpiry(float TimeOfExpiry, AActor* Character);
+
+ FDelegateHandle OnPlayerTurnDelegateHandle;
+ FDelegateHandle OnEnemyTurnDelegateHandle;
+};
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/DamageOverTime.cpp b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/DamageOverTime.cpp
new file mode 100644
index 0000000..e03f838
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/DamageOverTime.cpp
@@ -0,0 +1,17 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "DamageOverTime.h"
+#include "COMP250_1_2101327_AI/TurnBasedCombatV2/TurnBaseCombatV2.h"
+
+void UDamageOverTime::OnEnemyTurn(AActor* Enemy, AActor* Character)
+{
+ ATurnBaseCombatV2* CombatSystem = Cast(GetWorld()->GetGameState());
+ CombatSystem->DamageEnemy(DamagePerTurn, "DOT");
+ BaseDuration -= 1.0f;
+ Super::OnEnemyTurn(Enemy, Character);
+ if (BaseDuration <= 0.0f)
+ {
+ OnExpiry(Character);
+ }
+}
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/DamageOverTime.h b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/DamageOverTime.h
new file mode 100644
index 0000000..21dcc61
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/DamageOverTime.h
@@ -0,0 +1,23 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "../StatusEffect.h"
+#include "DamageOverTime.generated.h"
+
+/**
+ *
+ */
+UCLASS()
+class COMP250_1_2101327_AI_API UDamageOverTime : public UStatusEffect
+{
+ GENERATED_BODY()
+public:
+ UPROPERTY(EditAnywhere, BlueprintReadWrite)
+ float DamagePerTurn = 6.0f;
+
+ //virtual void Invoke(AActor* Character, float TimeOfExpiry) override;
+ //virtual void OnExpiry(AActor* Character) override;
+ virtual void OnEnemyTurn(AActor* Enemy, AActor* Character) override;
+};
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/HealOverTime.cpp b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/HealOverTime.cpp
new file mode 100644
index 0000000..64ab655
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/HealOverTime.cpp
@@ -0,0 +1,30 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "HealOverTime.h"
+
+#include "COMP250_1_2101327_AI/Player/PlayerCharacter.h"
+
+void UHealOverTime::Heal(AActor* Character, const float Amount) const
+{
+ if (APlayerCharacter* CastedCharacter = Cast(Character); CastedCharacter->Health < 100)
+ {
+ CastedCharacter->Health += Amount;
+ }
+ else
+ {
+ CastedCharacter->Health = 100;
+ }
+}
+
+void UHealOverTime::Invoke(AActor* Character, float TimeOfExpiry)
+{
+ Super::Invoke(Character, TimeOfExpiry);
+ GetWorld()->GetTimerManager().SetTimer(HealTimerHandle, [this, Character] { Heal(Character, 1); }, 1, true, 0);
+}
+
+void UHealOverTime::OnExpiry(AActor* Character)
+{
+ GetWorld()->GetTimerManager().ClearTimer(HealTimerHandle);
+ Super::OnExpiry(Character);
+}
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/HealOverTime.h b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/HealOverTime.h
new file mode 100644
index 0000000..fefbd0a
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/HealOverTime.h
@@ -0,0 +1,25 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "../StatusEffect.h"
+#include "HealOverTime.generated.h"
+
+/**
+ *
+ */
+UCLASS()
+class COMP250_1_2101327_AI_API UHealOverTime : public UStatusEffect
+{
+ GENERATED_BODY()
+
+protected:
+ UFUNCTION()
+ void Heal(AActor* Character, float Amount) const;
+
+public:
+ FTimerHandle HealTimerHandle;
+ virtual void Invoke(AActor* Character, float TimeOfExpiry) override;
+ virtual void OnExpiry(AActor* Character) override;
+};
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/Thorns.cpp b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/Thorns.cpp
new file mode 100644
index 0000000..7c58b65
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/Thorns.cpp
@@ -0,0 +1,28 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "Thorns.h"
+
+#include "COMP250_1_2101327_AI/TurnBasedCombatV2/TurnBaseCombatV2.h"
+
+void UThorns::Invoke(AActor* Character, float TimeOfExpiry)
+{
+ Super::Invoke(Character, TimeOfExpiry);
+}
+
+void UThorns::OnExpiry(AActor* Character)
+{
+ Super::OnExpiry(Character);
+}
+
+void UThorns::OnEnemyTurn(AActor* Enemy, AActor* Character)
+{
+ ATurnBaseCombatV2* CombatSystem = Cast(GetWorld()->GetGameState());
+ CombatSystem->DamageEnemy(DamagePerTurn, "thorns");
+ BaseDuration -= 1.0f;
+ Super::OnEnemyTurn(Enemy, Character);
+ if (BaseDuration <= 0.0f)
+ {
+ OnExpiry(Character);
+ }
+}
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/Thorns.h b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/Thorns.h
new file mode 100644
index 0000000..d36843b
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusEffects/Thorns.h
@@ -0,0 +1,24 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "../StatusEffect.h"
+#include "Thorns.generated.h"
+
+/**
+ *
+ */
+UCLASS()
+class COMP250_1_2101327_AI_API UThorns : public UStatusEffect
+{
+ GENERATED_BODY()
+
+public:
+ UPROPERTY(EditAnywhere, BlueprintReadWrite)
+ float DamagePerTurn = 3.0f;
+
+ virtual void Invoke(AActor* Character, float TimeOfExpiry) override;
+ virtual void OnExpiry(AActor* Character) override;
+ virtual void OnEnemyTurn(AActor* Enemy, AActor* Character) override;
+};
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusSystem.cpp b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusSystem.cpp
new file mode 100644
index 0000000..046bc5e
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusSystem.cpp
@@ -0,0 +1,86 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "StatusSystem.h"
+#include
+
+#include "Blueprint/UserWidget.h"
+#include "Components/Image.h"
+#include "Components/TextBlock.h"
+
+// Sets default values for this component's properties
+UStatusSystem::UStatusSystem()
+{
+ // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
+ // off to improve performance if you don't need them.
+ PrimaryComponentTick.bCanEverTick = true;
+ static ConstructorHelpers::FClassFinder HUDStatusIndicatorsWidgetClassFinder(TEXT("/Game/Blueprints/Status_UI/StatusIndicator"));
+ HUDStatusIndicatorsWidget = HUDStatusIndicatorsWidgetClassFinder.Class;
+ static ConstructorHelpers::FClassFinder HUDStatusIconWidgetClassFinder(TEXT("/Game/Blueprints/Status_UI/StatusIcon"));
+ HUDStatusIconWidget = HUDStatusIconWidgetClassFinder.Class;
+}
+
+
+// Called when the game starts
+void UStatusSystem::BeginPlay()
+{
+ Super::BeginPlay();
+
+ HUDStatusIndicators = CreateWidget(GetWorld(), HUDStatusIndicatorsWidget);
+ HUDStatusIndicators->AddToViewport();
+ StatusIconsBox = Cast(HUDStatusIndicators->GetWidgetFromName(TEXT("StatusIndicators")));
+}
+
+
+// Called every frame
+void UStatusSystem::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
+{
+ Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+}
+
+void UStatusSystem::AddStatusEffect(UStatusEffect* StatusEffect, const float DurationMultiplier, const bool Invoke)
+{
+ FActiveStatusEffect NewStatusEffect;
+ NewStatusEffect.StatusEffect = StatusEffect;
+ NewStatusEffect.TimeInitiated = UGameplayStatics::GetRealTimeSeconds(GetWorld());
+ if (StatusEffect->IsForCombatOnly)
+ {
+ NewStatusEffect.TimeTillExpiry = StatusEffect->BaseDuration * DurationMultiplier;
+ }
+ else
+ {
+ NewStatusEffect.TimeTillExpiry = UGameplayStatics::GetRealTimeSeconds(GetWorld()) + StatusEffect->BaseDuration * DurationMultiplier;
+ }
+ NewStatusEffect.StatusIcon = CreateWidget(GetWorld(), HUDStatusIconWidget);
+ UImage* StatusIconImage = Cast(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("StatusIconImage")));
+ StatusIconImage->SetBrushFromTexture(StatusEffect->Icon);
+ StatusIconsBox->AddChild(NewStatusEffect.StatusIcon);
+ NewStatusEffect.StatusEffect->OnStatusEffectAdd(GetOwner());
+ UTextBlock* StatusText = Cast(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("DurationText")));
+ StatusText->SetText(FText::FromString(FString::FromInt(NewStatusEffect.TimeTillExpiry)));
+ if (Invoke) NewStatusEffect.StatusEffect->Invoke(GetOwner(), NewStatusEffect.TimeTillExpiry);
+
+ ActiveStatusEffects.Add(NewStatusEffect);
+}
+
+void UStatusSystem::RemoveStatusEffect(UStatusEffect* StatusEffect)
+{
+ if (ActiveStatusEffects.Contains(FActiveStatusEffect{0, 0, StatusEffect, nullptr}))
+ {
+ ActiveStatusEffects.Remove(FActiveStatusEffect{0, 0, StatusEffect, nullptr});
+ }
+ else
+ {
+ UE_LOG(LogTemp, Warning, TEXT("StatusEffect not found in ActiveStatusEffects"));
+ }
+}
+
+FActiveStatusEffect UStatusSystem::GetActiveStatusEffect(UStatusEffect* StatusEffect)
+{
+ if (ActiveStatusEffects.Contains(FActiveStatusEffect{0, 0, StatusEffect, nullptr}))
+ {
+ return ActiveStatusEffects[ActiveStatusEffects.Find(FActiveStatusEffect{0, 0, StatusEffect, nullptr})];
+ }
+ UE_LOG(LogTemp, Warning, TEXT("StatusEffect not found in ActiveStatusEffects"));
+ return FActiveStatusEffect();
+}
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusSystem.h b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusSystem.h
new file mode 100644
index 0000000..c2fb5bb
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/StatusSystem.h
@@ -0,0 +1,70 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "Components/ActorComponent.h"
+#include "StatusEffect.h"
+#include "Components/WrapBox.h"
+#include "StatusSystem.generated.h"
+
+USTRUCT()
+struct FActiveStatusEffect
+{
+ GENERATED_BODY()
+
+ UPROPERTY()
+ float TimeInitiated;
+ UPROPERTY()
+ float TimeTillExpiry;
+
+ UPROPERTY()
+ UStatusEffect* StatusEffect;
+
+ UPROPERTY()
+ UUserWidget* StatusIcon;
+
+ bool operator==(const FActiveStatusEffect& Comp) const
+ {
+ return StatusEffect == Comp.StatusEffect;
+ }
+};
+
+UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
+class COMP250_1_2101327_AI_API UStatusSystem : public UActorComponent
+{
+ GENERATED_BODY()
+
+public:
+ // Sets default values for this component's properties
+ UStatusSystem();
+
+ UPROPERTY()
+ TSubclassOf HUDStatusIndicatorsWidget;
+ UPROPERTY()
+ TSubclassOf HUDStatusIconWidget;
+ UPROPERTY()
+ UUserWidget* HUDStatusIndicators;
+ UPROPERTY()
+ UWrapBox* StatusIconsBox;
+
+ UPROPERTY()
+ TArray ActiveStatusEffects;
+
+protected:
+ // Called when the game starts
+ virtual void BeginPlay() override;
+
+public:
+ // Called every frame
+ virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
+
+ UFUNCTION()
+ void AddStatusEffect(UStatusEffect* StatusEffect, float DurationMultiplier = 1.0f, bool Invoke = true);
+
+ UFUNCTION()
+ void RemoveStatusEffect(UStatusEffect* StatusEffect);
+
+ UFUNCTION()
+ FActiveStatusEffect GetActiveStatusEffect(UStatusEffect* StatusEffect);
+};
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/TurnBaseCombatV2.cpp b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/TurnBaseCombatV2.cpp
new file mode 100644
index 0000000..ea8c4f6
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/TurnBaseCombatV2.cpp
@@ -0,0 +1,501 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "TurnBaseCombatV2.h"
+#include "CoreMinimal.h"
+#include "AIController.h"
+#include "StatusSystem.h"
+#include "Blueprint/UserWidget.h"
+#include "BehaviorTree/BlackboardComponent.h"
+#include "Components/TextBlock.h"
+#include "Components/ProgressBar.h"
+#include "GameFramework/Character.h"
+#include "Kismet/GameplayStatics.h"
+#include "COMP250_1_2101327_AI/Player/PlayerCharacter.h"
+#include "UObject/UnrealTypePrivate.h"
+
+// Sets default values
+ATurnBaseCombatV2::ATurnBaseCombatV2()
+{
+ if (HUDWidget == nullptr)
+ {
+ static ConstructorHelpers::FClassFinder HUDWidgetClass(TEXT("/Game/Blueprints/Combat_UI/Combat_UI"));
+ HUDWidget = HUDWidgetClass.Class;
+ static ConstructorHelpers::FClassFinder StatusEffectThornsClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_Thorns"));
+ ThornsStatusEffect = StatusEffectThornsClassFinder.Class;
+ static ConstructorHelpers::FClassFinder StatusEffectDOTClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_DamageOverTime"));
+ DOTStatusEffect = StatusEffectDOTClassFinder.Class;
+
+ //static ConstructorHelpers::FClassFinder DeathScreenWidgetClass(TEXT("/Game/Blueprints/Death_UI/Death_UI"));
+ //DeathScreenWidgetSubclass = DeathScreenWidgetClass.Class;
+ }
+}
+
+void ATurnBaseCombatV2::StartCombat(AActor* Enemy)
+{
+ if (Enemy == nullptr) return;
+ UBlackboardComponent* EnemyBlackboard = Cast(Enemy->GetInstigatorController())->GetBlackboardComponent();
+
+ if (EnemyBlackboard->GetValueAsBool("IsInCombat")) return;
+ EnemyBlackboard->SetValueAsBool("IsInCombat", true);
+ FProperty* HealthProperty = Enemy->GetClass()->FindPropertyByName(FName("Health"));
+ int32* EnemyHealthPtr = HealthProperty->ContainerPtrToValuePtr(Enemy);
+ EnemyHealth = EnemyHealthPtr;
+
+ if (EnemyBlackboard->GetValueAsBool("Sight"))
+ {
+ //bEnemyHasExtraTurn = true;
+ SwitchTurn();
+ }
+ else
+ {
+ bPlayerHasExtraTurn = true;
+ }
+
+ if (HUD->IsInViewport()) return;
+ HUD->AddToViewport();
+ EnemyActor = Enemy;
+
+ ProbertiumResource = 10;
+ EisResource = 10;
+ AzosResource = 10;
+ IroquoidResource = 10;
+
+ //Disable Character Movement
+ if (ACharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn()))
+ {
+ PlayerCharacter->DisableInput(GetWorld()->GetFirstPlayerController());
+ }
+ //Set to UI Mode Only
+ APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
+ PlayerController->SetInputMode(FInputModeUIOnly());
+ PlayerController->bShowMouseCursor = true;
+
+ FVector Direction = Enemy->GetActorLocation() - PlayerActor->GetActorLocation();
+ Direction.Normalize();
+ FRotator LookAtRotation = FRotationMatrix::MakeFromX(Direction).Rotator();
+ LookAtRotation.Pitch = -9.0f;
+ PlayerController->SetControlRotation(LookAtRotation);
+
+ //DrawDebugPoint(GetWorld(), Enemy->GetActorLocation(), 10, FColor::Red, false, 10);
+
+ CurrentComboString = "";
+ UpdateComboString(CurrentComboString);
+ RevertActionPoints();
+ UpdateActionPoints();
+ UpdateResourceBars();
+ ClearBattleLog();
+}
+
+void ATurnBaseCombatV2::EndCombat()
+{
+ bEnemyHasExtraTurn = false;
+ bPlayerHasExtraTurn = false;
+ for (UStatusEffect* StatusEffect : StatusEffects)
+ {
+ StatusEffect->OnExpiry(PlayerActor);
+ }
+
+ HUD->RemoveFromParent();
+ APawn* PlayerPawn = Cast(GetWorld()->GetFirstPlayerController()->GetPawn());
+ PlayerPawn->bUseControllerRotationYaw = true;
+ PlayerPawn->bUseControllerRotationPitch = true;
+ //Enable Character Movement
+ if (ACharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn()))
+ {
+ PlayerCharacter->EnableInput(GetWorld()->GetFirstPlayerController());
+ }
+ //Set to Game Mode Only
+ APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
+ PlayerController->SetInputMode(FInputModeGameOnly());
+ PlayerController->bShowMouseCursor = false;
+}
+
+// void ATurnBaseCombatV2::FKeyPressed()
+// {
+// PButtonOnClick();
+// }
+//
+// void ATurnBaseCombatV2::WKeyPressed()
+// {
+// EButtonOnClick();
+// }
+
+void ATurnBaseCombatV2::BeginPlay()
+{
+ Super::BeginPlay();
+
+ TArray AllCharacterActorsInScene;
+
+ UGameplayStatics::GetAllActorsOfClassWithTag(GetWorld(), AActor::StaticClass(), FName("Player"), AllCharacterActorsInScene);
+ for (AActor* Actor : AllCharacterActorsInScene)
+ {
+ PlayerActor = Cast(Actor);
+ }
+ PlayerHealth = &Cast(PlayerActor)->Health;
+
+ HUD = CreateWidget(GetWorld(), HUDWidget);
+
+ TurnIndicatorTextBlock = Cast(HUD->GetWidgetFromName("TurnIndicator"));
+ CurrentComboTextBlock = Cast(HUD->GetWidgetFromName("CurrentCombo"));
+ ActionPointsTextBlock = Cast(HUD->GetWidgetFromName("ActionPoints"));
+ BattleLogTextBlock = Cast(HUD->GetWidgetFromName("BattleLog"));
+ PlayerHealthBar = Cast(HUD->GetWidgetFromName("PlayerHealthBar"));
+ EnemyHealthBar = Cast(HUD->GetWidgetFromName("EnemyHealthBar"));
+ ProbertiumResourceBar = Cast(HUD->GetWidgetFromName("ProbertiumResourceBar"));
+ EisResourceBar = Cast(HUD->GetWidgetFromName("EisResourceBar"));
+ AzosResourceBar = Cast(HUD->GetWidgetFromName("AzosResourceBar"));
+ IroquoidResourceBar = Cast(HUD->GetWidgetFromName("IroquoidResourceBar"));
+ CastButton = Cast(HUD->GetWidgetFromName("CastButton"));
+ PButton = Cast(HUD->GetWidgetFromName("PButton"));
+ EButton = Cast(HUD->GetWidgetFromName("EButton"));
+ AButton = Cast(HUD->GetWidgetFromName("AButton"));
+ IButton = Cast(HUD->GetWidgetFromName("IButton"));
+ BackspaceButton = Cast(HUD->GetWidgetFromName("BackspaceButton"));
+ RunButton = Cast(HUD->GetWidgetFromName("RunButton"));
+ CastButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::CastButtonOnClick);
+ PButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::PButtonOnClick);
+ EButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::EButtonOnClick);
+ AButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::AButtonOnClick);
+ IButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::IButtonOnClick);
+ BackspaceButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::BackspaceButtonOnClick);
+ RunButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::RunButtonOnClick);
+}
+
+void ATurnBaseCombatV2::ExecuteCast(FString Combo)
+{
+ if (!IsValidCombo(Combo))
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Invalid Combo"));
+ for (int i = 0; i < Combo.Len(); i++)
+ {
+ if (Combo[i] == 'P')
+ {
+ ProbertiumResource += 1;
+ }
+ else if (Combo[i] == 'E')
+ {
+ EisResource += 1;
+ }
+ else if (Combo[i] == 'A')
+ {
+ AzosResource += 1;
+ }
+ else if (Combo[i] == 'I')
+ {
+ IroquoidResource += 1;
+ }
+ }
+ CurrentComboString = "";
+ UpdateComboString(CurrentComboString);
+ RevertActionPoints();
+ UpdateActionPoints();
+ UpdateResourceBars();
+ return;
+ }
+ if (IsSpecialCombo(Combo))
+ {
+ UStatusSystem* StatusSystem = Cast(PlayerActor->GetComponentByClass(UStatusSystem::StaticClass()));
+ if (Combo == "AAE")
+ {
+ UStatusEffect* TempThornsStatusEffect = NewObject(PlayerActor, ThornsStatusEffect);
+ StatusSystem->AddStatusEffect(TempThornsStatusEffect, 1, false);
+ StatusEffects.Add(TempThornsStatusEffect);
+ AddBattleLogMessage("Player Casted Thorns");
+ }
+ else if (Combo == "PPI")
+ {
+ UStatusEffect* TempDOTStatusEffect = NewObject(PlayerActor, DOTStatusEffect);
+ StatusSystem->AddStatusEffect(TempDOTStatusEffect, 1, false);
+ StatusEffects.Add(TempDOTStatusEffect);
+ AddBattleLogMessage("Player Casted DOT");
+ }
+ }
+
+ if (GunEffect)
+ {
+ const UStaticMeshComponent* GunComponent = Cast(PlayerActor->GetComponentsByTag(UPrimitiveComponent::StaticClass(), FName("Gun"))[0]);
+ const FVector GunLocationOffset = GunComponent->GetSocketTransform("Muzzle").TransformPosition(FVector(-100, 0, 0));
+ UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(), GunEffect, GunLocationOffset, PlayerActor->GetActorRotation());
+ }
+
+ CurrentComboString = "";
+ UpdateComboString(CurrentComboString);
+ RevertActionPoints();
+ UpdateActionPoints();
+
+ //Damage Calculation
+ switch (bIsPlayerTurn)
+ {
+ case true:
+ // Player Turn
+ DamageEnemy(*ValidCombos.Find(Combo));
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("Enemy Damaged %d"), *ValidCombos.Find(Combo)));
+ OnPlayerTurn.Broadcast(PlayerActor, EnemyActor);
+ break;
+ case false:
+ // Enemy Turn
+ DamagePlayer(*ValidCombos.Find(Combo));
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("Player Damaged %d"), *ValidCombos.Find(Combo)));
+ OnEnemyTurn.Broadcast(EnemyActor, PlayerActor);
+ break;
+ }
+
+ //Ends Combat if either the player or enemy is dead
+ if (*EnemyHealth <= 0)
+ {
+ EndCombat();
+ EnemyActor->Destroy();
+ return;
+ }
+ if (*PlayerHealth <= 0)
+ {
+ //EndCombat();
+ DeathScreenWidget = CreateWidget(GetWorld(), DeathScreenWidgetSubclass);
+ DeathScreenWidget->AddToViewport();
+ return;
+ }
+
+ if (!bPlayerHasExtraTurn)
+ {
+ SwitchTurn();
+ }
+ bPlayerHasExtraTurn = false;
+}
+
+void ATurnBaseCombatV2::UseActionPoint()
+{
+ ActiveActionPoints += 1;
+ UpdateActionPoints();
+}
+
+void ATurnBaseCombatV2::ReuseActionPoint()
+{
+ ActiveActionPoints -= 1;
+ UpdateActionPoints();
+}
+
+void ATurnBaseCombatV2::RevertActionPoints()
+{
+ ActiveActionPoints = 0;
+ UpdateActionPoints();
+}
+
+void ATurnBaseCombatV2::DamagePlayer(int Damage, FString DamageType)
+{
+ *PlayerHealth -= FMath::Clamp(Damage, 0, 100);
+ UpdateProgressBars();
+ AddBattleLogMessage("Player was damaged for " + FString::FromInt(Damage) + " HP by " + DamageType + ".");
+}
+
+void ATurnBaseCombatV2::DamageEnemy(int Damage, FString DamageType)
+{
+ *EnemyHealth -= FMath::Clamp(Damage, 0, 100);
+ UpdateProgressBars();
+ AddBattleLogMessage("Enemy was damaged for " + FString::FromInt(Damage) + " HP by " + DamageType + ".");
+}
+
+void ATurnBaseCombatV2::UpdateProgressBars() const
+{
+ PlayerHealthBar->SetPercent(*PlayerHealth / 100.0f);
+ EnemyHealthBar->SetPercent(*EnemyHealth / 100.0f);
+}
+
+bool ATurnBaseCombatV2::IsValidCombo(const FString Combo) const
+{
+ return ValidCombos.Contains(Combo);
+}
+
+bool ATurnBaseCombatV2::IsSpecialCombo(const FString Combo) const
+{
+ return SpecialCombos.Contains(Combo);
+}
+
+void ATurnBaseCombatV2::SwitchTurn()
+{
+ //TurnIndicatorTextBlock->SetText(FText::FromString(bIsPlayerTurn ? "Enemy Turn" : "Player Turn"));
+ //bIsPlayerTurn = !bIsPlayerTurn;
+ TurnIndicatorTextBlock->SetText(FText::FromString("Enemy Turn"));
+ ToggleButtons();
+
+ FTimerHandle UnusedHandle;
+ GetWorldTimerManager().SetTimer(UnusedHandle, this, &ATurnBaseCombatV2::EnemyTurn, 2.0f, false);
+
+ //activeActor = bIsPlayerTurn ? enemyActor : playerActor;
+}
+
+void ATurnBaseCombatV2::CastButtonOnClick()
+{
+ ExecuteCast(CurrentComboString);
+}
+
+void ATurnBaseCombatV2::PButtonOnClick()
+{
+ if (ActiveActionPoints >= DefaultActionPoints)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
+ return;
+ }
+ if (ProbertiumResource <= 0)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Probertium"));
+ return;
+ }
+ UseActionPoint();
+ CurrentComboString.AppendChar('P');
+ UpdateComboString(CurrentComboString);
+ ProbertiumResource -= 1;
+ UpdateResourceBars();
+}
+
+void ATurnBaseCombatV2::EButtonOnClick()
+{
+ if (ActiveActionPoints >= DefaultActionPoints)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
+ return;
+ }
+ if (EisResource <= 0)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Eis"));
+ return;
+ }
+ UseActionPoint();
+ CurrentComboString.AppendChar('E');
+ UpdateComboString(CurrentComboString);
+ EisResource -= 1;
+ UpdateResourceBars();
+}
+
+void ATurnBaseCombatV2::AButtonOnClick()
+{
+ if (ActiveActionPoints >= DefaultActionPoints)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
+ return;
+ }
+ if (AzosResource <= 0)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Azos"));
+ return;
+ }
+ UseActionPoint();
+ CurrentComboString.AppendChar('A');
+ UpdateComboString(CurrentComboString);
+ AzosResource -= 1;
+ UpdateResourceBars();
+}
+
+void ATurnBaseCombatV2::IButtonOnClick()
+{
+ if (ActiveActionPoints >= DefaultActionPoints)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
+ return;
+ }
+ if (IroquoidResource <= 0)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Iroquoid"));
+ return;
+ }
+ UseActionPoint();
+ CurrentComboString.AppendChar('I');
+ UpdateComboString(CurrentComboString);
+ IroquoidResource -= 1;
+ UpdateResourceBars();
+}
+
+void ATurnBaseCombatV2::BackspaceButtonOnClick()
+{
+ if (CurrentComboString.Len() <= 0)
+ {
+ GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Blank Combo"));
+ return;
+ }
+ ReuseActionPoint();
+ if (CurrentComboString.Right(1) == "P")
+ {
+ ProbertiumResource += 1;
+ }
+ else if (CurrentComboString.Right(1) == "E")
+ {
+ EisResource += 1;
+ }
+ else if (CurrentComboString.Right(1) == "A")
+ {
+ AzosResource += 1;
+ }
+ else if (CurrentComboString.Right(1) == "I")
+ {
+ IroquoidResource += 1;
+ }
+ CurrentComboString.RemoveAt(CurrentComboString.Len() - 1);
+ UpdateComboString(CurrentComboString);
+ UpdateResourceBars();
+}
+
+void ATurnBaseCombatV2::RunButtonOnClick()
+{
+ UBlackboardComponent* EnemyBlackboard = Cast(EnemyActor->GetInstigatorController())->GetBlackboardComponent();
+
+ EnemyBlackboard->SetValueAsBool("IsInCombat", false);
+ EndCombat();
+}
+
+void ATurnBaseCombatV2::UpdateComboString(FString NewCombo) const
+{
+ CurrentComboTextBlock->SetText(FText::FromString(NewCombo));
+}
+
+void ATurnBaseCombatV2::UpdateActionPoints() const
+{
+ ActionPointsTextBlock->SetText(FText::FromString(FString::FromInt(DefaultActionPoints - ActiveActionPoints)));
+}
+
+void ATurnBaseCombatV2::AddBattleLogMessage(FString Message)
+{
+ BattleLog.Append(Message + "\n");
+ UpdateBattleLog();
+}
+
+void ATurnBaseCombatV2::ClearBattleLog()
+{
+ BattleLog = "";
+}
+
+void ATurnBaseCombatV2::UpdateBattleLog()
+{
+ TArray TempArray;
+ if (const int32 LineCount = BattleLog.ParseIntoArray(TempArray, TEXT("\n"), true); LineCount > 10)
+ {
+ ClearBattleLog();
+ }
+ BattleLogTextBlock->SetText(FText::FromString(BattleLog));
+}
+
+void ATurnBaseCombatV2::UpdateResourceBars() const
+{
+ ProbertiumResourceBar->SetPercent(ProbertiumResource / 10.0f);
+ EisResourceBar->SetPercent(EisResource / 10.0f);
+ AzosResourceBar->SetPercent(AzosResource / 10.0f);
+ IroquoidResourceBar->SetPercent(IroquoidResource / 10.0f);
+}
+
+void ATurnBaseCombatV2::ToggleButtons() const
+{
+ PButton->SetIsEnabled(!PButton->GetIsEnabled());
+ EButton->SetIsEnabled(!EButton->GetIsEnabled());
+ AButton->SetIsEnabled(!AButton->GetIsEnabled());
+ IButton->SetIsEnabled(!IButton->GetIsEnabled());
+ BackspaceButton->SetIsEnabled(!BackspaceButton->GetIsEnabled());
+ CastButton->SetIsEnabled(!CastButton->GetIsEnabled());
+ RunButton->SetIsEnabled(!RunButton->GetIsEnabled());
+}
+
+void ATurnBaseCombatV2::EnemyTurn()
+{
+ DamagePlayer(10);
+ OnEnemyTurn.Broadcast(EnemyActor, PlayerActor);
+ TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn"));
+ ToggleButtons();
+}
diff --git a/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/TurnBaseCombatV2.h b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/TurnBaseCombatV2.h
new file mode 100644
index 0000000..f09dc51
--- /dev/null
+++ b/COMP250_1_2101327_AI/Source/COMP250_1_2101327_AI/TurnBasedCombatV2/TurnBaseCombatV2.h
@@ -0,0 +1,212 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "Components/Button.h"
+#include "Components/ProgressBar.h"
+#include "Components/TextBlock.h"
+#include "StatusEffect.h"
+#include "NiagaraComponent.h"
+#include "NiagaraFunctionLibrary.h"
+#include "GameFramework/GameStateBase.h"
+#include "StatusEffects/Thorns.h"
+#include "TurnBaseCombatV2.generated.h"
+
+class UNiagaraSystem;
+
+UCLASS()
+class COMP250_1_2101327_AI_API ATurnBaseCombatV2 : public AGameStateBase
+{
+ GENERATED_BODY()
+
+public:
+ ATurnBaseCombatV2();
+
+ int* EnemyHealth = nullptr;
+ float* PlayerHealth = nullptr;
+ UPROPERTY(EditDefaultsOnly)
+ int DefaultActionPoints = 3;
+ UPROPERTY(EditDefaultsOnly)
+ int ActiveActionPoints = 0;
+
+ UPROPERTY(EditDefaultsOnly)
+ int ProbertiumResource = 10;
+ UPROPERTY(EditDefaultsOnly)
+ int EisResource = 10;
+ UPROPERTY(EditDefaultsOnly)
+ int AzosResource = 10;
+ UPROPERTY(EditDefaultsOnly)
+ int IroquoidResource = 10;
+
+ UPROPERTY(EditDefaultsOnly)
+ UNiagaraSystem* GunEffect;
+
+ UPROPERTY(VisibleAnywhere)
+ AActor* PlayerActor;
+ UPROPERTY(VisibleAnywhere)
+ AActor* EnemyActor;
+ // AActor* ActiveActor;
+ UPROPERTY(BlueprintReadWrite)
+ UUserWidget* HUD;
+ /*
+ TODO:
+ Reference Player Inventory
+ */
+ UPROPERTY(EditAnywhere)
+ TSubclassOf HUDWidget;
+ UPROPERTY(EditAnywhere)
+ TMap ValidCombos =
+ {
+ {"P", 5},
+ {"PP", 15},
+ {"PPP", 20},
+ {"E", 5},
+ {"EE", 15},
+ {"EEE", 20},
+ {"A", 5},
+ {"AA", 15},
+ {"AAA", 20},
+ {"I", 5},
+ {"II", 15},
+ {"III", 20},
+ {"IA", 15},
+ {"IIA", 20},
+ {"EP", 15},
+ {"EEP", 20},
+ {"AE", 15},
+ {"AAE", 20},
+ {"PI", 15},
+ {"PPI", 20}
+ };
+ UPROPERTY(EditAnywhere)
+ TMap SpecialCombos =
+ {
+ //{"IIA", "ReduceActSpeed"},
+ //{"EEP", "AreaOfEffect"},
+ {"AAE", "Thorns"},
+ {"PPI", "DamageOverTime"}
+ };
+
+ FString BattleLog;
+
+ UFUNCTION(BlueprintCallable)
+ void StartCombat(AActor* Enemy);
+ UFUNCTION(BlueprintCallable)
+ void EndCombat();
+ // UFUNCTION(BlueprintCallable)
+ // void FKeyPressed();
+ // UFUNCTION(BlueprintCallable)
+ // void WKeyPressed();
+
+ DECLARE_EVENT_TwoParams(ATurnBaseCombatV2, FOnPlayerTurn, AActor*, AActor*);
+ DECLARE_EVENT_TwoParams(ATurnBaseCombatV2, FOnEnemyTurn, AActor*, AActor*);
+ FOnPlayerTurn OnPlayerTurn;
+ FOnEnemyTurn OnEnemyTurn;
+
+ void DamagePlayer(int Damage, FString DamageType = "unknown");
+ void DamageEnemy(int Damage, FString DamageType = "unknown");
+
+protected:
+ virtual void BeginPlay() override;
+ void ExecuteCast(FString Combo);
+ void UseActionPoint();
+ void ReuseActionPoint();
+ void RevertActionPoints();
+ void UpdateProgressBars() const;
+
+ bool bPlayerHasExtraTurn = false;
+ bool bEnemyHasExtraTurn = false;
+
+private:
+ bool IsValidCombo(FString Combo) const;
+ bool IsSpecialCombo(FString Combo) const;
+
+ UPROPERTY()
+ TSubclassOf ThornsStatusEffect;
+ UPROPERTY()
+ TSubclassOf DOTStatusEffect;
+
+ UPROPERTY()
+ TArray StatusEffects;
+
+ UPROPERTY(VisibleAnywhere)
+ bool bIsPlayerTurn = true;
+
+ UPROPERTY(VisibleAnywhere)
+ FString CurrentComboString = "";
+
+ void SwitchTurn();
+
+ UPROPERTY(VisibleAnywhere)
+ UTextBlock* TurnIndicatorTextBlock;
+ UPROPERTY(VisibleAnywhere)
+ UTextBlock* CurrentComboTextBlock;
+ UPROPERTY(VisibleAnywhere)
+ UTextBlock* BattleLogTextBlock;
+ UPROPERTY(VisibleAnywhere)
+ UTextBlock* ActionPointsTextBlock;
+
+ UPROPERTY(VisibleAnywhere)
+ UProgressBar* PlayerHealthBar;
+ UPROPERTY(VisibleAnywhere)
+ UProgressBar* EnemyHealthBar;
+
+ UPROPERTY(VisibleAnywhere)
+ UProgressBar* ProbertiumResourceBar;
+ UPROPERTY(VisibleAnywhere)
+ UProgressBar* EisResourceBar;
+ UPROPERTY(VisibleAnywhere)
+ UProgressBar* AzosResourceBar;
+ UPROPERTY(VisibleAnywhere)
+ UProgressBar* IroquoidResourceBar;
+
+ UPROPERTY(VisibleAnywhere)
+ UButton* CastButton;
+
+ UPROPERTY(VisibleAnywhere)
+ UButton* PButton;
+ UPROPERTY(VisibleAnywhere)
+ UButton* EButton;
+ UPROPERTY(VisibleAnywhere)
+ UButton* AButton;
+ UPROPERTY(VisibleAnywhere)
+ UButton* IButton;
+
+ UPROPERTY(VisibleAnywhere)
+ UButton* BackspaceButton;
+ UPROPERTY(VisibleAnywhere)
+ UButton* RunButton;
+
+ UFUNCTION()
+ void CastButtonOnClick();
+
+ UFUNCTION()
+ void PButtonOnClick();
+ UFUNCTION()
+ void EButtonOnClick();
+ UFUNCTION()
+ void AButtonOnClick();
+ UFUNCTION()
+ void IButtonOnClick();
+
+ UFUNCTION()
+ void BackspaceButtonOnClick();
+ UFUNCTION()
+ void RunButtonOnClick();
+
+ void UpdateComboString(FString NewCombo) const;
+ void UpdateActionPoints() const;
+
+ void AddBattleLogMessage(FString Message);
+ void ClearBattleLog();
+ void UpdateBattleLog();
+ void UpdateResourceBars() const;
+ void ToggleButtons() const;
+ void EnemyTurn();
+
+ UPROPERTY()
+ UUserWidget* DeathScreenWidget;
+ UPROPERTY()
+ TSubclassOf DeathScreenWidgetSubclass;
+};
diff --git a/COMP250_1_2101327_AI/readme.md b/COMP250_1_2101327_AI/readme.md
deleted file mode 100644
index aed00db..0000000
--- a/COMP250_1_2101327_AI/readme.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Introduction
-
-This is the ***ROOT*** folder for the unreal game project.
-
-_NOTE - Unreal has blur enabled by default, disable this in project settings if you don't want blur._
-
-
-
-# Adding UE5 Game Project
-
-1. Open unreal, select a template, and create the project template anywhere.
-2. Open the ***ROOT*** folder of the UE5 project you just created and copy `yourgame.uproject`, `Content`. `Config`, and `Source` into this folder.
-3. If your `yourgame.uproject` file & `Content`. `Config`, `Source` folders are in the same directory as the repositories `.gitignore` file, then your setup is correct.
-
-Once you've completed the above steps you're ready to open the project and start working.
-
-
-
-# Opening The Project: For Programmers
-
-If you're a programmer and plan on doing work in C++ you should right click the `yourgame.uproject` file and select the `Generate Visual Studio project files` option. When this is complete double click the `yourgame.sln` file and run the game from Visual Studio by clicking `Local Windows Debugger`. Whenever you code in C++ you should close UE5 and recompile it from VS.
-
-If you are not doing anything in C++, then you can open the project straight from double clicking `yourgame.uproject`. Make sure you click yes on the prompt asking to compile. UE5 will take awhile to open because it's compiling C++ binaries in the background.
-
-If UE5 is bing weird delete all the cache files/folders & generated files/folders, then lauch it from Visual Studio so it's forced to compile everything correctly and you will catch any compiler bugs if anything is wrong.
-
-
-
-# Common Visual Studio/C++ Problems
-
-### Too Much Unreal
-
-If you are trying to run UE5 from Visual Studio, then close any other UE5 executable windows you have open. If Unreal is already running when you launch it from Visual Studio then it will sometimes prevent Visual Studio from being able to correctly compile your C++ files, which results in a compiler error.
-
-To fix this close all open instances of Unreal Engine. Once you've done that everything will be fine and you should be able to run Unreal from Visual Studio.
-
-
-### I'm getting an error with the build.bat in the Visual Studio error console
-
-This happens when certain executables are already running in the background and haven't shutdown when they're meant to. To fix this open task manager and close `HUB for UE5 runtime traces...` and close every instance of `Runtime Broker` you can find.
-
-Once you've done this, Visual Studio will work again and you can compile code.
-
-
-
-# Fixing UE5 Setup
-
-### dotnet is not recognized as an internal or external command
-
-If you get an error similar to this one when generating visual studio project files or opening the project for the first time, it's because `.NET 6` is not installed or its environment path is not set.
-
-To fix this locate `C:\program files\dotnet`, and delete the `dotnet` folder if it exists. If it doesn't exist, then don't do anything.
-
-Next download the .NET 6 SDK ([.NET 6 download here](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)) and install it. _(do not download `ASP.NET Core Runtime`, `.NET Desktop Runtime`, `.NET Runtime`, or any other SDK - just the plain `.NET 6` SDK that has everything included)_
-
-This will fix the dotnet error.
-
-### I don't know how to setup VS2022 for Unreal Engine 5
-
-Follow this guide: [Setting Up Visual Studio Environment for C++](https://docs.unrealengine.com/5.1/en-US/setting-up-visual-studio-development-environment-for-cplusplus-projects-in-unreal-engine/)
\ No newline at end of file
diff --git a/readme.md b/readme.md
index c8782c0..f9e003d 100644
--- a/readme.md
+++ b/readme.md
@@ -1,13 +1,53 @@
+# COMP250 Project Proposal
-# WARNING!!!
+## Computing Artifact Outline
-Do not put in development or completed project assets in this repository. When you import assets into unreal they're taken into unreal and changed into `.uasset` files. Because of this it's wasteful to put the original development assets in the game repository. Doing so bloats the project and increases cloning times of the project for everyone.
+The computing artifact I am proposing is a combat artificial intelligence attached to an enemy non-player character for a small turn based strategy game with the focus of resource management and combo building. In this game you have a limited set of resources that can be used to build combos to attack an opponent and defend yourself. Combos vary in resource costs and which resource is required for it to be cast. To win you must defeat the opponent by reducing their health to 0.
+The combat artificial intelligence must be able to find the optimal set of combos and actions to defeat their opponent.
-Instead you should have another repo that uses the [art-lfs-repo](https://github.falmouth.ac.uk/Games-Academy/art-lfs-repo) template. This is where you put your development assets like your models and textures while working on them, including your completed ones. Then when you're done, you import them into Unreal Engine (and UE5 will store the files internally in its own format).
+## Artifact Specialism
+This computing artifact is suitable for the specified specialism of Artificial Intelligence as it falls under the specified contract of non-player character behaviour. The computing artifact will apply a goal-directed behaviour system. The combat artificial intelligence will be using the Goal Oriented Action Planning (GOAP) (Suyikno and Setiawan 2019) artificial intelligence to guide and action the resource management and combo build to aim for the goal of eliminating the player. GOAP is a form of artificial intelligence planning system that is used in computer games to generate intelligent behaviour for non-player characters (NPCs). It operates by identifying a goal state and a set of actions that can be taken to achieve the goal, and then use search algorithms such as Depth First Search (DFS) or Breadth First Search (BFS) against a tree to find the most cost effective plan that will achieve the goal by executing the available actions in the generated order. (Brent Owens 2014)
+## Potential Applications
-# UE5 Stucture & Organisation
+A combat artificial intelligence can use GOAP to become more adaptable and intelligent in its decision-making, which makes it a useful tool for game designers who want to develop entertaining and challenging gameplay. Combat can become more strategic and sophisticated with the help of GOAP providing players with a more immersive gaming experience.
+
+This artificial intelligence is not only limited to resource management and combo-building features if more parameters are included in the GOAP system for example weather conditions, or stealth conditions. The artificial intelligence can take these into account when deciding what actions to take. This can be used in a stealth game where the artificial intelligence must sneak past enemies or in a survival game where the artificial intelligence must avoid the weather conditions. (Mitchell 2015)
+
+## Existing Solutions
+
+Current existing solutions using the Goal Oriented Action Planning artificial intelligence is the game F.E.A.R. (2005) (Monolith Productions 2005).
+GOAP was originally designed for F.E.A.R, an example of actions to complete their goals that were included in their artificial intelligence:
+
+* Moving into a position in the world.
+* Playing an animation.
+* Interacting with a smart object (an item in the world that artificial intelligence characters can interact with) (AIandGames 2020)
+
+Another example of a project using the Goal Oriented Action Planning artificial intelligence is a Third Year Undergraduate Dissertation Project called StarPlanner by Panagiotis Peikidis to play the game StarCraft. (Peikidis 2010)
+
+Both of these projects use the Goal Oriented Action Planning artificial intelligence to plan and execute actions to achieve a goal or goals. The main goal in F.E.A.R. is to kill the player and the goal in StarPlanner is to win the game. These projects convey the effectiveness of the Goal Oriented Action Planning artificial intelligence in a game environment in a combat setting.
+
+## Development Plan & Scope
+
+The development plan for this computing artifact will consist of 6 weeks of development split into 5 milestones. The first milestone will be to research and understand the Goal Oriented Action Planning artificial intelligence and how it can be applied to a combat artificial intelligence and to decide which search algorithm will be the most optimal for this specific case. The second milestone will be to build the game. The third milestone will be to implement the resource management and combo-building features into the combat artificial intelligence including the costs of each action. The fourth milestone will be to test the combat artificial intelligence and make any necessary changes by adjusting the costs. The fifth milestone will be to polish the combat artificial intelligence, make any final changes and bug fixes.
+
+## Practiced Based Research
+
+This constitutes as practice based research as it is a project in which will analyze artificial intelligence systems and apply them. In this case finite state machines and behaviour trees. The project will compare the feasibility of these systems and the effectiveness of the Goal Oriented Action Planning artificial intelligence and apply these techniques in a game environment.
+
+*Word Count: 786*
+## References
+
+AIANDGAMES. 2020. ÔÇÿBuilding the AI of F.E.A.R. With Goal Oriented Action Planning, AI and GamesÔÇÖ. AI and Games [online]. Available at: https://www.aiandgames.com/2020/05/06/ai-101-goap-fear/.
+
+BRENT OWENS, Brent. 2014. ÔÇÿGoal Oriented Action Planning for a Smarter AIÔÇÖ. Game Development Envato Tuts+ [online]. Available at: https://gamedevelopment.tutsplus.com/tutorials/goal-oriented-action-planning-for-a-smarter-ai--cms-20793.
+
+MITCHELL, Jared. 2015. ÔÇÿGoal-Oriented Action Planning ResearchÔÇÖ. Jared Mitchell [online]. Available at: https://jaredemitchell.com/goal-oriented-action-planning-research/.
+
+MONOLITH PRODUCTIONS. 2005. ÔÇÿF.E.A.R.ÔÇÖ.
+
+PEIKIDIS, Panagiotis. 2010. ÔÇÿPanagiotis Peikidis - 3rd Year ProjectÔÇÖ. pekalicious.github.io [online]. Available at: https://pekalicious.github.io/StarPlanner/ [accessed 5 Feb 2023].
+
+SUYIKNO, D A and A SETIAWAN. 2019. ÔÇÿFeasible NPC Hiding Behaviour Using Goal Oriented Action Planning in Case of HideandSeek 3D Game SimulationÔÇÖ. In 2019 Fourth International Conference on Informatics and Computing (ICIC). 1ÔÇô6.
-1. [UE5 Directory Structure](https://docs.unrealengine.com/5.1/en-US/unreal-engine-directory-structure/)
-2. [UE5 Asset Naming Conventions](https://docs.unrealengine.com/5.1/en-US/recommended-asset-naming-conventions-in-unreal-engine-projects/)