diff --git a/source/core/assets/configs/tower.json b/source/core/assets/configs/tower.json index 4d1daa23c..907105301 100644 --- a/source/core/assets/configs/tower.json +++ b/source/core/assets/configs/tower.json @@ -2,51 +2,51 @@ "income": { "health": 10, "baseAttack": 0, - "cost": 10 + "cost": 100 }, "wall": { "health": 300, "baseAttack": 0, - "cost": 45 + "cost": 200 }, "TNTTower": { "health": 10, "baseAttack": 5, - "cost": 30 + "cost": 50 }, "weapon": { "health": 75, "baseAttack": 15, - "cost": 15 + "cost": 50 }, "DroidTower": { "health": 100, "baseAttack": 25, - "cost": 45 + "cost": 300 }, "fireTower": { "health": 100, "baseAttack": 25, - "cost": 45 + "cost": 300 }, "stunTower": { "health": 100, "baseAttack": 25, - "cost": 45 + "cost": 500 }, "fireworksTower": { "health": 125, "baseAttack": 45, - "cost": 70 + "cost": 500 }, "pierceTower": { "health": 125, "baseAttack": 45, - "cost": 70 + "cost": 500 }, "ricochetTower": { "health": 125, "baseAttack": 45, - "cost": 70 + "cost": 500 } } \ No newline at end of file diff --git a/source/core/assets/images/HelpScreen/Demonbosshelp.png b/source/core/assets/images/HelpScreen/Demonbosshelp.png new file mode 100644 index 000000000..502a41977 Binary files /dev/null and b/source/core/assets/images/HelpScreen/Demonbosshelp.png differ diff --git a/source/core/assets/images/HelpScreen/Dragonknighthelp.png b/source/core/assets/images/HelpScreen/Dragonknighthelp.png new file mode 100644 index 000000000..92594af03 Binary files /dev/null and b/source/core/assets/images/HelpScreen/Dragonknighthelp.png differ diff --git a/source/core/assets/images/HelpScreen/Econ.png b/source/core/assets/images/HelpScreen/Econ.png new file mode 100644 index 000000000..299bc7c22 Binary files /dev/null and b/source/core/assets/images/HelpScreen/Econ.png differ diff --git a/source/core/assets/images/HelpScreen/Engineer.png b/source/core/assets/images/HelpScreen/Engineer.png new file mode 100644 index 000000000..7bcb61922 Binary files /dev/null and b/source/core/assets/images/HelpScreen/Engineer.png differ diff --git a/source/core/assets/images/HelpScreen/Firewormhelp.png b/source/core/assets/images/HelpScreen/Firewormhelp.png new file mode 100644 index 000000000..1b1fb1be9 Binary files /dev/null and b/source/core/assets/images/HelpScreen/Firewormhelp.png differ diff --git a/source/core/assets/images/HelpScreen/HTP.png b/source/core/assets/images/HelpScreen/HTP.png new file mode 100644 index 000000000..fafc6b262 Binary files /dev/null and b/source/core/assets/images/HelpScreen/HTP.png differ diff --git a/source/core/assets/images/HelpScreen/IceBosshelp.png b/source/core/assets/images/HelpScreen/IceBosshelp.png new file mode 100644 index 000000000..af09d4c92 Binary files /dev/null and b/source/core/assets/images/HelpScreen/IceBosshelp.png differ diff --git a/source/core/assets/images/HelpScreen/Mob.png b/source/core/assets/images/HelpScreen/Mob.png new file mode 100644 index 000000000..a0dfa6fda Binary files /dev/null and b/source/core/assets/images/HelpScreen/Mob.png differ diff --git a/source/core/assets/images/HelpScreen/Patrickbosshelp.png b/source/core/assets/images/HelpScreen/Patrickbosshelp.png new file mode 100644 index 000000000..d7d342e78 Binary files /dev/null and b/source/core/assets/images/HelpScreen/Patrickbosshelp.png differ diff --git a/source/core/assets/images/HelpScreen/Skeletonhelp.png b/source/core/assets/images/HelpScreen/Skeletonhelp.png new file mode 100644 index 000000000..258c6f730 Binary files /dev/null and b/source/core/assets/images/HelpScreen/Skeletonhelp.png differ diff --git a/source/core/assets/images/HelpScreen/Turret.png b/source/core/assets/images/HelpScreen/Turret.png new file mode 100644 index 000000000..f8be39f9b Binary files /dev/null and b/source/core/assets/images/HelpScreen/Turret.png differ diff --git a/source/core/assets/images/HelpScreen/WaterQueenhelp.png b/source/core/assets/images/HelpScreen/WaterQueenhelp.png new file mode 100644 index 000000000..1481b12c0 Binary files /dev/null and b/source/core/assets/images/HelpScreen/WaterQueenhelp.png differ diff --git a/source/core/assets/images/HelpScreen/Waterslimehelp.png b/source/core/assets/images/HelpScreen/Waterslimehelp.png new file mode 100644 index 000000000..53884cbac Binary files /dev/null and b/source/core/assets/images/HelpScreen/Waterslimehelp.png differ diff --git a/source/core/assets/images/HelpScreen/Wizardhelp.png b/source/core/assets/images/HelpScreen/Wizardhelp.png new file mode 100644 index 000000000..ab5be4a71 Binary files /dev/null and b/source/core/assets/images/HelpScreen/Wizardhelp.png differ diff --git a/source/core/assets/images/HelpScreen/hs.jpg b/source/core/assets/images/HelpScreen/hs.jpg new file mode 100644 index 000000000..44eb11456 Binary files /dev/null and b/source/core/assets/images/HelpScreen/hs.jpg differ diff --git a/source/core/assets/images/LoadingScreen.png b/source/core/assets/images/LoadingScreen.png new file mode 100644 index 000000000..bfae39510 Binary files /dev/null and b/source/core/assets/images/LoadingScreen.png differ diff --git a/source/core/assets/images/background/main_menu/main_menu_bg.png b/source/core/assets/images/background/main_menu/main_menu_bg.png index 8fc9e4556..54e011d2a 100644 Binary files a/source/core/assets/images/background/main_menu/main_menu_bg.png and b/source/core/assets/images/background/main_menu/main_menu_bg.png differ diff --git a/source/core/assets/images/background/settings/settings_bg.png b/source/core/assets/images/background/settings/settings_bg.png index f0a0c5064..febd8eb6f 100644 Binary files a/source/core/assets/images/background/settings/settings_bg.png and b/source/core/assets/images/background/settings/settings_bg.png differ diff --git a/source/core/assets/images/mobs/skeleton.atlas b/source/core/assets/images/mobs/skeleton.atlas index f0117d879..9e1c78e17 100644 --- a/source/core/assets/images/mobs/skeleton.atlas +++ b/source/core/assets/images/mobs/skeleton.atlas @@ -69,7 +69,7 @@ skeleton_attack index: -1 skeleton_attack rotate: false - xy: 514, 2 + xy: 578, 52 size: 62, 48 orig: 62, 48 offset: 0, 0 @@ -83,7 +83,7 @@ skeleton_attack index: -1 skeleton_attack rotate: false - xy: 770, 2 + xy: 834, 52 size: 62, 48 orig: 62, 48 offset: 0, 0 @@ -95,41 +95,6 @@ skeleton_attack orig: 62, 48 offset: 0, 0 index: -1 -skeleton_death - rotate: false - xy: 1026, 2 - size: 62, 48 - orig: 62, 48 - offset: 0, 0 - index: -1 -skeleton_death - rotate: false - xy: 66, 52 - size: 62, 48 - orig: 62, 48 - offset: 0, 0 - index: -1 -skeleton_death - rotate: false - xy: 834, 52 - size: 62, 48 - orig: 62, 48 - offset: 0, 0 - index: -1 -skeleton_death - rotate: false - xy: 1154, 55 - size: 62, 45 - orig: 62, 45 - offset: 0, 0 - index: -1 -skeleton_death - rotate: false - xy: 578, 2 - size: 62, 48 - orig: 62, 48 - offset: 0, 0 - index: -1 skeleton_death rotate: false xy: 194, 52 @@ -188,7 +153,7 @@ skeleton_walk index: -1 skeleton_walk rotate: false - xy: 514, 52 + xy: 514, 2 size: 62, 48 orig: 62, 48 offset: 0, 0 @@ -202,7 +167,7 @@ skeleton_walk index: -1 skeleton_walk rotate: false - xy: 770, 52 + xy: 770, 2 size: 62, 48 orig: 62, 48 offset: 0, 0 @@ -237,21 +202,21 @@ skeleton_walk index: -1 skeleton_walk rotate: false - xy: 578, 52 + xy: 514, 52 size: 62, 48 orig: 62, 48 offset: 0, 0 index: -1 skeleton_walk rotate: false - xy: 130, 2 + xy: 66, 52 size: 62, 48 orig: 62, 48 offset: 0, 0 index: -1 skeleton_walk rotate: false - xy: 834, 2 + xy: 770, 52 size: 62, 48 orig: 62, 48 offset: 0, 0 diff --git a/source/core/assets/images/mobs/skeleton.png b/source/core/assets/images/mobs/skeleton.png index cbcbd1ed1..9d75bb066 100644 Binary files a/source/core/assets/images/mobs/skeleton.png and b/source/core/assets/images/mobs/skeleton.png differ diff --git a/source/core/assets/images/ui/Screen/Losing.png b/source/core/assets/images/ui/Screen/Losing.png new file mode 100644 index 000000000..133a500f8 Binary files /dev/null and b/source/core/assets/images/ui/Screen/Losing.png differ diff --git a/source/core/assets/images/ui/Screen/Nextlevel.png b/source/core/assets/images/ui/Screen/Nextlevel.png new file mode 100644 index 000000000..424016fa4 Binary files /dev/null and b/source/core/assets/images/ui/Screen/Nextlevel.png differ diff --git a/source/core/assets/images/ui/Screen/WinningScreen.png b/source/core/assets/images/ui/Screen/WinningScreen.png new file mode 100644 index 000000000..bd977c7a8 Binary files /dev/null and b/source/core/assets/images/ui/Screen/WinningScreen.png differ diff --git a/source/core/assets/images/ui/Sprites/UI_Glass_Arrow_Large_01a - Copy.png b/source/core/assets/images/ui/Sprites/UI_Glass_Arrow_Large_01a - Copy.png new file mode 100644 index 000000000..6f8775172 Binary files /dev/null and b/source/core/assets/images/ui/Sprites/UI_Glass_Arrow_Large_01a - Copy.png differ diff --git a/source/core/assets/images/ui/buttons/glass.atlas b/source/core/assets/images/ui/buttons/glass.atlas index 4a7987fe5..3e095821f 100644 --- a/source/core/assets/images/ui/buttons/glass.atlas +++ b/source/core/assets/images/ui/buttons/glass.atlas @@ -6,693 +6,714 @@ filter: Linear, Linear repeat: none dot_gothic_16 rotate: false - xy: 1, 989 + xy: 1, 979 size: 505, 107 orig: 505, 107 offset: 0, 0 index: -1 dot_gothic_32 rotate: false - xy: 509, 1527 + xy: 509, 1517 size: 505, 240 orig: 505, 240 offset: 0, 0 index: -1 Emulogic-zrEw rotate: false - xy: 1, 763 + xy: 1, 753 size: 505, 224 orig: 505, 224 offset: 0, 0 index: -1 determination_mono_18 rotate: false - xy: 1525, 1974 + xy: 1525, 1964 size: 505, 64 orig: 505, 64 offset: 0, 0 index: -1 determination_mono_18_bold rotate: false - xy: 509, 1769 + xy: 509, 1759 size: 506, 106 orig: 506, 106 offset: 0, 0 index: -1 determination_mono_22 rotate: false - xy: 1017, 1949 + xy: 1017, 1939 size: 506, 89 orig: 506, 89 offset: 0, 0 index: -1 determination_mono_32 rotate: false - xy: 509, 1380 + xy: 509, 1370 size: 503, 145 orig: 503, 145 offset: 0, 0 index: -1 determination_mono_48_title rotate: false - xy: 1, 1642 + xy: 1, 1632 size: 506, 396 orig: 506, 396 offset: 0, 0 index: -1 emulogic_18 rotate: false - xy: 1017, 1850 + xy: 1017, 1840 size: 505, 97 orig: 505, 97 offset: 0, 0 index: -1 game_paused_24 rotate: false - xy: 1, 1587 + xy: 1, 1577 size: 506, 53 orig: 506, 53 offset: 0, 0 index: -1 game_paused_title rotate: false - xy: 1, 657 + xy: 1, 647 size: 502, 104 orig: 502, 104 offset: 0, 0 index: -1 glitch_24 rotate: false - xy: 509, 1877 + xy: 509, 1867 size: 506, 161 orig: 506, 161 offset: 0, 0 index: -1 glitch_title rotate: false - xy: 1, 1098 + xy: 1, 1088 size: 506, 487 orig: 506, 487 offset: 0, 0 index: -1 UI_Glass_Arrow_Large_01a rotate: false - xy: 965, 1346 + xy: 965, 1336 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Arrow_Medium_01a rotate: false - xy: 99, 167 + xy: 457, 613 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Arrow_Small_01a rotate: false - xy: 251, 319 + xy: 403, 461 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Banner_01a rotate: false - xy: 1017, 1816 + xy: 1017, 1806 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Banner_01b rotate: false - xy: 403, 589 + xy: 99, 5 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Textfield_01a rotate: false - xy: 403, 589 + xy: 99, 5 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a1 rotate: false - xy: 509, 1194 + xy: 509, 1184 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a3 rotate: false - xy: 509, 1194 + xy: 509, 1184 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a2 rotate: false - xy: 305, 623 + xy: 305, 461 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a2 rotate: false - xy: 305, 623 + xy: 305, 461 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a3 rotate: false - xy: 1, 167 + xy: 1, 5 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a1 rotate: false - xy: 1, 167 + xy: 1, 5 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a4 rotate: false - xy: 153, 319 + xy: 153, 157 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a1 rotate: false - xy: 1017, 1782 + xy: 1017, 1772 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a2 rotate: false - xy: 1115, 1816 + xy: 1115, 1806 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a3 rotate: false - xy: 509, 1160 + xy: 509, 1150 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a4 rotate: false - xy: 607, 1194 + xy: 607, 1184 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a4 rotate: false - xy: 607, 1194 + xy: 607, 1184 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a1 rotate: false - xy: 403, 623 + xy: 1115, 1772 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a3 rotate: false - xy: 403, 623 + xy: 1115, 1772 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a2 rotate: false - xy: 1115, 1782 + xy: 1213, 1806 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a2 rotate: false - xy: 1115, 1782 + xy: 1213, 1806 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a3 rotate: false - xy: 1213, 1816 + xy: 509, 1116 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a1 rotate: false - xy: 1213, 1816 + xy: 509, 1116 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a4 rotate: false - xy: 509, 1126 + xy: 607, 1150 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a1 rotate: false - xy: 607, 1160 + xy: 705, 1184 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a2 rotate: false - xy: 705, 1194 + xy: 305, 295 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a3 rotate: false - xy: 305, 555 + xy: 1181, 1772 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a4 rotate: false - xy: 1, 35 + xy: 1279, 1806 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a4 rotate: false - xy: 1, 35 + xy: 1279, 1806 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a1 _1 rotate: false - xy: 469, 623 + xy: 251, 157 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a3 rotate: false - xy: 469, 623 + xy: 251, 157 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a2_2 rotate: false - xy: 1181, 1782 + xy: 575, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a2 rotate: false - xy: 1181, 1782 + xy: 575, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a3_3 rotate: false - xy: 1279, 1816 + xy: 673, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a1 rotate: false - xy: 1279, 1816 + xy: 673, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a4_4 rotate: false - xy: 575, 1126 + xy: 771, 1184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a1_ rotate: false - xy: 673, 1160 + xy: 305, 261 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a2 rotate: false - xy: 771, 1194 + xy: 1247, 1772 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a3 rotate: false - xy: 305, 521 + xy: 1345, 1806 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a4 rotate: false - xy: 371, 555 + xy: 965, 1302 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a4 rotate: false - xy: 371, 555 + xy: 965, 1302 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Large_01a rotate: false - xy: 1, 1 + xy: 457, 579 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Medium_01a rotate: false - xy: 965, 1312 + xy: 403, 427 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Small_01a rotate: false - xy: 99, 133 + xy: 251, 123 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Large_01a rotate: false - xy: 251, 285 + xy: 609, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Medium_01a rotate: false - xy: 437, 589 + xy: 707, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Small_01a rotate: false - xy: 1215, 1782 + xy: 805, 1184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Dropdown_01a rotate: false - xy: 1313, 1816 + xy: 305, 227 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Dropdown_Handle_01a rotate: false - xy: 609, 1126 + xy: 1281, 1772 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Fillbar_01a rotate: false - xy: 707, 1160 + xy: 1379, 1806 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Fillbar_Filler_01a rotate: false - xy: 805, 1194 + xy: 965, 1268 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Horizontal_01a rotate: false - xy: 305, 589 + xy: 305, 427 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Inward_01a rotate: false - xy: 1, 69 + xy: 153, 59 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 UI_Glass_Frame_Lite_01a rotate: false - xy: 305, 487 + xy: 457, 545 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Standard_01a rotate: false - xy: 153, 221 + xy: 305, 329 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 UI_Glass_Frame_Vertical_01a rotate: false - xy: 305, 389 + xy: 403, 329 size: 32, 96 orig: 32, 96 offset: 0, 0 index: -1 UI_Glass_Minus_Large_01a rotate: false - xy: 339, 521 + xy: 371, 295 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Minus_Medium_01a rotate: false - xy: 405, 555 + xy: 339, 261 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Minus_Small_01a rotate: false - xy: 965, 1278 + xy: 251, 89 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Large_01a rotate: false - xy: 99, 99 + xy: 643, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Medium_01a rotate: false - xy: 251, 251 + xy: 741, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Small_01a rotate: false - xy: 1249, 1782 + xy: 839, 1184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Scrollbar_01a rotate: false - xy: 1347, 1816 + xy: 305, 193 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Scrollbar_Handle_01a rotate: false - xy: 643, 1126 + xy: 1315, 1772 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a1 rotate: false - xy: 741, 1160 + xy: 1413, 1806 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a2 rotate: false - xy: 839, 1194 + xy: 965, 1234 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a4 rotate: false - xy: 839, 1194 + xy: 965, 1234 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a3 rotate: false - xy: 305, 355 + xy: 457, 511 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_01a rotate: false - xy: 339, 487 + xy: 339, 227 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_Filler_01a rotate: false - xy: 373, 521 + xy: 677, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_Handle_01a rotate: false - xy: 965, 1244 + xy: 775, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Available_01a rotate: false - xy: 1283, 1782 + xy: 873, 1184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Selected_01a rotate: false - xy: 1381, 1816 + xy: 1349, 1772 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Unavailable_01a rotate: false - xy: 677, 1126 + xy: 1447, 1806 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Bar_01a rotate: false - xy: 775, 1160 + xy: 339, 193 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Cover_01a rotate: false - xy: 873, 1194 + xy: 711, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Handle_01a rotate: false - xy: 339, 453 + xy: 809, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 Weapon-Tower-Default rotate: false - xy: 153, 353 + xy: 153, 343 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 droid-tower-default rotate: false - xy: 509, 1228 + xy: 509, 1218 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 fire-tower-default rotate: false - xy: 1, 505 + xy: 1, 495 + size: 150, 150 + orig: 150, 150 + offset: 0, 0 + index: -1 +firework-tower-default + rotate: false + xy: 153, 191 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 imageedit_2_8132799771 rotate: false - xy: 661, 1228 + xy: 661, 1218 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 mine-tower-default rotate: false - xy: 1, 353 + xy: 1, 343 + size: 150, 150 + orig: 150, 150 + offset: 0, 0 + index: -1 +pierce-tower-default + rotate: false + xy: 305, 495 + size: 150, 150 + orig: 150, 150 + offset: 0, 0 + index: -1 +ricochet-tower-default + rotate: false + xy: 1, 39 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 stun-tower-default rotate: false - xy: 153, 505 + xy: 153, 495 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 tnt-tower-default rotate: false - xy: 813, 1228 + xy: 813, 1218 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 wall-tower-default rotate: false - xy: 1, 201 + xy: 1, 191 size: 150, 150 orig: 150, 150 offset: 0, 0 diff --git a/source/core/assets/images/ui/buttons/glass.json b/source/core/assets/images/ui/buttons/glass.json index 8637af19f..7e4dc5eb1 100644 --- a/source/core/assets/images/ui/buttons/glass.json +++ b/source/core/assets/images/ui/buttons/glass.json @@ -301,6 +301,87 @@ com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable: { a: 1 } } + pierce_tower_selected: { + name: pierce-tower-default + color: { + r: 0 + g: 0.74509805 + b: 0.003921569 + a: 1 + } + } + ricochet_tower_selected: { + name: ricochet-tower-default + color: { + r: 0 + g: 0.74509805 + b: 0.003921569 + a: 1 + } + } + firework_tower_selected: { + name: firework-tower-default + color: { + r: 0 + g: 0.74509805 + b: 0.003921569 + a: 1 + } + } + pierce_tower_disabled: { + name: pierce-tower-default + color: { + r: 0.8156863 + g: 0 + b: 0 + a: 1 + } + } + ricochet_tower_disabled: { + name: ricochet-tower-default + color: { + r: 0.8156863 + g: 0 + b: 0 + a: 1 + } + } + firework_tower_disabled: { + name: firework-tower-default + color: { + r: 0.8156863 + g: 0 + b: 0 + a: 1 + } + } + pierce_tower_over: { + name: pierce-tower-default + color: { + r: 0 + g: 0.9137255 + b: 0.9843137 + a: 1 + } + } + ricochet_tower_over: { + name: ricochet-tower-default + color: { + r: 0 + g: 0.9137255 + b: 0.9843137 + a: 1 + } + } + firework_tower_over: { + name: firework-tower-default + color: { + r: 0 + g: 0.9137255 + b: 0.9843137 + a: 1 + } + } } com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle: { default: { @@ -396,6 +477,33 @@ com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle: { imageCheckedDown: mine_tower_down imageCheckedOver: mine_tower_over } + pierce_tower: { + imageUp: pierce-tower-default + imageDown: pierce_tower_selected + imageOver: pierce_tower_over + imageDisabled: pierce_tower_disabled + imageChecked: pierce_tower_selected + imageCheckedDown: pierce_tower_selected + imageCheckedOver: pierce_tower_over + } + ricochet_tower: { + imageUp: ricochet-tower-default + imageDown: ricochet_tower_selected + imageOver: ricochet_tower_over + imageDisabled: ricochet_tower_disabled + imageChecked: ricochet_tower_selected + imageCheckedDown: ricochet_tower_selected + imageCheckedOver: ricochet_tower_over + } + fireworks_tower: { + imageUp: firework-tower-default + imageDown: firework_tower_selected + imageOver: firework_tower_over + imageDisabled: firework_tower_disabled + imageChecked: firework_tower_selected + imageCheckedDown: firework_tower_selected + imageCheckedOver: firework_tower_over + } } com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: { default: { diff --git a/source/core/assets/images/ui/buttons/glass.png b/source/core/assets/images/ui/buttons/glass.png index 57c85ace2..d0a06883c 100644 Binary files a/source/core/assets/images/ui/buttons/glass.png and b/source/core/assets/images/ui/buttons/glass.png differ diff --git a/source/core/assets/images/ui/game screen/1 earth before.png b/source/core/assets/images/ui/game screen/1 earth before.png index c4233d125..1312aeb97 100644 Binary files a/source/core/assets/images/ui/game screen/1 earth before.png and b/source/core/assets/images/ui/game screen/1 earth before.png differ diff --git a/source/core/assets/images/ui/game screen/1.1 earth before.png b/source/core/assets/images/ui/game screen/1.1 earth before.png index 5bed55ad9..0e58a9b27 100644 Binary files a/source/core/assets/images/ui/game screen/1.1 earth before.png and b/source/core/assets/images/ui/game screen/1.1 earth before.png differ diff --git a/source/core/assets/images/ui/game screen/2.0 earth dying.png b/source/core/assets/images/ui/game screen/2.0 earth dying.png index 162af4008..86127efd1 100644 Binary files a/source/core/assets/images/ui/game screen/2.0 earth dying.png and b/source/core/assets/images/ui/game screen/2.0 earth dying.png differ diff --git a/source/core/assets/images/ui/game screen/2.1 earth dying.png b/source/core/assets/images/ui/game screen/2.1 earth dying.png index c2e54ef5c..e6f0f8328 100644 Binary files a/source/core/assets/images/ui/game screen/2.1 earth dying.png and b/source/core/assets/images/ui/game screen/2.1 earth dying.png differ diff --git a/source/core/assets/images/ui/game screen/3. meeting.png b/source/core/assets/images/ui/game screen/3. meeting.png index e91965704..a7b89cdbc 100644 Binary files a/source/core/assets/images/ui/game screen/3. meeting.png and b/source/core/assets/images/ui/game screen/3. meeting.png differ diff --git a/source/core/assets/images/ui/game screen/3.1 meeting turret.png b/source/core/assets/images/ui/game screen/3.1 meeting turret.png index 6669cedb4..94793be5d 100644 Binary files a/source/core/assets/images/ui/game screen/3.1 meeting turret.png and b/source/core/assets/images/ui/game screen/3.1 meeting turret.png differ diff --git a/source/core/assets/images/ui/game screen/4.0 spaceship built.png b/source/core/assets/images/ui/game screen/4.0 spaceship built.png index 0baad28ac..ec496ffdb 100644 Binary files a/source/core/assets/images/ui/game screen/4.0 spaceship built.png and b/source/core/assets/images/ui/game screen/4.0 spaceship built.png differ diff --git a/source/core/assets/images/ui/game screen/4.1 spaceship leaving.png b/source/core/assets/images/ui/game screen/4.1 spaceship leaving.png index 10761bfb8..190ad6288 100644 Binary files a/source/core/assets/images/ui/game screen/4.1 spaceship leaving.png and b/source/core/assets/images/ui/game screen/4.1 spaceship leaving.png differ diff --git a/source/core/assets/images/ui/game screen/5 arrival.png b/source/core/assets/images/ui/game screen/5 arrival.png index 31369d500..15cd7697c 100644 Binary files a/source/core/assets/images/ui/game screen/5 arrival.png and b/source/core/assets/images/ui/game screen/5 arrival.png differ diff --git a/source/core/assets/images/ui/game screen/5.1 arrival.png b/source/core/assets/images/ui/game screen/5.1 arrival.png index f718a06f8..ec393bc53 100644 Binary files a/source/core/assets/images/ui/game screen/5.1 arrival.png and b/source/core/assets/images/ui/game screen/5.1 arrival.png differ diff --git a/source/core/assets/images/ui/game screen/6.0 survey.png b/source/core/assets/images/ui/game screen/6.0 survey.png index ecce5abc5..bf328c7f6 100644 Binary files a/source/core/assets/images/ui/game screen/6.0 survey.png and b/source/core/assets/images/ui/game screen/6.0 survey.png differ diff --git a/source/core/assets/images/ui/game screen/6.1 survey.png b/source/core/assets/images/ui/game screen/6.1 survey.png index 22606d09e..56924bc69 100644 Binary files a/source/core/assets/images/ui/game screen/6.1 survey.png and b/source/core/assets/images/ui/game screen/6.1 survey.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/1.png b/source/core/assets/planets/Barren_or_Moon_bw/2/1.png new file mode 100644 index 000000000..83b146773 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/1.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/10.png b/source/core/assets/planets/Barren_or_Moon_bw/2/10.png new file mode 100644 index 000000000..38c48d3f9 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/10.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/11.png b/source/core/assets/planets/Barren_or_Moon_bw/2/11.png new file mode 100644 index 000000000..95cf8ab42 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/11.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/12.png b/source/core/assets/planets/Barren_or_Moon_bw/2/12.png new file mode 100644 index 000000000..af7abbc1c Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/12.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/13.png b/source/core/assets/planets/Barren_or_Moon_bw/2/13.png new file mode 100644 index 000000000..69d8b3c97 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/13.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/14.png b/source/core/assets/planets/Barren_or_Moon_bw/2/14.png new file mode 100644 index 000000000..cde8aac41 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/14.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/15.png b/source/core/assets/planets/Barren_or_Moon_bw/2/15.png new file mode 100644 index 000000000..72688aec7 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/15.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/16.png b/source/core/assets/planets/Barren_or_Moon_bw/2/16.png new file mode 100644 index 000000000..8d2c0c3f8 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/16.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/17.png b/source/core/assets/planets/Barren_or_Moon_bw/2/17.png new file mode 100644 index 000000000..103f9db5d Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/17.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/18.png b/source/core/assets/planets/Barren_or_Moon_bw/2/18.png new file mode 100644 index 000000000..8042f62d4 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/18.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/19.png b/source/core/assets/planets/Barren_or_Moon_bw/2/19.png new file mode 100644 index 000000000..e1f79e56d Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/19.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/2.png b/source/core/assets/planets/Barren_or_Moon_bw/2/2.png new file mode 100644 index 000000000..dfe9ffa08 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/2.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/20.png b/source/core/assets/planets/Barren_or_Moon_bw/2/20.png new file mode 100644 index 000000000..ea08f6dbd Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/20.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/21.png b/source/core/assets/planets/Barren_or_Moon_bw/2/21.png new file mode 100644 index 000000000..6c0e49f7e Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/21.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/22.png b/source/core/assets/planets/Barren_or_Moon_bw/2/22.png new file mode 100644 index 000000000..8f46a8754 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/22.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/23.png b/source/core/assets/planets/Barren_or_Moon_bw/2/23.png new file mode 100644 index 000000000..d26c3f2cb Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/23.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/24.png b/source/core/assets/planets/Barren_or_Moon_bw/2/24.png new file mode 100644 index 000000000..31a0089cf Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/24.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/25.png b/source/core/assets/planets/Barren_or_Moon_bw/2/25.png new file mode 100644 index 000000000..0f6b42833 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/25.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/26.png b/source/core/assets/planets/Barren_or_Moon_bw/2/26.png new file mode 100644 index 000000000..ceea305fb Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/26.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/27.png b/source/core/assets/planets/Barren_or_Moon_bw/2/27.png new file mode 100644 index 000000000..409574f4b Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/27.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/28.png b/source/core/assets/planets/Barren_or_Moon_bw/2/28.png new file mode 100644 index 000000000..da0ea0619 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/28.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/29.png b/source/core/assets/planets/Barren_or_Moon_bw/2/29.png new file mode 100644 index 000000000..5883a9c6a Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/29.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/3.png b/source/core/assets/planets/Barren_or_Moon_bw/2/3.png new file mode 100644 index 000000000..3eb5240ad Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/3.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/30.png b/source/core/assets/planets/Barren_or_Moon_bw/2/30.png new file mode 100644 index 000000000..6b9a39fda Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/30.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/31.png b/source/core/assets/planets/Barren_or_Moon_bw/2/31.png new file mode 100644 index 000000000..0ab825429 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/31.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/32.png b/source/core/assets/planets/Barren_or_Moon_bw/2/32.png new file mode 100644 index 000000000..3f819e061 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/32.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/33.png b/source/core/assets/planets/Barren_or_Moon_bw/2/33.png new file mode 100644 index 000000000..3b342a7ed Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/33.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/34.png b/source/core/assets/planets/Barren_or_Moon_bw/2/34.png new file mode 100644 index 000000000..7e72e313b Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/34.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/35.png b/source/core/assets/planets/Barren_or_Moon_bw/2/35.png new file mode 100644 index 000000000..8f7a6ac98 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/35.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/36.png b/source/core/assets/planets/Barren_or_Moon_bw/2/36.png new file mode 100644 index 000000000..c97607f9d Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/36.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/37.png b/source/core/assets/planets/Barren_or_Moon_bw/2/37.png new file mode 100644 index 000000000..111369017 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/37.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/38.png b/source/core/assets/planets/Barren_or_Moon_bw/2/38.png new file mode 100644 index 000000000..d1bcb6c63 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/38.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/39.png b/source/core/assets/planets/Barren_or_Moon_bw/2/39.png new file mode 100644 index 000000000..a95c42274 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/39.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/4.png b/source/core/assets/planets/Barren_or_Moon_bw/2/4.png new file mode 100644 index 000000000..99c9a00e7 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/4.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/40.png b/source/core/assets/planets/Barren_or_Moon_bw/2/40.png new file mode 100644 index 000000000..a2d84a577 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/40.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/41.png b/source/core/assets/planets/Barren_or_Moon_bw/2/41.png new file mode 100644 index 000000000..5a5e72514 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/41.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/42.png b/source/core/assets/planets/Barren_or_Moon_bw/2/42.png new file mode 100644 index 000000000..184df838b Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/42.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/43.png b/source/core/assets/planets/Barren_or_Moon_bw/2/43.png new file mode 100644 index 000000000..28e4bd7b2 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/43.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/44.png b/source/core/assets/planets/Barren_or_Moon_bw/2/44.png new file mode 100644 index 000000000..08e086483 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/44.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/45.png b/source/core/assets/planets/Barren_or_Moon_bw/2/45.png new file mode 100644 index 000000000..8f0966920 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/45.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/46.png b/source/core/assets/planets/Barren_or_Moon_bw/2/46.png new file mode 100644 index 000000000..2746951f5 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/46.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/47.png b/source/core/assets/planets/Barren_or_Moon_bw/2/47.png new file mode 100644 index 000000000..f4c6864b6 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/47.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/48.png b/source/core/assets/planets/Barren_or_Moon_bw/2/48.png new file mode 100644 index 000000000..9cc5ffc9a Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/48.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/49.png b/source/core/assets/planets/Barren_or_Moon_bw/2/49.png new file mode 100644 index 000000000..5d6713c95 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/49.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/5.png b/source/core/assets/planets/Barren_or_Moon_bw/2/5.png new file mode 100644 index 000000000..89bc4b608 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/5.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/50.png b/source/core/assets/planets/Barren_or_Moon_bw/2/50.png new file mode 100644 index 000000000..6f917443d Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/50.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/51.png b/source/core/assets/planets/Barren_or_Moon_bw/2/51.png new file mode 100644 index 000000000..d4dbdbec9 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/51.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/52.png b/source/core/assets/planets/Barren_or_Moon_bw/2/52.png new file mode 100644 index 000000000..98e7cc3dc Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/52.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/53.png b/source/core/assets/planets/Barren_or_Moon_bw/2/53.png new file mode 100644 index 000000000..e63b80a40 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/53.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/54.png b/source/core/assets/planets/Barren_or_Moon_bw/2/54.png new file mode 100644 index 000000000..440ab7aca Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/54.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/55.png b/source/core/assets/planets/Barren_or_Moon_bw/2/55.png new file mode 100644 index 000000000..fee03428e Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/55.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/56.png b/source/core/assets/planets/Barren_or_Moon_bw/2/56.png new file mode 100644 index 000000000..d7efc51e5 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/56.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/57.png b/source/core/assets/planets/Barren_or_Moon_bw/2/57.png new file mode 100644 index 000000000..4636aa76b Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/57.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/58.png b/source/core/assets/planets/Barren_or_Moon_bw/2/58.png new file mode 100644 index 000000000..f0d2ce55b Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/58.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/59.png b/source/core/assets/planets/Barren_or_Moon_bw/2/59.png new file mode 100644 index 000000000..1dcca3581 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/59.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/6.png b/source/core/assets/planets/Barren_or_Moon_bw/2/6.png new file mode 100644 index 000000000..2b2446eec Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/6.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/60.png b/source/core/assets/planets/Barren_or_Moon_bw/2/60.png new file mode 100644 index 000000000..ee5a8d3d6 Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/60.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/7.png b/source/core/assets/planets/Barren_or_Moon_bw/2/7.png new file mode 100644 index 000000000..aa572f74c Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/7.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/8.png b/source/core/assets/planets/Barren_or_Moon_bw/2/8.png new file mode 100644 index 000000000..cc337325f Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/8.png differ diff --git a/source/core/assets/planets/Barren_or_Moon_bw/2/9.png b/source/core/assets/planets/Barren_or_Moon_bw/2/9.png new file mode 100644 index 000000000..343949c3e Binary files /dev/null and b/source/core/assets/planets/Barren_or_Moon_bw/2/9.png differ diff --git a/source/core/assets/planets/Desert_bw/1/1.png b/source/core/assets/planets/Desert_bw/1/1.png new file mode 100644 index 000000000..f46cb689c Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/1.png differ diff --git a/source/core/assets/planets/Desert_bw/1/10.png b/source/core/assets/planets/Desert_bw/1/10.png new file mode 100644 index 000000000..c58ab448a Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/10.png differ diff --git a/source/core/assets/planets/Desert_bw/1/11.png b/source/core/assets/planets/Desert_bw/1/11.png new file mode 100644 index 000000000..9bbd5b15e Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/11.png differ diff --git a/source/core/assets/planets/Desert_bw/1/12.png b/source/core/assets/planets/Desert_bw/1/12.png new file mode 100644 index 000000000..10ab860ba Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/12.png differ diff --git a/source/core/assets/planets/Desert_bw/1/13.png b/source/core/assets/planets/Desert_bw/1/13.png new file mode 100644 index 000000000..06bef9c92 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/13.png differ diff --git a/source/core/assets/planets/Desert_bw/1/14.png b/source/core/assets/planets/Desert_bw/1/14.png new file mode 100644 index 000000000..8190ee841 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/14.png differ diff --git a/source/core/assets/planets/Desert_bw/1/15.png b/source/core/assets/planets/Desert_bw/1/15.png new file mode 100644 index 000000000..4e8d7bc08 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/15.png differ diff --git a/source/core/assets/planets/Desert_bw/1/16.png b/source/core/assets/planets/Desert_bw/1/16.png new file mode 100644 index 000000000..698ee30e1 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/16.png differ diff --git a/source/core/assets/planets/Desert_bw/1/17.png b/source/core/assets/planets/Desert_bw/1/17.png new file mode 100644 index 000000000..58a1598b7 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/17.png differ diff --git a/source/core/assets/planets/Desert_bw/1/18.png b/source/core/assets/planets/Desert_bw/1/18.png new file mode 100644 index 000000000..986726910 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/18.png differ diff --git a/source/core/assets/planets/Desert_bw/1/19.png b/source/core/assets/planets/Desert_bw/1/19.png new file mode 100644 index 000000000..b8eaff229 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/19.png differ diff --git a/source/core/assets/planets/Desert_bw/1/2.png b/source/core/assets/planets/Desert_bw/1/2.png new file mode 100644 index 000000000..2781b82e5 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/2.png differ diff --git a/source/core/assets/planets/Desert_bw/1/20.png b/source/core/assets/planets/Desert_bw/1/20.png new file mode 100644 index 000000000..b3958de59 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/20.png differ diff --git a/source/core/assets/planets/Desert_bw/1/21.png b/source/core/assets/planets/Desert_bw/1/21.png new file mode 100644 index 000000000..a60474811 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/21.png differ diff --git a/source/core/assets/planets/Desert_bw/1/22.png b/source/core/assets/planets/Desert_bw/1/22.png new file mode 100644 index 000000000..c601e384f Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/22.png differ diff --git a/source/core/assets/planets/Desert_bw/1/23.png b/source/core/assets/planets/Desert_bw/1/23.png new file mode 100644 index 000000000..6d85bd568 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/23.png differ diff --git a/source/core/assets/planets/Desert_bw/1/24.png b/source/core/assets/planets/Desert_bw/1/24.png new file mode 100644 index 000000000..9a87cb24a Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/24.png differ diff --git a/source/core/assets/planets/Desert_bw/1/25.png b/source/core/assets/planets/Desert_bw/1/25.png new file mode 100644 index 000000000..ba3244ab0 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/25.png differ diff --git a/source/core/assets/planets/Desert_bw/1/26.png b/source/core/assets/planets/Desert_bw/1/26.png new file mode 100644 index 000000000..bbf9658cd Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/26.png differ diff --git a/source/core/assets/planets/Desert_bw/1/27.png b/source/core/assets/planets/Desert_bw/1/27.png new file mode 100644 index 000000000..085b26c0c Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/27.png differ diff --git a/source/core/assets/planets/Desert_bw/1/28.png b/source/core/assets/planets/Desert_bw/1/28.png new file mode 100644 index 000000000..90e2e3973 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/28.png differ diff --git a/source/core/assets/planets/Desert_bw/1/29.png b/source/core/assets/planets/Desert_bw/1/29.png new file mode 100644 index 000000000..0b45d77e2 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/29.png differ diff --git a/source/core/assets/planets/Desert_bw/1/3.png b/source/core/assets/planets/Desert_bw/1/3.png new file mode 100644 index 000000000..7e4940092 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/3.png differ diff --git a/source/core/assets/planets/Desert_bw/1/30.png b/source/core/assets/planets/Desert_bw/1/30.png new file mode 100644 index 000000000..699ef070a Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/30.png differ diff --git a/source/core/assets/planets/Desert_bw/1/31.png b/source/core/assets/planets/Desert_bw/1/31.png new file mode 100644 index 000000000..a9ae13fe9 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/31.png differ diff --git a/source/core/assets/planets/Desert_bw/1/32.png b/source/core/assets/planets/Desert_bw/1/32.png new file mode 100644 index 000000000..8f67ae032 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/32.png differ diff --git a/source/core/assets/planets/Desert_bw/1/33.png b/source/core/assets/planets/Desert_bw/1/33.png new file mode 100644 index 000000000..18a14ff2d Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/33.png differ diff --git a/source/core/assets/planets/Desert_bw/1/34.png b/source/core/assets/planets/Desert_bw/1/34.png new file mode 100644 index 000000000..79f2d7d4a Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/34.png differ diff --git a/source/core/assets/planets/Desert_bw/1/35.png b/source/core/assets/planets/Desert_bw/1/35.png new file mode 100644 index 000000000..e6b295841 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/35.png differ diff --git a/source/core/assets/planets/Desert_bw/1/36.png b/source/core/assets/planets/Desert_bw/1/36.png new file mode 100644 index 000000000..a93e0e1b2 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/36.png differ diff --git a/source/core/assets/planets/Desert_bw/1/37.png b/source/core/assets/planets/Desert_bw/1/37.png new file mode 100644 index 000000000..8fce78ac2 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/37.png differ diff --git a/source/core/assets/planets/Desert_bw/1/38.png b/source/core/assets/planets/Desert_bw/1/38.png new file mode 100644 index 000000000..48421334b Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/38.png differ diff --git a/source/core/assets/planets/Desert_bw/1/39.png b/source/core/assets/planets/Desert_bw/1/39.png new file mode 100644 index 000000000..deb2f6036 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/39.png differ diff --git a/source/core/assets/planets/Desert_bw/1/4.png b/source/core/assets/planets/Desert_bw/1/4.png new file mode 100644 index 000000000..ba06391a6 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/4.png differ diff --git a/source/core/assets/planets/Desert_bw/1/40.png b/source/core/assets/planets/Desert_bw/1/40.png new file mode 100644 index 000000000..369e0c071 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/40.png differ diff --git a/source/core/assets/planets/Desert_bw/1/41.png b/source/core/assets/planets/Desert_bw/1/41.png new file mode 100644 index 000000000..fb5c606ac Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/41.png differ diff --git a/source/core/assets/planets/Desert_bw/1/42.png b/source/core/assets/planets/Desert_bw/1/42.png new file mode 100644 index 000000000..8f19f22af Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/42.png differ diff --git a/source/core/assets/planets/Desert_bw/1/43.png b/source/core/assets/planets/Desert_bw/1/43.png new file mode 100644 index 000000000..7733662a7 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/43.png differ diff --git a/source/core/assets/planets/Desert_bw/1/44.png b/source/core/assets/planets/Desert_bw/1/44.png new file mode 100644 index 000000000..b838b2be2 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/44.png differ diff --git a/source/core/assets/planets/Desert_bw/1/45.png b/source/core/assets/planets/Desert_bw/1/45.png new file mode 100644 index 000000000..292b15023 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/45.png differ diff --git a/source/core/assets/planets/Desert_bw/1/46.png b/source/core/assets/planets/Desert_bw/1/46.png new file mode 100644 index 000000000..794767e0b Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/46.png differ diff --git a/source/core/assets/planets/Desert_bw/1/47.png b/source/core/assets/planets/Desert_bw/1/47.png new file mode 100644 index 000000000..09fb1ba56 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/47.png differ diff --git a/source/core/assets/planets/Desert_bw/1/48.png b/source/core/assets/planets/Desert_bw/1/48.png new file mode 100644 index 000000000..0841b4217 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/48.png differ diff --git a/source/core/assets/planets/Desert_bw/1/49.png b/source/core/assets/planets/Desert_bw/1/49.png new file mode 100644 index 000000000..456f88164 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/49.png differ diff --git a/source/core/assets/planets/Desert_bw/1/5.png b/source/core/assets/planets/Desert_bw/1/5.png new file mode 100644 index 000000000..f1f657c6b Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/5.png differ diff --git a/source/core/assets/planets/Desert_bw/1/50.png b/source/core/assets/planets/Desert_bw/1/50.png new file mode 100644 index 000000000..2dbba0084 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/50.png differ diff --git a/source/core/assets/planets/Desert_bw/1/51.png b/source/core/assets/planets/Desert_bw/1/51.png new file mode 100644 index 000000000..525975029 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/51.png differ diff --git a/source/core/assets/planets/Desert_bw/1/52.png b/source/core/assets/planets/Desert_bw/1/52.png new file mode 100644 index 000000000..53636a69d Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/52.png differ diff --git a/source/core/assets/planets/Desert_bw/1/53.png b/source/core/assets/planets/Desert_bw/1/53.png new file mode 100644 index 000000000..d33b7b261 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/53.png differ diff --git a/source/core/assets/planets/Desert_bw/1/54.png b/source/core/assets/planets/Desert_bw/1/54.png new file mode 100644 index 000000000..69b2e663a Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/54.png differ diff --git a/source/core/assets/planets/Desert_bw/1/55.png b/source/core/assets/planets/Desert_bw/1/55.png new file mode 100644 index 000000000..0361ed344 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/55.png differ diff --git a/source/core/assets/planets/Desert_bw/1/56.png b/source/core/assets/planets/Desert_bw/1/56.png new file mode 100644 index 000000000..8fa954a7c Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/56.png differ diff --git a/source/core/assets/planets/Desert_bw/1/57.png b/source/core/assets/planets/Desert_bw/1/57.png new file mode 100644 index 000000000..0046fa102 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/57.png differ diff --git a/source/core/assets/planets/Desert_bw/1/58.png b/source/core/assets/planets/Desert_bw/1/58.png new file mode 100644 index 000000000..c5d0730ce Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/58.png differ diff --git a/source/core/assets/planets/Desert_bw/1/59.png b/source/core/assets/planets/Desert_bw/1/59.png new file mode 100644 index 000000000..d439755c9 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/59.png differ diff --git a/source/core/assets/planets/Desert_bw/1/6.png b/source/core/assets/planets/Desert_bw/1/6.png new file mode 100644 index 000000000..4f47a7d3a Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/6.png differ diff --git a/source/core/assets/planets/Desert_bw/1/60.png b/source/core/assets/planets/Desert_bw/1/60.png new file mode 100644 index 000000000..901ec426c Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/60.png differ diff --git a/source/core/assets/planets/Desert_bw/1/7.png b/source/core/assets/planets/Desert_bw/1/7.png new file mode 100644 index 000000000..4afcc2b93 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/7.png differ diff --git a/source/core/assets/planets/Desert_bw/1/8.png b/source/core/assets/planets/Desert_bw/1/8.png new file mode 100644 index 000000000..2467b0973 Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/8.png differ diff --git a/source/core/assets/planets/Desert_bw/1/9.png b/source/core/assets/planets/Desert_bw/1/9.png new file mode 100644 index 000000000..64c1407ae Binary files /dev/null and b/source/core/assets/planets/Desert_bw/1/9.png differ diff --git a/source/core/assets/planets/Lava_bw/1/1.png b/source/core/assets/planets/Lava_bw/1/1.png new file mode 100644 index 000000000..4870542ee Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/1.png differ diff --git a/source/core/assets/planets/Lava_bw/1/10.png b/source/core/assets/planets/Lava_bw/1/10.png new file mode 100644 index 000000000..27892603b Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/10.png differ diff --git a/source/core/assets/planets/Lava_bw/1/11.png b/source/core/assets/planets/Lava_bw/1/11.png new file mode 100644 index 000000000..8fac24b5e Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/11.png differ diff --git a/source/core/assets/planets/Lava_bw/1/12.png b/source/core/assets/planets/Lava_bw/1/12.png new file mode 100644 index 000000000..9d1506a86 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/12.png differ diff --git a/source/core/assets/planets/Lava_bw/1/13.png b/source/core/assets/planets/Lava_bw/1/13.png new file mode 100644 index 000000000..6772fcc59 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/13.png differ diff --git a/source/core/assets/planets/Lava_bw/1/14.png b/source/core/assets/planets/Lava_bw/1/14.png new file mode 100644 index 000000000..a840e1709 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/14.png differ diff --git a/source/core/assets/planets/Lava_bw/1/15.png b/source/core/assets/planets/Lava_bw/1/15.png new file mode 100644 index 000000000..1ecb607ba Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/15.png differ diff --git a/source/core/assets/planets/Lava_bw/1/16.png b/source/core/assets/planets/Lava_bw/1/16.png new file mode 100644 index 000000000..cea173d97 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/16.png differ diff --git a/source/core/assets/planets/Lava_bw/1/17.png b/source/core/assets/planets/Lava_bw/1/17.png new file mode 100644 index 000000000..96aa223a8 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/17.png differ diff --git a/source/core/assets/planets/Lava_bw/1/18.png b/source/core/assets/planets/Lava_bw/1/18.png new file mode 100644 index 000000000..9f747091a Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/18.png differ diff --git a/source/core/assets/planets/Lava_bw/1/19.png b/source/core/assets/planets/Lava_bw/1/19.png new file mode 100644 index 000000000..26f7dd583 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/19.png differ diff --git a/source/core/assets/planets/Lava_bw/1/2.png b/source/core/assets/planets/Lava_bw/1/2.png new file mode 100644 index 000000000..2f3256c15 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/2.png differ diff --git a/source/core/assets/planets/Lava_bw/1/20.png b/source/core/assets/planets/Lava_bw/1/20.png new file mode 100644 index 000000000..6635e686b Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/20.png differ diff --git a/source/core/assets/planets/Lava_bw/1/21.png b/source/core/assets/planets/Lava_bw/1/21.png new file mode 100644 index 000000000..4a652d49d Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/21.png differ diff --git a/source/core/assets/planets/Lava_bw/1/22.png b/source/core/assets/planets/Lava_bw/1/22.png new file mode 100644 index 000000000..7d2e6a780 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/22.png differ diff --git a/source/core/assets/planets/Lava_bw/1/23.png b/source/core/assets/planets/Lava_bw/1/23.png new file mode 100644 index 000000000..87d84cae8 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/23.png differ diff --git a/source/core/assets/planets/Lava_bw/1/24.png b/source/core/assets/planets/Lava_bw/1/24.png new file mode 100644 index 000000000..0afc0c14f Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/24.png differ diff --git a/source/core/assets/planets/Lava_bw/1/25.png b/source/core/assets/planets/Lava_bw/1/25.png new file mode 100644 index 000000000..8c1f67ad8 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/25.png differ diff --git a/source/core/assets/planets/Lava_bw/1/26.png b/source/core/assets/planets/Lava_bw/1/26.png new file mode 100644 index 000000000..3821d8c8f Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/26.png differ diff --git a/source/core/assets/planets/Lava_bw/1/27.png b/source/core/assets/planets/Lava_bw/1/27.png new file mode 100644 index 000000000..4f1278653 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/27.png differ diff --git a/source/core/assets/planets/Lava_bw/1/28.png b/source/core/assets/planets/Lava_bw/1/28.png new file mode 100644 index 000000000..e63366a61 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/28.png differ diff --git a/source/core/assets/planets/Lava_bw/1/29.png b/source/core/assets/planets/Lava_bw/1/29.png new file mode 100644 index 000000000..9d2f957c6 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/29.png differ diff --git a/source/core/assets/planets/Lava_bw/1/3.png b/source/core/assets/planets/Lava_bw/1/3.png new file mode 100644 index 000000000..c1832e3f8 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/3.png differ diff --git a/source/core/assets/planets/Lava_bw/1/30.png b/source/core/assets/planets/Lava_bw/1/30.png new file mode 100644 index 000000000..a829dcafa Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/30.png differ diff --git a/source/core/assets/planets/Lava_bw/1/31.png b/source/core/assets/planets/Lava_bw/1/31.png new file mode 100644 index 000000000..bca15d38a Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/31.png differ diff --git a/source/core/assets/planets/Lava_bw/1/32.png b/source/core/assets/planets/Lava_bw/1/32.png new file mode 100644 index 000000000..f518b17ea Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/32.png differ diff --git a/source/core/assets/planets/Lava_bw/1/33.png b/source/core/assets/planets/Lava_bw/1/33.png new file mode 100644 index 000000000..c198e15dc Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/33.png differ diff --git a/source/core/assets/planets/Lava_bw/1/34.png b/source/core/assets/planets/Lava_bw/1/34.png new file mode 100644 index 000000000..5858eed2b Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/34.png differ diff --git a/source/core/assets/planets/Lava_bw/1/35.png b/source/core/assets/planets/Lava_bw/1/35.png new file mode 100644 index 000000000..4ff7388ba Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/35.png differ diff --git a/source/core/assets/planets/Lava_bw/1/36.png b/source/core/assets/planets/Lava_bw/1/36.png new file mode 100644 index 000000000..bdbe0cbbc Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/36.png differ diff --git a/source/core/assets/planets/Lava_bw/1/37.png b/source/core/assets/planets/Lava_bw/1/37.png new file mode 100644 index 000000000..124696f87 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/37.png differ diff --git a/source/core/assets/planets/Lava_bw/1/38.png b/source/core/assets/planets/Lava_bw/1/38.png new file mode 100644 index 000000000..b63846619 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/38.png differ diff --git a/source/core/assets/planets/Lava_bw/1/39.png b/source/core/assets/planets/Lava_bw/1/39.png new file mode 100644 index 000000000..69067340a Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/39.png differ diff --git a/source/core/assets/planets/Lava_bw/1/4.png b/source/core/assets/planets/Lava_bw/1/4.png new file mode 100644 index 000000000..1bba4861a Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/4.png differ diff --git a/source/core/assets/planets/Lava_bw/1/40.png b/source/core/assets/planets/Lava_bw/1/40.png new file mode 100644 index 000000000..b73701d1c Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/40.png differ diff --git a/source/core/assets/planets/Lava_bw/1/41.png b/source/core/assets/planets/Lava_bw/1/41.png new file mode 100644 index 000000000..be99af527 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/41.png differ diff --git a/source/core/assets/planets/Lava_bw/1/42.png b/source/core/assets/planets/Lava_bw/1/42.png new file mode 100644 index 000000000..0f33b33ef Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/42.png differ diff --git a/source/core/assets/planets/Lava_bw/1/43.png b/source/core/assets/planets/Lava_bw/1/43.png new file mode 100644 index 000000000..12da1adfd Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/43.png differ diff --git a/source/core/assets/planets/Lava_bw/1/44.png b/source/core/assets/planets/Lava_bw/1/44.png new file mode 100644 index 000000000..bb3861f75 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/44.png differ diff --git a/source/core/assets/planets/Lava_bw/1/45.png b/source/core/assets/planets/Lava_bw/1/45.png new file mode 100644 index 000000000..4889df522 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/45.png differ diff --git a/source/core/assets/planets/Lava_bw/1/46.png b/source/core/assets/planets/Lava_bw/1/46.png new file mode 100644 index 000000000..f42703873 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/46.png differ diff --git a/source/core/assets/planets/Lava_bw/1/47.png b/source/core/assets/planets/Lava_bw/1/47.png new file mode 100644 index 000000000..fd942d677 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/47.png differ diff --git a/source/core/assets/planets/Lava_bw/1/48.png b/source/core/assets/planets/Lava_bw/1/48.png new file mode 100644 index 000000000..a52660c5f Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/48.png differ diff --git a/source/core/assets/planets/Lava_bw/1/49.png b/source/core/assets/planets/Lava_bw/1/49.png new file mode 100644 index 000000000..66f7a08b1 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/49.png differ diff --git a/source/core/assets/planets/Lava_bw/1/5.png b/source/core/assets/planets/Lava_bw/1/5.png new file mode 100644 index 000000000..dcab56667 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/5.png differ diff --git a/source/core/assets/planets/Lava_bw/1/50.png b/source/core/assets/planets/Lava_bw/1/50.png new file mode 100644 index 000000000..f93a71b11 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/50.png differ diff --git a/source/core/assets/planets/Lava_bw/1/51.png b/source/core/assets/planets/Lava_bw/1/51.png new file mode 100644 index 000000000..34c30435c Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/51.png differ diff --git a/source/core/assets/planets/Lava_bw/1/52.png b/source/core/assets/planets/Lava_bw/1/52.png new file mode 100644 index 000000000..a9d61627e Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/52.png differ diff --git a/source/core/assets/planets/Lava_bw/1/53.png b/source/core/assets/planets/Lava_bw/1/53.png new file mode 100644 index 000000000..d8f6e7acc Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/53.png differ diff --git a/source/core/assets/planets/Lava_bw/1/54.png b/source/core/assets/planets/Lava_bw/1/54.png new file mode 100644 index 000000000..1977fe824 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/54.png differ diff --git a/source/core/assets/planets/Lava_bw/1/55.png b/source/core/assets/planets/Lava_bw/1/55.png new file mode 100644 index 000000000..41d663d35 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/55.png differ diff --git a/source/core/assets/planets/Lava_bw/1/56.png b/source/core/assets/planets/Lava_bw/1/56.png new file mode 100644 index 000000000..58e5ce938 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/56.png differ diff --git a/source/core/assets/planets/Lava_bw/1/57.png b/source/core/assets/planets/Lava_bw/1/57.png new file mode 100644 index 000000000..92f979cb6 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/57.png differ diff --git a/source/core/assets/planets/Lava_bw/1/58.png b/source/core/assets/planets/Lava_bw/1/58.png new file mode 100644 index 000000000..2453d425a Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/58.png differ diff --git a/source/core/assets/planets/Lava_bw/1/59.png b/source/core/assets/planets/Lava_bw/1/59.png new file mode 100644 index 000000000..34b374eb6 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/59.png differ diff --git a/source/core/assets/planets/Lava_bw/1/6.png b/source/core/assets/planets/Lava_bw/1/6.png new file mode 100644 index 000000000..b0ede3cc5 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/6.png differ diff --git a/source/core/assets/planets/Lava_bw/1/60.png b/source/core/assets/planets/Lava_bw/1/60.png new file mode 100644 index 000000000..27c94b8f7 Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/60.png differ diff --git a/source/core/assets/planets/Lava_bw/1/7.png b/source/core/assets/planets/Lava_bw/1/7.png new file mode 100644 index 000000000..2d651f42c Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/7.png differ diff --git a/source/core/assets/planets/Lava_bw/1/8.png b/source/core/assets/planets/Lava_bw/1/8.png new file mode 100644 index 000000000..1d823981d Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/8.png differ diff --git a/source/core/assets/planets/Lava_bw/1/9.png b/source/core/assets/planets/Lava_bw/1/9.png new file mode 100644 index 000000000..db5fca99d Binary files /dev/null and b/source/core/assets/planets/Lava_bw/1/9.png differ diff --git a/source/core/assets/sounds/towers/12-Gauge-Pump-Action-Shotgun-Close-Gunshot.mp3 b/source/core/assets/sounds/towers/12-Gauge-Pump-Action-Shotgun-Close-Gunshot.mp3 new file mode 100644 index 000000000..61bc03e66 Binary files /dev/null and b/source/core/assets/sounds/towers/12-Gauge-Pump-Action-Shotgun-Close-Gunshot.mp3 differ diff --git a/source/core/assets/sounds/towers/5.56_single_shot.mp3 b/source/core/assets/sounds/towers/5.56_single_shot.mp3 new file mode 100644 index 000000000..0611f722a Binary files /dev/null and b/source/core/assets/sounds/towers/5.56_single_shot.mp3 differ diff --git a/source/core/assets/sounds/towers/Desert-Eagle-Far-Single-Gunshot.mp3 b/source/core/assets/sounds/towers/Desert-Eagle-Far-Single-Gunshot.mp3 new file mode 100644 index 000000000..5e39881ce Binary files /dev/null and b/source/core/assets/sounds/towers/Desert-Eagle-Far-Single-Gunshot.mp3 differ diff --git a/source/core/assets/sounds/towers/ar15_single_shot_far.mp3 b/source/core/assets/sounds/towers/ar15_single_shot_far.mp3 new file mode 100644 index 000000000..34ef353ee Binary files /dev/null and b/source/core/assets/sounds/towers/ar15_single_shot_far.mp3 differ diff --git a/source/core/assets/sounds/towers/eco_tower_ping.mp3 b/source/core/assets/sounds/towers/eco_tower_ping.mp3 new file mode 100644 index 000000000..1553f6001 Binary files /dev/null and b/source/core/assets/sounds/towers/eco_tower_ping.mp3 differ diff --git a/source/core/assets/sounds/towers/explosion.mp3 b/source/core/assets/sounds/towers/explosion.mp3 new file mode 100644 index 000000000..ab19a2947 Binary files /dev/null and b/source/core/assets/sounds/towers/explosion.mp3 differ diff --git a/source/core/src/main/com/csse3200/game/GdxGame.java b/source/core/src/main/com/csse3200/game/GdxGame.java index 903f443d3..5e3581d2a 100644 --- a/source/core/src/main/com/csse3200/game/GdxGame.java +++ b/source/core/src/main/com/csse3200/game/GdxGame.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.Screen; import com.csse3200.game.files.UserSettings; import com.csse3200.game.screens.*; +import com.csse3200.game.screens.HelpScreen.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,7 +18,7 @@ */ public class GdxGame extends Game { private static final Logger logger = LoggerFactory.getLogger(GdxGame.class); - + public int currentLevel = 0; @Override public void create() { logger.info("Creating game"); @@ -63,30 +64,31 @@ public void dispose() { * @return new screen */ private Screen newScreen(ScreenType screenType) { - switch (screenType) { - case MAIN_MENU: - return new MainMenuScreen(this); - case MAIN_GAME: - return new MainGameScreen(this); - case SETTINGS: - return new SettingsScreen(this); - case STORY_SCREEN: - return new StoryScreen(this); - case LEVEL_SELECT: - return new LevelSelectScreen(this); - case LOSING_SCREEN: - return new LosingScreen(this); - case TURRET_SELECTION: - return new TurretSelectionScreen(this); - case HELP_SCREEN: - return new HelpScreen(this); - default: - return null; - } + return switch (screenType) { + case Next_Screen -> new NextLevelScreen(this, currentLevel); + case Win_Screen -> new WinningScreen(this); + case MAIN_MENU -> new MainMenuScreen(this); + case MAIN_GAME -> new MainGameScreen(this); + case SETTINGS -> new SettingsScreen(this); + case STORY_SCREEN -> new StoryScreen(this); + case LEVEL_SELECT -> new LevelSelectScreen(this, currentLevel); + case LOSING_SCREEN -> new LosingScreen(this); + case TURRET_SELECTION -> new TurretSelectionScreen(this); + case HELP_SCREEN -> new GameDescriptionHelpScreen(this); + case HELP_MOBS_SCREEN -> new MobsDescriptionHelpScreen(this); + case HELP_TOWER_SCREEN -> new TowerDescriptionHelpScreen(this); + case HELP_BOSS_SCREEN -> new BossDescriptionHelpScreen(this); + case LOAD_SCREEN -> new LoadingScreen(this); + case HOW_TO_PLAY -> new HowToPlay(this); + + case TUTORIAL_SCREEN-> new Tutorial(this); + default-> null; + }; } public enum ScreenType { - MAIN_MENU, MAIN_GAME, SETTINGS, STORY_SCREEN, LEVEL_SELECT, TURRET_SELECTION, LOSING_SCREEN, HELP_SCREEN + MAIN_MENU, MAIN_GAME, SETTINGS, STORY_SCREEN, LEVEL_SELECT, TURRET_SELECTION, LOSING_SCREEN, HELP_SCREEN, LOAD_SCREEN, + HELP_MOBS_SCREEN, HELP_TOWER_SCREEN, HELP_BOSS_SCREEN, Win_Screen, Next_Screen, HOW_TO_PLAY, TUTORIAL_SCREEN } /** @@ -95,4 +97,4 @@ public enum ScreenType { public void exit() { app.exit(); } -} +} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/ai/tasks/AITaskComponent.java b/source/core/src/main/com/csse3200/game/ai/tasks/AITaskComponent.java index 93798e8d4..b54745014 100644 --- a/source/core/src/main/com/csse3200/game/ai/tasks/AITaskComponent.java +++ b/source/core/src/main/com/csse3200/game/ai/tasks/AITaskComponent.java @@ -46,8 +46,8 @@ public AITaskComponent addTask(PriorityTask task) { */ public T getTask(Class task) { for (PriorityTask priorityTask : priorityTasks) { - if (priorityTask.getClass() == task) { - return (T) priorityTask; + if (task.isInstance(priorityTask)) { + return task.cast(priorityTask); } } logger.info("Task {} not found", task); @@ -83,12 +83,8 @@ public void dispose() { */ public void disposeAll() { currentTask = null; - for (int i = 0; i < priorityTasks.size(); i++) { - priorityTasksToBeRestored.add(priorityTasks.get(i)); - } - for (int i = 0; i < priorityTasks.size(); i++) { - priorityTasks.remove(i); - } + priorityTasksToBeRestored.addAll(priorityTasks); + priorityTasks.clear(); } /** @@ -96,12 +92,8 @@ public void disposeAll() { * back into priorityTasks. */ public void restore() { - for (int i = 0; i < priorityTasksToBeRestored.size(); i++) { - priorityTasks.add(priorityTasksToBeRestored.get(i)); - } - for (int i = 0; i < priorityTasksToBeRestored.size(); i++) { - priorityTasksToBeRestored.remove(i); - } + priorityTasks.addAll(priorityTasksToBeRestored); + priorityTasksToBeRestored.clear(); this.update(); } diff --git a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java index 8fccaf74b..30ada73cc 100644 --- a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java +++ b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java @@ -22,8 +22,6 @@ public class ForestGameArea extends GameArea { private static final Logger logger = LoggerFactory.getLogger(ForestGameArea.class); private Timer waveTimer; - - private static final int NUM_WEAPON_TOWERS = 3; private static final GridPoint2 PLAYER_SPAWN = new GridPoint2(2, 4); // Temporary spawn point for testing private static final float WALL_WIDTH = 0.1f; @@ -161,6 +159,7 @@ public class ForestGameArea extends GameArea { "images/mobs/rocky.atlas" }; private static final String[] forestSounds = { + "sounds/ui/Open_Close/NA_SFUI_Vol1_Open_01.ogg", "sounds/Impact4.ogg", "sounds/economy/click.wav", "sounds/economy/click_1.wav", @@ -201,10 +200,14 @@ public class ForestGameArea extends GameArea { "sounds/mobBoss/patrickThunder.mp3", "sounds/mobBoss/patrickHit.mp3", "sounds/mobBoss/spawnDemonSlime.mp3", + "sounds/towers/Desert-Eagle-Far-Single-Gunshot.mp3", + "sounds/towers/5.56_single_shot.mp3", + "sounds/towers/explosion.mp3", + "sounds/towers/eco_tower_ping.mp3", + "sounds/towers/ar15_single_shot_far.mp3", "sounds/mobs/skeletonHit.mp3", "sounds/mobs/coatAttack.mp3", "sounds/mobs/archerArrow.mp3" - }; private static final String BACKGROUND_MUSIC = "sounds/background/Sci-Fi1.ogg"; @@ -243,6 +246,37 @@ private void stopWaveTimer() { } } + /** + * Cases to spawn a wave + */ +// private void spawnWave() { +// wave++; +// switch (wave) { +// case 1: +// case 2: +// spawnFireWorm(); +// spawnDragonKnight(); +// +// break; +// case 3: +// spawnSkeleton(); +// spawnWizard(); +// // mobBoss2 = spawnMobBoss2(); +// break; +// case 4: +// spawnWaterQueen(); +// spawnWaterSlime(); +// // mobBoss2 = spawnMobBoss2(); +// +// break; +// case 5: +// spawnDemonBoss(); +// default: +// // Handle other wave scenarios if needed +// break; +// } +// } + /** * Create the game area, including terrain, static entities (trees), dynamic entities (player) */ @@ -257,40 +291,20 @@ public void create() { spawnTerrain(); // Set up infrastructure for end game tracking -// player = spawnPlayer(); + // player = spawnPlayer(); logger.info("Creating waves"); waves = WaveFactory.createWaves(); spawnEntity(waves); waves.getEvents().addListener("spawnWave", this::spawnMob); - // spawnCoat(); -// spawnDodgingDragonKnight(17,4); -// spawnDeflectWizard(17, 3); -// spawnSplittingXenoGrunt(17, 2); -// spawnPatrick(); -// spawnDemonBoss(); - // spawnSplittingRocky(17, 4); - // spawnFireWizard(17, 3); - // spawnNecromancer(17, 2); - - - spawnScrap(); spawnGapScanners(); - -// spawnTNTTower(); -// spawnWeaponTower(); -// spawnGapScanners(); -// spawnDroidTower(); -// spawnFireWorksTower(); // Commented these out until they are needed for Demonstration -// spawnPierceTower(); -// spawnRicochetTower(); -// spawnBombship(); } - + private void displayUI() { Entity ui = new Entity(); +// ui.addComponent(new GameAreaDisplay("Box Forest")); TODO: This should be the level name? ui.addComponent(ServiceLocator.getGameEndService().getDisplay()); ui.addComponent(ServiceLocator.getCurrencyService().getDisplay()); spawnEntity(ui); @@ -331,102 +345,18 @@ private void spawnTerrain() { } - private Entity spawnPlayer() { - Entity newPlayer = PlayerFactory.createPlayer(); - spawnEntityAt(newPlayer, PLAYER_SPAWN, true, true); - return newPlayer; - } + //private Entity spawnPlayer() { + // Entity newPlayer = PlayerFactory.createPlayer(); + // spawnEntityAt(newPlayer, PLAYER_SPAWN, true, true); + // return newPlayer; + // } // Spawn player at a specific position - private Entity spawnPlayer(GridPoint2 position) { - Entity newPlayer = PlayerFactory.createPlayer(); - spawnEntityAt(newPlayer, position, true, true); - return newPlayer; - } - - // commented 383 - 386 out as there was a missing arg? - private void spawnDemonBoss() { - Entity demon = MobBossFactory.createDemonBoss(5000); - spawnEntityAt(demon, new GridPoint2(19, 5), true, false); - } - - private void spawnPatrick() { - Entity patrick = MobBossFactory.createPatrickBoss(3000); - spawnEntityAt(patrick, new GridPoint2(18, 5), true, false); - } - - private void spawnPatrickDeath() { - Entity patrickDeath = MobBossFactory.patrickDead(); - spawnEntityAt(patrickDeath, new GridPoint2(18, 5), true, false); - } - // commented 398 - 401 out as there was a missing arg? -// private void spawnIceBaby() { -// Entity iceBaby = MobBossFactory.createIceBoss(); -// spawnEntityAt(iceBaby, new GridPoint2(19, 5), true, false); -// } - -// private void spawnDemonBoss() { -// Entity demon = MobBossFactory.createDemonBoss(); -// spawnEntityAt(demon, new GridPoint2(19, 5), true, false); -// } - -// private void spawnPatrick() { -// Entity patrick = MobBossFactory.createPatrickBoss(3000); -// spawnEntityAt(patrick, new GridPoint2(18, 5), true, false); -// } -// -// private void spawnPatrickDeath() { -// Entity patrickDeath = MobBossFactory.patrickDead(); -// spawnEntityAt(patrickDeath, new GridPoint2(18, 5), true, false); -// } -// -// private void spawnIceBaby() { -// Entity iceBaby = MobBossFactory.createIceBoss(); -// spawnEntityAt(iceBaby, new GridPoint2(19, 5), true, false); -// } - - /** - * Spawns a projectile that only heads towards the enemies in its lane. - * - * @param position The position of the Entity that's shooting the projectile. - * @param targetLayer The enemy layer of the "shooter". - * @param direction The direction the projectile should head towards. - * @param speed The speed of the projectiles. - */ - private void spawnProjectile(Vector2 position, short targetLayer, int direction, Vector2 speed) { - Entity Projectile = ProjectileFactory.createFireBall(targetLayer, new Vector2(direction, position.y), speed); - Projectile.setPosition(position); - spawnEntity(Projectile); - } - - /** - * Spawns a projectile specifically for general mobs/xenohunters - * - * @param position The position of the Entity that's shooting the projectile. - * @param targetLayer The enemy layer of the "shooter". - * @param direction The direction the projectile should head towards. - * @param speed The speed of the projectiles. - */ - private void spawnProjectileTest(Vector2 position, short targetLayer, int direction, Vector2 speed) { - Entity Projectile = ProjectileFactory.createEngineerBullet(targetLayer, new Vector2(direction, position.y), speed); - Projectile.setPosition(position); - spawnEntity(Projectile); - } - - /** - * Spawns a projectile to be used for multiple projectile function. - * - * @param position The position of the Entity that's shooting the projectile. - * @param targetLayer The enemy layer of the "shooter". - * @param space The space between the projectiles' destination. - * @param direction The direction the projectile should head towards. - * @param speed The speed of the projectiles. - */ - private void spawnProjectile(Vector2 position, short targetLayer, int space, int direction, Vector2 speed) { - Entity Projectile = ProjectileFactory.createFireBall(targetLayer, new Vector2(direction, position.y + space), speed); - Projectile.setPosition(position); - spawnEntity(Projectile); - } + // private Entity spawnPlayer(GridPoint2 position) { + // Entity newPlayer = PlayerFactory.createPlayer(); +// spawnEntityAt(newPlayer, position, true, true); + // return newPlayer; + // } /** * Spawn an entity on the map. Is called during a wave. Add cases here for each mob type @@ -437,6 +367,9 @@ private void spawnProjectile(Vector2 position, short targetLayer, int space, int public void spawnMob(String entity, GridPoint2 randomPos, int health) { Entity mob; switch (entity) { + case "Xeno": + mob = NPCFactory.createXenoGrunt(health); + break; case "SplittingWaterSlime": mob = NPCFactory.createSplittingWaterSlime(health); break; @@ -449,7 +382,7 @@ public void spawnMob(String entity, GridPoint2 randomPos, int health) { case "Skeleton": mob = NPCFactory.createSkeleton(health); break; - case "DeflectWizard": + case "Wizard": mob = NPCFactory.createWizard(health); break; case "WaterQueen": @@ -461,6 +394,7 @@ public void spawnMob(String entity, GridPoint2 randomPos, int health) { case "IceBoss": mob = MobBossFactory.createIceBoss(health); break; + case "Coat": mob = NPCFactory.createCoat(health); break; @@ -473,15 +407,7 @@ public void spawnMob(String entity, GridPoint2 randomPos, int health) { case "ArcaneArcher": mob = NPCFactory.createDodgingArcaneArcher(health); break; - case "SplittingRocky": - mob = NPCFactory.createSplittingRocky(health); - break; - case "Necromancer": - mob = NPCFactory.createNecromancer(health); - break; - case "DeflectFireWizard": - mob = NPCFactory.createDeflectFireWizard(health); - break; + case "PatrickBoss": mob = MobBossFactory.createPatrickBoss(health); break; @@ -499,400 +425,6 @@ public void spawnMob(String entity, GridPoint2 randomPos, int health) { spawnEntityAt(mob, randomPos, true, false); } - // * TEMPORARY FOR TESTING -// private void spawnSplittingXenoGrunt(int x, int y) { -// GridPoint2 pos = new GridPoint2(x, y); -// Entity xenoGrunt = NPCFactory.createSplittingXenoGrunt(); -// xenoGrunt.setScale(1.5f, 1.5f); -// spawnEntityAt(xenoGrunt, pos, true, true); -// } - // * TEMPORARY FOR TESTING - private void spawnSplittingRocky(int x, int y) { - GridPoint2 pos = new GridPoint2(x, y); - Entity rocky = NPCFactory.createSplittingRocky(60); - rocky.setScale(1.5f, 1.5f); - spawnEntityAt(rocky, pos, true, true); - } - - private void spawnFireWizard(int x, int y) { - GridPoint2 pos = new GridPoint2(x, y); - Entity firewiz = NPCFactory.createDeflectFireWizard(60); - firewiz.setScale(1.5f, 1.5f); - spawnEntityAt(firewiz, pos, true, true); - } - - private void spawnNecromancer(int x, int y) { - GridPoint2 pos = new GridPoint2(x, y); - Entity Necromancer = NPCFactory.createNecromancer(60); - Necromancer.setScale(1.5f, 1.5f); - spawnEntityAt(Necromancer, pos, true, true); - } - - // * TEMPORARY FOR TESTING -// private void spawnDodgingDragonKnight(int x, int y) { -// GridPoint2 pos = new GridPoint2(x, y); -// Entity fireworm = NPCFactory.createDodgingDragonKnight(); -// fireworm.setScale(1.5f, 1.5f); -// spawnEntityAt(fireworm, pos, true, true); -// } -// -// // * TEMPORARY FOR TESTING -// private void spawnDeflectXenoGrunt(int x, int y) { -// GridPoint2 pos = new GridPoint2(x, y); -// Entity xenoGrunt = NPCFactory.createDeflectXenoGrunt(); -// xenoGrunt.setScale(1.5f, 1.5f); -// spawnEntityAt(xenoGrunt, pos, true, true); -// } -// -// private void spawnFireWorm() { -// int[] pickedLanes = random.ints(1, 7) -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity fireWorm = NPCFactory.createFireWorm(); -// fireWorm.setScale(1.5f, 1.5f); -// spawnEntityAt(fireWorm, randomPos, true, false); -// } -// } -// -// private void spawnSkeleton() { -// int[] pickedLanes = new Random().ints(1, 7) -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity skeleton = NPCFactory.createSkeleton(); -// skeleton.setScale(1.5f, 1.5f); -// spawnEntityAt(skeleton, randomPos, true, false); -// } -// } - -// private void spawnDragonKnight() { -// int[] pickedLanes = random.ints(1, 7) -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity fireWorm = NPCFactory.createDragonKnight(); -// fireWorm.setScale(1.5f, 1.5f); -// spawnEntityAt(fireWorm, randomPos, true, false); -// } -// } -// -// private void spawnWizard() { -// int[] pickedLanes = new Random().ints(1, 7) -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity wizard = NPCFactory.createWizard(); -// wizard.setScale(1.5f, 1.5f); -// spawnEntityAt(wizard, randomPos, true, false); -// } -// } -// -// private void spawnWaterQueen() { -// int[] pickedLanes = new Random().ints(1, 7) -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity waterQueen = NPCFactory.createWaterQueen(); -// waterQueen.setScale(1.5f, 1.5f); -// spawnEntityAt(waterQueen, randomPos, true, false); -// } -// } -// -// private void spawnWaterSlime() { -// int[] pickedLanes = new Random().ints(1, 7) -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity waterSlime = NPCFactory.createWaterSlime(); -// waterSlime.setScale(1.5f, 1.5f); -// spawnEntityAt(waterSlime, randomPos, true, false); -// } -// } - - // * TEMPORARY FOR TESTING - private void spawnDodgingDragonKnight(int x, int y) { - GridPoint2 pos = new GridPoint2(x, y); - Entity fireworm = NPCFactory.createDodgingDragonKnight(100); - fireworm.setScale(1.5f, 1.5f); - spawnEntityAt(fireworm, pos, true, true); - } -// -// // * TEMPORARY FOR TESTING - private void spawnDeflectWizard(int x, int y) { - GridPoint2 pos = new GridPoint2(x, y); - Entity xenoGrunt = NPCFactory.createDeflectWizard(100); - xenoGrunt.setScale(1.5f, 1.5f); - spawnEntityAt(xenoGrunt, pos, true, true); - } -// -// private void spawnFireWorm() { -// -// int[] pickedLanes = rand.ints(0, ServiceLocator.getMapService().getHeight() ) -// -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity fireWorm = NPCFactory.createFireWorm(); -// fireWorm.setScale(1.5f, 1.5f); -// spawnEntityAt(fireWorm, randomPos, true, false); -// } -// } -// -// private void spawnSkeleton() { -// -// int[] pickedLanes = new Random().ints(0, ServiceLocator.getMapService().getHeight() ) -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity skeleton = NPCFactory.createSkeleton(); -// skeleton.setScale(1.5f, 1.5f); -// spawnEntityAt(skeleton, randomPos, true, false); -// } -// } -// -// private void spawnDragonKnight() { -// -// int[] pickedLanes = rand.ints(0, ServiceLocator.getMapService().getHeight() ) -// -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity fireWorm = NPCFactory.createDodgingDragonKnight(); -// fireWorm.setScale(1.5f, 1.5f); -// spawnEntityAt(fireWorm, randomPos, true, false); -// } -// } -// -// private void spawnWizard() { -// -// int[] pickedLanes = rand.ints(0, ServiceLocator.getMapService().getHeight() ) -// -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity wizard = NPCFactory.createDeflectWizard(); -// wizard.setScale(1.5f, 1.5f); -// spawnEntityAt(wizard, randomPos, true, false); -// } -// } -// -// private void spawnWaterQueen() { -// -// int[] pickedLanes = new Random().ints(0, ServiceLocator.getMapService().getHeight() ) -// -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity waterQueen = NPCFactory.createWaterQueen(); -// waterQueen.setScale(1.5f, 1.5f); -// spawnEntityAt(waterQueen, randomPos, true, false); -// } -// } -// -// private void spawnWaterSlime() { -// -// int[] pickedLanes = new Random().ints(0, ServiceLocator.getMapService().getHeight() ) -// -// .distinct().limit(5).toArray(); -// for (int i = 0; i < NUM_GRUNTS; i++) { -// GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); -// Entity waterSlime = NPCFactory.createSplittingWaterSlime(); -// waterSlime.setScale(1.5f, 1.5f); -// spawnEntityAt(waterSlime, randomPos, true, false); -// } -// } - - private void spawnCoat() { - Entity gregMob = NPCFactory.createCoat(100); - gregMob.setScale(1.5f, 1.5f); - spawnEntityAt(gregMob, new GridPoint2(17, 4), false, false); - } - - /** - * Creates multiple projectiles that travel simultaneous. They all have same - * the starting point but different destinations. - * - * @param position The position of the Entity that's shooting the projectile. - * @param targetLayer The enemy layer of the "shooter". - * @param direction The direction the projectile should head towards. - * @param space The space between the projectiles' destination. - * @param speed The speed of the projectiles. - * @param quantity The amount of projectiles to spawn. - */ - private void spawnMultiProjectile(Vector2 position, short targetLayer, int direction, int space, Vector2 speed, int quantity) { - int half = quantity / 2; - for (int i = 0; i < quantity; i++) { - spawnProjectile(position, targetLayer, space * half, direction, speed); - --half; - } - } - - /** - * Returns projectile that can do an area of effect damage - * - * @param position The position of the Entity that's shooting the projectile. - * @param targetLayer The enemy layer of the "shooter". - * @param direction The direction the projectile should head towards. - * @param speed The speed of the projectiles. - * @param effect Type of effect. - * @param aoe Whether it is an aoe projectile. - */ - private void spawnEffectProjectile(Vector2 position, short targetLayer, int direction, Vector2 speed, - ProjectileEffects effect, boolean aoe) { - Entity Projectile = ProjectileFactory.createEffectProjectile(targetLayer, new Vector2(direction, position.y), speed, effect, aoe); - Projectile.setPosition(position); - spawnEntity(Projectile); - } - - /** - * Spawns a pierce fireball. - * Pierce fireball can go through targetlayers without disappearing but damage - * will still be applied. - * - * @param position The position of the Entity that's shooting the projectile. - * @param targetLayer The enemy layer of the "shooter". - * @param direction The direction the projectile should head towards. - * @param speed The speed of the projectiles. - */ - private void spawnPierceFireBall(Vector2 position, short targetLayer, int direction, Vector2 speed) { - Entity projectile = ProjectileFactory.createPierceFireBall(targetLayer, new Vector2(direction, position.y), speed); - projectile.setPosition(position); - spawnEntity(projectile); - } - - /** - * Spawns a ricochet fireball - * Ricochet fireballs bounce off targets with a specified maximum count of 3 - * Possible extensions: Make the bounce count flexible with a param. - * - * @param position The position of the Entity that's shooting the projectile. - * @param targetLayer The enemy layer of the "shooter". - * @param direction The direction the projectile should head towards. - * @param speed The speed of the projectiles. - */ - private void spawnRicochetFireball(Vector2 position, short targetLayer, int direction, Vector2 speed) { - // Bounce count set to 0. - Entity projectile = ProjectileFactory.createRicochetFireball(targetLayer, new Vector2(direction, position.y), speed, 0); - projectile.setPosition(position); - spawnEntity(projectile); - } - - /** - * Spawns a split firework fireball. - * Splits into mini projectiles that spreads out after collision. - * - * @param position The position of the Entity that's shooting the projectile. - * @param targetLayer The enemy layer of the "shooter". - * @param direction The direction the projectile should towards. - * @param speed The speed of the projectiles. - * @param amount The amount of projectiles appearing after collision. - */ - private void spawnSplitFireWorksFireBall(Vector2 position, short targetLayer, int direction, Vector2 speed, int amount) { - Entity projectile = ProjectileFactory.createSplitFireWorksFireball(targetLayer, new Vector2(direction, position.y), speed, amount); - projectile.setPosition(position); - spawnEntity(projectile); - } - - private void spawnWeaponTower() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(5, 1); - - for (int i = 0; i < NUM_WEAPON_TOWERS + 7 ; i++) { - GridPoint2 randomPos1 = RandomUtils.random(minPos, maxPos); - GridPoint2 randomPos2 = RandomUtils.random(minPos, maxPos); - Entity wallTower = TowerFactory.createWallTower(); - Entity fireTower = TowerFactory.createFireTower(); - Entity stunTower = TowerFactory.createStunTower(); - spawnEntityAt(fireTower, randomPos1, true, true); - spawnEntityAt(stunTower, randomPos2, true, true); - spawnEntityAt(wallTower, randomPos2, true, true); - } - } - - // * TEMPORARY FOR TESTING - private void spawnFireTowerAt(int x, int y) { - GridPoint2 pos = new GridPoint2(x, y); - Entity fireTower = TowerFactory.createFireTower(); - - spawnEntityAt(fireTower, pos, true, true); - } - private void spawnDroidTowerAt(int x, int y) { - GridPoint2 pos = new GridPoint2(x, y); - Entity droidTower = TowerFactory.createDroidTower(); - - spawnEntityAt(droidTower, pos, true, true); - } - - private void spawnTNTTower() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(5, 1); - - for (int i = 0; i < NUM_WEAPON_TOWERS + 5; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity weaponTower = TowerFactory.createTNTTower(); - spawnEntityAt(weaponTower, randomPos, true, true); - } - - } - private void spawnFireWorksTower() { - GridPoint2 minPos = new GridPoint2(0, 2); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(1, 1); - - for (int i = 0; i < NUM_WEAPON_TOWERS; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity FireWorksTower = TowerFactory.createFireworksTower(); - spawnEntityAt(FireWorksTower, randomPos, true, true); - } - - } - private void spawnPierceTower() { - GridPoint2 minPos = new GridPoint2(0, 2); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(3, 3); - - for (int i = 0; i < NUM_WEAPON_TOWERS; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity PierceTower = TowerFactory.createPierceTower(); - spawnEntityAt(PierceTower, randomPos, true, true); - } - - } - private void spawnRicochetTower() { - GridPoint2 minPos = new GridPoint2(0, 2); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(0, 3); - - for (int i = 0; i < NUM_WEAPON_TOWERS; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity RicochetTower = TowerFactory.createRicochetTower(); - spawnEntityAt(RicochetTower, randomPos, true, true); - } - - } - - private void spawnBombship() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(5, 1); - Entity bombship = BombshipFactory.createBombship(); - spawnEntityAt(bombship, minPos, true, true); - } - - private void spawnDroidTower() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(5, 1); - - for (int i = 0; i < NUM_WEAPON_TOWERS + 5; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity weaponTower = TowerFactory.createDroidTower(); - spawnEntityAt(weaponTower, randomPos, true, false); - } - } - - private void playMusic() { - Music music = ServiceLocator.getResourceService().getAsset(BACKGROUND_MUSIC, Music.class); - music.setLooping(true); - music.setVolume(0.3f); - music.play(); - } private void loadAssets() { logger.debug("Loading assets"); @@ -941,17 +473,6 @@ private void spawnScrap() { } } - private void spawnIncome() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); - - for (int i = 0; i < 50; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity towerfactory = TowerFactory.createIncomeTower(); - spawnEntityAt(towerfactory, randomPos, true, true); - } - } - /** * Creates the scanners (one per lane) that detect absence of towers and presence of mobs, * and trigger engineer spawning diff --git a/source/core/src/main/com/csse3200/game/components/EffectComponent.java b/source/core/src/main/com/csse3200/game/components/EffectComponent.java index 32b32e3d3..db110417e 100644 --- a/source/core/src/main/com/csse3200/game/components/EffectComponent.java +++ b/source/core/src/main/com/csse3200/game/components/EffectComponent.java @@ -54,9 +54,6 @@ public void update() { // apply slow effect if (mob) { - if (target == null) { - return; - } if (slowFlag) { isSlowed = true; Vector2 half_speed = new Vector2(defaultTargetSpeed.x / 2, defaultTargetSpeed.y / 2); @@ -85,9 +82,6 @@ public void update() { } targetPhysics.setSpeed(STUN_SPEED); } else if (isStunned) { - if (target == null) { - return; - } isStunned = false; targetPhysics.setSpeed(defaultTargetSpeed); } diff --git a/source/core/src/main/com/csse3200/game/components/EffectsComponent.java b/source/core/src/main/com/csse3200/game/components/EffectsComponent.java index 596bb71f2..4fb249d6d 100644 --- a/source/core/src/main/com/csse3200/game/components/EffectsComponent.java +++ b/source/core/src/main/com/csse3200/game/components/EffectsComponent.java @@ -2,20 +2,13 @@ import java.util.ArrayList; -import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.physics.box2d.Fixture; -import com.csse3200.game.ai.tasks.AITaskComponent; -import com.csse3200.game.components.tower.TowerUpgraderComponent; import com.csse3200.game.entities.Entity; import com.csse3200.game.physics.BodyUserData; import com.csse3200.game.physics.PhysicsLayer; import com.csse3200.game.physics.components.HitboxComponent; -import com.csse3200.game.physics.components.PhysicsMovementComponent; import com.csse3200.game.services.ServiceLocator; -import com.badlogic.gdx.utils.Timer; -import com.badlogic.gdx.utils.Timer.Task; - import com.badlogic.gdx.utils.Array; /** @@ -102,6 +95,7 @@ public void applySingleEffect(ProjectileEffects effect, Entity targetEntity) { } effectComponent.applyEffect(effect, hostEntity, targetEntity); } + /** * Used for aoe projectiles to apply effects to all entities within the area of effect (radius). * @param effect effect to be applied to entities within radius @@ -136,132 +130,4 @@ public void applyAoeEffect(ProjectileEffects effect) { effectComponent.applyEffect(effect, hostEntity, targetEntity); } } - - /** - * Deals damage to target based on hosts' CombatStatsComponent - * @param target CombatStatsComponent of entity hit by projectile - * @param host CombatStatsComponent of projectile - */ - private void fireballEffect(CombatStatsComponent target, CombatStatsComponent host) { - target.hit(host); - } - -// /** -// * Applies 5 ticks of damage from hosts' CombatStatsComponent over 5 seconds -// * @param target CombatStatsComponent of entity hit by projectile -// * @param host CombatStatsComponent of projectile -// */ -// private void burnEffect(CombatStatsComponent target, CombatStatsComponent host) { -// // Ensure burn effects aren't applied multiple times by same projectile -// if (burnEntities.contains(target, false)) { -// return; -// } -// burnEntities.add(target); -// // Create a timer task to apply the effect repeatedly -// int numberOfTicks = 5; -// long delay = 1; -// Timer.schedule(new Timer.Task() { -// private int count = 0; -// -// @Override -// public void run() { -// if (count < numberOfTicks) { -// target.hit(host); -// count++; -// } else { -// // Ensure to cancel the task when it's done -// this.cancel(); -// } -// } -// }, delay, delay); -// } - - /** - * Applies slow effect to targetEntity. If entity is a mob, speed - * and firing rate will be slowed. If entity is a tower, firing rate - * will be slowed - * @param targetEntity Entity for slow effect to be applied to - */ - private void slowEffect(Entity targetEntity) { - boolean towerFlag = false; - boolean mobFlag = false; - - PhysicsMovementComponent targetPhysics = null; - float xSpeed = 0; - float ySpeed = 0; - - // Create a timer task to apply the effect repeatedly - if (PhysicsLayer.contains(PhysicsLayer.HUMANS, targetEntity.getComponent(HitboxComponent.class).getLayer())) { - // towers - towerFlag = true; - targetEntity.getEvents().trigger("upgradeTower", TowerUpgraderComponent.UPGRADE.FIRERATE, -30); - } else if (PhysicsLayer.contains(PhysicsLayer.NPC, targetEntity.getComponent(HitboxComponent.class).getLayer())) { - // mobs - mobFlag = true; - targetPhysics = targetEntity.getComponent(PhysicsMovementComponent.class); - if (targetPhysics == null) { - return; - } - - // Halve the mob speed - xSpeed = targetPhysics.getSpeed().x; - ySpeed = targetPhysics.getSpeed().y; - targetPhysics.setSpeed(new Vector2(xSpeed/2, ySpeed/2)); - } else { - return; - } - - // Reset speed - boolean finalTowerFlag = towerFlag; - boolean finalMobFlag = mobFlag; - PhysicsMovementComponent finalTargetPhysics = targetPhysics; - float finalXSpeed = xSpeed; - float finalYSpeed = ySpeed; - Timer.schedule(new Task() { - @Override - public void run() { - if (finalTowerFlag) { - targetEntity.getEvents().trigger("upgradeTower", TowerUpgraderComponent.UPGRADE.FIRERATE, 30); - } else if (finalMobFlag) { - finalTargetPhysics.setSpeed(new Vector2(finalXSpeed, finalYSpeed)); - } - } - }, 5); // 5 seconds delay - } - - /** - * Applies stun effect to a taget entity. - * @param targetEntity Entity for stun effect to be applied to. - */ - private void stunEffect(Entity targetEntity) { - CombatStatsComponent hostCombatStats = targetEntity.getComponent(CombatStatsComponent.class); - AITaskComponent taskComponent = targetEntity.getComponent(AITaskComponent.class); - - if (hostCombatStats == null || taskComponent == null) { - return; - } - - hostCombatStats.setBaseAttack(0); - - if (stunnedEntities.contains(targetEntity)) { - return; - } - - taskComponent.disposeAll(); - stunnedEntities.add(targetEntity); - - new java.util.Timer().schedule( - new java.util.TimerTask() { - @Override - public void run() { - taskComponent.restore(); - for (int i = 0; i < stunnedEntities.size(); i++) { - if (stunnedEntities.get(i).equals(targetEntity)) { - stunnedEntities.remove(stunnedEntities.get(i)); - } - } - this.cancel(); - } - }, 5000); - } } \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/components/gamearea/CurrencyDisplay.java b/source/core/src/main/com/csse3200/game/components/gamearea/CurrencyDisplay.java index 858563858..b110de999 100644 --- a/source/core/src/main/com/csse3200/game/components/gamearea/CurrencyDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/gamearea/CurrencyDisplay.java @@ -1,5 +1,6 @@ package com.csse3200.game.components.gamearea; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.Texture; @@ -56,11 +57,17 @@ private void addActors() { ServiceLocator.getCurrencyService().getCrystal().getAmount()); table.add(scrapsTb).width(scrapsTb.getWidth() * 0.5f).height(scrapsTb.getHeight() * 0.5f); + table.row(); table.add(crystalsTb).width(crystalsTb.getWidth() * 0.5f).height(crystalsTb.getHeight() * 0.5f); stage.addActor(table); - scrapsTb.addAction(new SequenceAction(Actions.fadeIn(4f))); - crystalsTb.addAction(new SequenceAction(Actions.fadeIn(8f))); + scrapsTb.setPosition(table.getX() - 200f, Gdx.graphics.getHeight() - 205f); + scrapsTb.addAction(new SequenceAction(Actions.moveTo(table.getX() + 20f, Gdx.graphics.getHeight() - 205f, + 1f, Interpolation.fastSlow))); + + crystalsTb.setPosition(table.getX() - 200f, Gdx.graphics.getHeight() - 268f); + crystalsTb.addAction(new SequenceAction(Actions.moveTo(table.getX() + 20f, Gdx.graphics.getHeight() - 268f, + 1f, Interpolation.fastSlow))); } private TextButton createButton(String imageFilePath, int value) { diff --git a/source/core/src/main/com/csse3200/game/components/gamearea/EngineerCountDisplay.java b/source/core/src/main/com/csse3200/game/components/gamearea/EngineerCountDisplay.java index 6334e1b4a..09d2d3d73 100644 --- a/source/core/src/main/com/csse3200/game/components/gamearea/EngineerCountDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/gamearea/EngineerCountDisplay.java @@ -1,8 +1,10 @@ package com.csse3200.game.components.gamearea; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.scenes.scene2d.Touchable; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; @@ -57,20 +59,25 @@ private void addActors() { table.add(engineerTb).width(engineerTb.getWidth() * 0.5f).height(engineerTb.getHeight() * 0.5f); stage.addActor(table); - engineerTb.addAction(new SequenceAction(Actions.fadeIn(4f))); + // Animate the engineer count label + engineerTb.setPosition(table.getX() - 200f, Gdx.graphics.getHeight() - 145f); + engineerTb.addAction(new SequenceAction(Actions.moveTo(table.getX() + 20f, Gdx.graphics.getHeight() - 145, + 1f, Interpolation.fastSlow))); } /** * Updates the engineer count on the UI component */ public void updateCount() { - int currentCount = ServiceLocator.getGameEndService().getEngineerCount(); - String text = String.format("%d", currentCount); - engineerTb.getLabel().setText(text); - if (currentCount < ServiceLocator.getGameEndService().getThreshold()) { + if (engineerTb != null) { // fix for null pointer exception + int currentCount = ServiceLocator.getGameEndService().getEngineerCount(); + String text = String.format("%d", currentCount); + engineerTb.getLabel().setText(text); + if (currentCount < ServiceLocator.getGameEndService().getThreshold()) { // engineerTb.addAction(Actions.color(Color.RED, 0.5f, Interpolation.swingIn)); - engineerTb.addAction(Actions.forever(new SequenceAction(Actions.fadeOut(0.5f), - Actions.fadeIn(0.5f)))); + engineerTb.addAction(Actions.forever(new SequenceAction(Actions.fadeOut(0.5f), + Actions.fadeIn(0.5f)))); + } } } diff --git a/source/core/src/main/com/csse3200/game/components/gamearea/GameAreaDisplay.java b/source/core/src/main/com/csse3200/game/components/gamearea/GameAreaDisplay.java index 3db923bca..9a8149869 100644 --- a/source/core/src/main/com/csse3200/game/components/gamearea/GameAreaDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/gamearea/GameAreaDisplay.java @@ -15,7 +15,7 @@ */ public class GameAreaDisplay extends UIComponent { private static final Logger logger = LoggerFactory.getLogger(GameAreaDisplay.class); - + private static final String DEFAULT_STYLE = "default"; private String gameAreaName = ""; private Label title; @@ -45,10 +45,10 @@ private Dialog createTowerDetailsDialog() { Label.LabelStyle labelStyle = new Label.LabelStyle(); labelStyle.font = new BitmapFont(); labelStyle.fontColor = Color.WHITE; - skin.add("default", labelStyle); + skin.add(DEFAULT_STYLE, labelStyle); // Create the dialog using the registered label style - Dialog dialog = new Dialog("Tower Details", skin,"default"); + Dialog dialog = new Dialog("Tower Details", skin, DEFAULT_STYLE); dialog.text("Health: 100"); // Set tower health here dialog.getContentTable().row(); dialog.text("Attack: 50"); // Set tower attack here @@ -56,8 +56,9 @@ private Dialog createTowerDetailsDialog() { dialog.setVisible(false); // Hide the dialog initially return dialog; } + private void addActors() { - title = new Label(this.gameAreaName, skin, "default"); + title = new Label(this.gameAreaName, skin, DEFAULT_STYLE); stage.addActor(title); } @@ -68,7 +69,6 @@ public void draw(SpriteBatch batch) { float offsetY = 30f; title.setPosition(offsetX, screenHeight - offsetY); - } @Override diff --git a/source/core/src/main/com/csse3200/game/components/maingame/MainGameActions.java b/source/core/src/main/com/csse3200/game/components/maingame/MainGameActions.java index 7253f6d3b..bbdd88acc 100644 --- a/source/core/src/main/com/csse3200/game/components/maingame/MainGameActions.java +++ b/source/core/src/main/com/csse3200/game/components/maingame/MainGameActions.java @@ -21,7 +21,19 @@ public MainGameActions(GdxGame game) { public void create() { entity.getEvents().addListener("exit", this::onExit); entity.getEvents().addListener("lose", this::onLose); - //entity.getEvents().addListener("win", this::onWin); + entity.getEvents().addListener("win", this::WinningScreen); + entity.getEvents().addListener("Next Level", this::NextLevel); + } + + private void NextLevel() { + logger.info("Next level"); + game.setScreen(GdxGame.ScreenType.Next_Screen); + + } + + private void WinningScreen() { + logger.info("Uer Won the game"); + game.setScreen(GdxGame.ScreenType.Win_Screen); } /** @@ -35,6 +47,4 @@ private void onExit() { private void onLose() { game.setScreen(GdxGame.ScreenType.LOSING_SCREEN); } - -// private void onWin() { game.setScreen(GdxGame.ScreenType.WIN_SCREEN);} // TODO : Uncomment this once win screen implemented } diff --git a/source/core/src/main/com/csse3200/game/components/maingame/MainGameDisplay.java b/source/core/src/main/com/csse3200/game/components/maingame/MainGameDisplay.java index f9d6c4de1..bb0e32a50 100644 --- a/source/core/src/main/com/csse3200/game/components/maingame/MainGameDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/maingame/MainGameDisplay.java @@ -15,7 +15,6 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Array; import com.csse3200.game.GdxGame; -import com.csse3200.game.components.pausemenu.PauseMenuButtonComponent; import com.csse3200.game.entities.Entity; import com.csse3200.game.entities.factories.PauseMenuFactory; import com.csse3200.game.screens.TowerType; @@ -32,6 +31,7 @@ public class MainGameDisplay extends UIComponent { private static final Logger logger = LoggerFactory.getLogger(MainGameDisplay.class); private static final float Z_INDEX = 2f; + private static final String SHORTCUT_FONT = "small"; private final Table towerTable = new Table(); private final Table buttonTable = new Table(); private final Table progressTable = new Table(); @@ -86,19 +86,83 @@ private void addActors() { // Create and position the tables that will hold the buttons. // Contains the tower build menu buttons - towerTable.top().padTop(50f); + towerTable.top().padTop(80f); towerTable.setFillParent(true); // Contains other buttons (just pause at this stage) - buttonTable.top().right().padTop(50f).padRight(80f); + buttonTable.top().right().padTop(80f).padRight(80f); buttonTable.setFillParent(true); progressTable.top().center().setWidth(500f); progressTable.setFillParent(true); - levelNameTable.top().left().padLeft(20f).padTop(20f); + levelNameTable.center().top().padLeft(20f).padTop(20f).pad(20f); levelNameTable.setFillParent(true); + // set the towerTypes if they aren't already + setTowers(); + + // Update the centrally located towerTypes list - + ServiceLocator.setTowerTypes(towers); + + // create the tower buttons, pause button, and their associated listeners + createTowerButtons(); + TextButton pauseBtn = createPauseButton(); + + progressbar = new LevelProgressBar(500, 10); + + levelNameTable.setSkin(getSkin()); + levelNameTable.add(this.level, "default"); + + // Scale all the tower build buttons down + // Add all buttons to their respective tables and position them + towerTable.setSkin(getSkin()); + towerTable.add(tower1).padRight(10f); + towerTable.add(tower2).padRight(10f); + towerTable.add(tower3).padRight(10f); + towerTable.add(tower4).padRight(10f); + towerTable.add(tower5).padRight(10f); + towerTable.row(); + towerTable.add("1", SHORTCUT_FONT); + towerTable.add("2", SHORTCUT_FONT); + towerTable.add("3", SHORTCUT_FONT); + towerTable.add("4", SHORTCUT_FONT); + towerTable.add("5", SHORTCUT_FONT); + towerTable.row().colspan(5).pad(20f); + towerTable.add(progressbar).fillX(); + + buttonTable.add(pauseBtn); + + // Add tables to the stage + + stage.addActor(buttonTable); + stage.addActor(towerTable); + stage.addActor(levelNameTable); + + // Animate the tower select buttons + int tower1Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 + 400; + int tower2Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 + 240; + int tower3Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 + 80; + int tower4Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 - 80; + int tower5Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 - 240; + animateTowerButton(tower1, tower1Gap, 230); + animateTowerButton(tower2, tower2Gap, 230); + animateTowerButton(tower3, tower3Gap, 230); + animateTowerButton(tower4, tower4Gap, 230); + animateTowerButton(tower5, tower5Gap, 230); + + TooltipManager tm = TooltipManager.getInstance(); + tm.initialTime = 3; + tm.hideAll(); + } + + @Override + public void draw(SpriteBatch batch) { + // draw is handled by the stage + towerUpdate(); + } + + private void setTowers() { // Stores tower defaults, in case towers haven't been set in the tower select screen TowerType[] defaultTowers = { TowerType.TNT, @@ -117,20 +181,19 @@ private void addActors() { // If no towers set, populate with default towers if (towers.isEmpty() || towers.size < 5) { - if (towers.isEmpty()) { - towers.addAll(defaultTowers); - } else { - for (TowerType tower : defaultTowers) { - if (towers.size < 5 && !towers.contains(tower, false)) { - towers.add(tower); - } +// if (towers.isEmpty()) { +// towers.addAll(defaultTowers); +// } else { + for (TowerType tower : defaultTowers) { + if (towers.size < 5 && !towers.contains(tower, true)) { + towers.add(tower); } } } - - // Update the centrally located towerTypes list - ServiceLocator.setTowerTypes(towers); + } + private void createTowerButtons() { tower1 = new ImageButton(skin, towers.get(0).getSkinName()); towerButtons.add(tower1); tower2 = new ImageButton(skin, towers.get(1).getSkinName()); @@ -142,12 +205,43 @@ private void addActors() { tower5 = new ImageButton(skin, towers.get(4).getSkinName()); towerButtons.add(tower5); + int i = 0; + for (ImageButton button : towerButtons) { + // Triggers an event when the button is pressed. + int finalI = i; + button.addListener( + new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + + TowerType selected = ServiceLocator.getCurrencyService().getTower(); + if (selected == towers.get(finalI) ) { + ServiceLocator.getCurrencyService().setTowerType(null); + + towerToggle(null); + + } else { + ServiceLocator.getCurrencyService().setTowerType(towers.get(finalI)); + + towerToggle(button); + + } + click.play(0.4f); + } + }); + TextTooltip tower1Tooltip = new TextTooltip(towers.get(i).getDescription(), getSkin()); + button.addListener(tower1Tooltip); + i++; + } + } + + private TextButton createPauseButton() { TextButton pauseBtn = ButtonFactory.createButton("Pause"); // Starting animation for pause button - pauseBtn.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - 150); - pauseBtn.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - 200, - Gdx.graphics.getHeight() - 150, 1f, Interpolation.fastSlow))); + pauseBtn.setPosition((float)Gdx.graphics.getWidth(), (Gdx.graphics.getHeight() - 150f)); + pauseBtn.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - 200f, + Gdx.graphics.getHeight() - 150f, 1f, Interpolation.fastSlow))); // Spawns a pause menu when the button is pressed. pauseBtn.addListener( @@ -179,181 +273,7 @@ public boolean keyUp(InputEvent event, int keycode) { return false; } }); - - // Triggers an event when the button is pressed. - tower1.addListener( - new ClickListener() { - @Override - public void clicked(InputEvent event, float x, float y) { - - TowerType selected = ServiceLocator.getCurrencyService().getTower(); - if (selected == towers.get(0) ) { - ServiceLocator.getCurrencyService().setTowerType(null); - - towerToggle(null); - - } else { - ServiceLocator.getCurrencyService().setTowerType(towers.get(0)); - - towerToggle(tower1); - - } - click.play(0.4f); - } - }); - TextTooltip tower1Tooltip = new TextTooltip(towers.get(0).getDescription(), getSkin()); - tower1.addListener(tower1Tooltip); - - // Triggers an event when the button is pressed. - tower2.addListener( - new ClickListener() { - @Override - public void clicked(InputEvent event, float x, float y) { - - TowerType selected = ServiceLocator.getCurrencyService().getTower(); - if (selected == towers.get(1) ) { - ServiceLocator.getCurrencyService().setTowerType(null); - - towerToggle(null); - - } else { - ServiceLocator.getCurrencyService().setTowerType(towers.get(1)); - - towerToggle(tower2); - - } - click.play(0.4f); - } - }); - TextTooltip tower2Tooltip = new TextTooltip(towers.get(1).getDescription(), getSkin()); - tower2.addListener(tower2Tooltip); - - tower3.addListener( - new ClickListener() { - @Override - public void clicked(InputEvent event, float x, float y) { - - TowerType selected = ServiceLocator.getCurrencyService().getTower(); - if (selected == towers.get(2)) { - ServiceLocator.getCurrencyService().setTowerType(null); - - towerToggle(null); - - } else { - ServiceLocator.getCurrencyService().setTowerType(towers.get(2)); - if (ServiceLocator.getCurrencyService().getScrap().getAmount() - >= Integer.parseInt(towers.get(2).getPrice())) { - - towerToggle(tower3); - - } else { - tower3.setDisabled(true); - } - } - click.play(0.4f); - } - }); - - TextTooltip tower3Tooltip = new TextTooltip(towers.get(3).getDescription(), getSkin()); - tower3.addListener(tower3Tooltip); - - tower4.addListener( - new ClickListener() { - @Override - public void clicked(InputEvent event, float x, float y) { - - TowerType selected = ServiceLocator.getCurrencyService().getTower(); - if (selected == towers.get(3)) { - ServiceLocator.getCurrencyService().setTowerType(null); - - towerToggle(null); - - } else { - ServiceLocator.getCurrencyService().setTowerType(towers.get(3)); - - towerToggle(tower4); - - } - click.play(0.4f); - } - }); - TextTooltip tower4Tooltip = new TextTooltip(towers.get(3).getDescription(), getSkin()); - tower4.addListener(tower4Tooltip); - - tower5.addListener( - new ClickListener() { - @Override - public void clicked(InputEvent event, float x, float y) { - - TowerType selected = ServiceLocator.getCurrencyService().getTower(); - if (selected == towers.get(4)) { - ServiceLocator.getCurrencyService().setTowerType(null); - - towerToggle(null); - - } else { - ServiceLocator.getCurrencyService().setTowerType(towers.get(4)); - - towerToggle(tower5); - - } - click.play(0.4f); - } - }); - TextTooltip tower5Tooltip = new TextTooltip(towers.get(4).getDescription(), getSkin()); - tower5.addListener(tower5Tooltip); - - progressbar = new LevelProgressBar(500, 10); - - levelNameTable.setSkin(getSkin()); - levelNameTable.add(this.level, "title"); - - // Scale all the tower build buttons down - // Add all buttons to their respective tables and position them - towerTable.setSkin(getSkin()); - towerTable.add(tower1).padRight(10f); - towerTable.add(tower2).padRight(10f); - towerTable.add(tower3).padRight(10f); - towerTable.add(tower4).padRight(10f); - towerTable.add(tower5).padRight(10f); - towerTable.row(); - towerTable.add("1", "small"); - towerTable.add("2", "small"); - towerTable.add("3", "small"); - towerTable.add("4", "small"); - towerTable.add("5", "small"); - towerTable.row().colspan(5).pad(20f); - towerTable.add(progressbar).fillX(); - - buttonTable.add(pauseBtn); - - // Add tables to the stage - - stage.addActor(buttonTable); - stage.addActor(towerTable); - stage.addActor(levelNameTable); - - // Animate the tower select buttons - int tower1Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 + 400; - int tower2Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 + 240; - int tower3Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 + 80; - int tower4Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 - 80; - int tower5Gap = Gdx.graphics.getWidth() /2 + (int) towerTable.getX()/2 - 240; - animateTowerButton(tower1, tower1Gap, 230); - animateTowerButton(tower2, tower2Gap, 230); - animateTowerButton(tower3, tower3Gap, 230); - animateTowerButton(tower4, tower4Gap, 230); - animateTowerButton(tower5, tower5Gap, 230); - - TooltipManager tm = TooltipManager.getInstance(); - tm.initialTime = 3; - tm.hideAll(); - } - - @Override - public void draw(SpriteBatch batch) { - // draw is handled by the stage - towerUpdate(); + return pauseBtn; } /** @@ -369,6 +289,10 @@ public void updateLevelProgressBar() { * depending on button selection and currency balance */ private void towerUpdate() { + // Check for small tower array + if (towers.size < 5) { + setTowers(); + } // no tower selected, set all to off if (ServiceLocator.getCurrencyService().getTower() == null) { // toggle all buttons to off diff --git a/source/core/src/main/com/csse3200/game/components/maingame/UIElementsDisplay.java b/source/core/src/main/com/csse3200/game/components/maingame/UIElementsDisplay.java index 6b0d93bf1..cd005fe8b 100644 --- a/source/core/src/main/com/csse3200/game/components/maingame/UIElementsDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/maingame/UIElementsDisplay.java @@ -12,22 +12,16 @@ import com.csse3200.game.services.ServiceLocator; import com.csse3200.game.ui.ButtonFactory; import com.csse3200.game.ui.UIComponent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.swing.event.ChangeEvent; -import java.security.Provider; - /** * Displays a button to represent the remaining mobs left in the current wave and a button to skip to the next wave. */ public class UIElementsDisplay extends UIComponent { - private static final Logger logger = LoggerFactory.getLogger(UIElementsDisplay.class); private static final float Z_INDEX = 2f; private final Table buttonTable = new Table(); private TextButton remainingMobsButton; private TextButton timerButton; + private long time = 0; @Override public void create() { @@ -43,16 +37,15 @@ private void addActors() { remainingMobsButton = ButtonFactory.createButton("Mobs:" + ServiceLocator.getWaveService().getEnemyCount()); - remainingMobsButton.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - 230); - remainingMobsButton.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - 218, - Gdx.graphics.getHeight() - 230, 1f, Interpolation.fastSlow))); + remainingMobsButton.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - 230f); + remainingMobsButton.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - 217f, + Gdx.graphics.getHeight() - 230f, 1f, Interpolation.fastSlow))); - buttonTable.top().right().padTop(130f).padRight(80f); + buttonTable.top().right().padTop(160f).padRight(80f); buttonTable.setFillParent(true); buttonTable.add(remainingMobsButton).right(); - buttonTable.row(); - buttonTable.add(timerButton); + stage.addActor(buttonTable); @@ -81,11 +74,12 @@ public void createTimerButton() { timerButton = ButtonFactory.createButton("Next wave in:" + (ServiceLocator.getWaveService().getNextWaveTime() / 1000)); - timerButton.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - 300); - timerButton.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - 445, - Gdx.graphics.getHeight() - 300, 1f, Interpolation.fastSlow))); + timerButton.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - 300f); + timerButton.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - 435f, + Gdx.graphics.getHeight() - 300f, 1f, Interpolation.fastSlow))); + timerButton.setDisabled(true); buttonTable.row(); - buttonTable.add(timerButton).padRight(10f); + buttonTable.add(timerButton); } /** @@ -96,20 +90,22 @@ public void updateTimerButton() { int totalSecs = (int) ((ServiceLocator.getWaveService().getNextWaveTime() - ServiceLocator.getTimeSource().getTime()) / 1000); - // TODO : THESE SHOULD BE REMOVED AND PLACED WHEREVER THE BOSS MOB GETS SPAWNED - if (totalSecs % 20 == 0) { - ServiceLocator.getMapService().shakeCameraMap(); - ServiceLocator.getMapService().shakeCameraGrid(); - } int seconds = totalSecs % 60; int minutes = (totalSecs % 3600) / 60; String finalTime = String.format("%02d:%02d", minutes, seconds); if (ServiceLocator.getTimeSource().getTime() < ServiceLocator.getWaveService().getNextWaveTime()) { if (!findActor(timerButton)) { + remainingMobsButton.setDisabled(false); createTimerButton(); } timerButton.setText("Next wave in: " + finalTime); + time = ServiceLocator.getTimeSource().getTime(); } else { + if (ServiceLocator.getTimeSource().getTime() < time + 2000) { + ServiceLocator.getMapService().shakeCameraMap(); + ServiceLocator.getMapService().shakeCameraGrid(); + } + remainingMobsButton.setDisabled(true); timerButton.addAction(new SequenceAction(Actions.fadeOut(1f), Actions.removeActor())); stage.act(); stage.draw(); diff --git a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java index 2f57c0ecc..7562fd92c 100644 --- a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java +++ b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java @@ -2,7 +2,6 @@ import com.csse3200.game.GdxGame; import com.csse3200.game.components.Component; -import com.csse3200.game.screens.HelpScreen; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java index f0a67c1ff..2fdc6ddf1 100644 --- a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java @@ -53,14 +53,13 @@ private void addActors() { cursorPixmap.dispose(); // Dispose of the Pixmap to release resources table = new Table(); - table1 = new Table(); table.setFillParent(true); - table1.setFillParent(true); + stage.addActor(table); - Image title = - new Image( - ServiceLocator.getResourceService() - .getAsset("images/background/main_menu/main_menu_bg.png", Texture.class)); + Texture backgroundTexture = ServiceLocator.getResourceService().getAsset("images/background/main_menu/main_menu_bg.png", Texture.class); + Image title = new Image(backgroundTexture); + title.setFillParent(true); + table.addActorAt(0, title); title.setWidth(Gdx.graphics.getWidth()); title.setHeight(Gdx.graphics.getHeight()); title.setPosition(0, 0); @@ -126,18 +125,13 @@ public void changed(ChangeEvent changeEvent, Actor actor) { float padTopOtherBtns = 15f / originalScreenHeight * Gdx.graphics.getHeight(); - table.add(title); - table1.row(); - table1.add(startBtn).padTop(padTopStartBtn); - table1.row(); - table1.add(helpBtn).padTop(padTopOtherBtns); - table1.row(); - table1.add(settingsBtn).padTop(padTopOtherBtns); - table1.row(); - table1.add(exitBtn).padTop(padTopOtherBtns); + table.center(); + table.add(startBtn).padTop(250f).center().row(); + table.add(helpBtn).padTop(15f).center().row(); + table.add(settingsBtn).padTop(15f).center().row(); + table.add(exitBtn).padTop(15f).center().row(); stage.addActor(table); - stage.addActor(table1); } @Override diff --git a/source/core/src/main/com/csse3200/game/components/npc/ArcaneArcherAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/ArcaneArcherAnimationController.java index 71fa5359d..82c587f18 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/ArcaneArcherAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/ArcaneArcherAnimationController.java @@ -5,19 +5,14 @@ import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.ServiceLocator; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one * of the events is triggered. */ public class ArcaneArcherAnimationController extends Component { - // // For on collision sounds later - // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; - // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( - // COLLISION_SFX, Sound.class); + AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); private static final String ATTACK_SOUND = "sounds/mobs/archerArrow.mp3"; Sound attackSound = ServiceLocator.getResourceService().getAsset( diff --git a/source/core/src/main/com/csse3200/game/components/npc/CoatAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/CoatAnimationController.java index e9bf8170e..c023e0aa5 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/CoatAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/CoatAnimationController.java @@ -5,19 +5,13 @@ import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.ServiceLocator; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one * of the events is triggered. */ public class CoatAnimationController extends Component { - // // For on collision sounds later - // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; - // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( - // COLLISION_SFX, Sound.class); AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); private static final String ATTACK_SOUND = "sounds/mobs/coatAttack.mp3"; Sound attackSound = ServiceLocator.getResourceService().getAsset( diff --git a/source/core/src/main/com/csse3200/game/components/npc/DeflectingComponent.java b/source/core/src/main/com/csse3200/game/components/npc/DeflectingComponent.java index ab5aa645e..15fe60fcd 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/DeflectingComponent.java +++ b/source/core/src/main/com/csse3200/game/components/npc/DeflectingComponent.java @@ -60,7 +60,7 @@ public void create() { @Override public void update() { - resetHealth(); + super.update(); } /** @@ -77,8 +77,6 @@ private void deflectProj(Fixture me, Fixture other) { if (deflectLimitAmount-- <= 0) { // Reached deflect limit amt, return. entity.getComponent(this.getClass()).setEnabled(false); - // reset health - resetHealth(); return; } diff --git a/source/core/src/main/com/csse3200/game/components/npc/DodgingComponent.java b/source/core/src/main/com/csse3200/game/components/npc/DodgingComponent.java index 14a3b07d9..f07028878 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/DodgingComponent.java +++ b/source/core/src/main/com/csse3200/game/components/npc/DodgingComponent.java @@ -7,6 +7,8 @@ import com.csse3200.game.physics.raycast.RaycastHit; import com.csse3200.game.services.ServiceLocator; +import java.util.Random; + /** * A component that adds a dodging event listener to the current attached * entity. The entity will dodge another entity that is presumably coming at its @@ -27,9 +29,10 @@ public class DodgingComponent extends Component { private final RaycastHit hit = new RaycastHit(); private short targetLayer; private float rangeDetection; - private float dodgeSpeed = 1.75f; + private float dodgeSpeed = 1.75f; private float originalSpeed; // Original entity vertical speed private PhysicsEngine physics; + private Random random = new Random(); // Sometimes the raycast mechanic doesn't detect the other entity because of the // target's (or self) collider size does not match. This value makes sure the @@ -92,11 +95,15 @@ public void create() { * @param mobPos The current Vector2 mob position in the map. */ public void changeTraverseDirection(Vector2 mobPos) { + int randDirection = random.nextInt(2) == 1 ? -1 : 1; + if (isTargetVisible(mobPos)) { // If mob is in the top half quadrant of the map grid, make the entity dodge // downwards. - setVerticalAngleDirection(mobPos.y > 3.5 ? mobPos.y - 15 : mobPos.y + 15); - setVerticalSpeed(dodgeSpeed); + // setVerticalAngleDirection(mobPos.y > 3.5 ? mobPos.y - 15 : mobPos.y + 15); + // Random direction + setVerticalAngleDirection(mobPos.y + (15 * randDirection)); + setVerticalSpeed(dodgeSpeed); } else { setVerticalAngleDirection(mobPos.y); setVerticalSpeed(originalSpeed); @@ -110,7 +117,7 @@ public void changeTraverseDirection(Vector2 mobPos) { * @param mobPos The current Vector2 position of the mob * @return True if a target is visible, false otherwise. */ - private boolean isTargetVisible(Vector2 mobPos) { + public boolean isTargetVisible(Vector2 mobPos) { Vector2 maxRange = new Vector2(mobPos.x - rangeDetection, mobPos.y); // check also the upper and lower boundaries of the mob with the offset y mob // detection. diff --git a/source/core/src/main/com/csse3200/game/components/npc/DragonKnightAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/DragonKnightAnimationController.java index 6d9d54215..7302a1cdc 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/DragonKnightAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/DragonKnightAnimationController.java @@ -2,19 +2,13 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one * of the events is triggered. */ public class DragonKnightAnimationController extends Component { - // // For on collision sounds later - // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; - // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( - // COLLISION_SFX, Sound.class); AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); @Override public void create() { diff --git a/source/core/src/main/com/csse3200/game/components/npc/FireWormAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/FireWormAnimationController.java index 141d43d69..28d118210 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/FireWormAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/FireWormAnimationController.java @@ -4,19 +4,13 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.ServiceLocator; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one * of the events is triggered. */ public class FireWormAnimationController extends Component { - // // For on collision sounds later - // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; - // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( - // COLLISION_SFX, Sound.class); AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); private static final String ATTACK_SOUND = "sounds/mobs/fireWormRoar.mp3"; Sound attackSound = ServiceLocator.getResourceService().getAsset( diff --git a/source/core/src/main/com/csse3200/game/components/npc/FirewizardAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/FirewizardAnimationController.java index 267c23404..b10236761 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/FirewizardAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/FirewizardAnimationController.java @@ -3,12 +3,9 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; -import java.security.SecureRandom; - public class FirewizardAnimationController extends Component { AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); @Override diff --git a/source/core/src/main/com/csse3200/game/components/npc/NecromancerAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/NecromancerAnimationController.java index 3bdad9407..dfbd4bc9a 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/NecromancerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/NecromancerAnimationController.java @@ -3,13 +3,9 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; -import java.security.SecureRandom; - public class NecromancerAnimationController extends Component { AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); - @Override public void create() { diff --git a/source/core/src/main/com/csse3200/game/components/npc/NightBorneAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/NightBorneAnimationController.java index d821f6cca..fccdfe580 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/NightBorneAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/NightBorneAnimationController.java @@ -2,7 +2,6 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one @@ -13,9 +12,7 @@ public class NightBorneAnimationController extends Component { // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( // COLLISION_SFX, Sound.class); - AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); - + AnimationRenderComponent animator; @Override public void create() { diff --git a/source/core/src/main/com/csse3200/game/components/npc/RockyAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/RockyAnimationController.java index f6743dd9d..63f850085 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/RockyAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/RockyAnimationController.java @@ -3,11 +3,8 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; -import java.security.SecureRandom; - public class RockyAnimationController extends Component { AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); @Override diff --git a/source/core/src/main/com/csse3200/game/components/npc/SkeletonAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/SkeletonAnimationController.java index d5ea57bfa..7a821ef75 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/SkeletonAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/SkeletonAnimationController.java @@ -4,19 +4,13 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.ServiceLocator; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one * of the events is triggered. */ public class SkeletonAnimationController extends Component { - // // For on collision sounds later - // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; - // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( - // COLLISION_SFX, Sound.class); AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); /** Sound variables */ private static final String ATTACK_SOUND = "sounds/mobs/boneBreak.mp3"; diff --git a/source/core/src/main/com/csse3200/game/components/npc/SplitMoblings.java b/source/core/src/main/com/csse3200/game/components/npc/SplitMoblings.java index 1127cd4ad..6b92dd1cf 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/SplitMoblings.java +++ b/source/core/src/main/com/csse3200/game/components/npc/SplitMoblings.java @@ -97,7 +97,7 @@ private void onDeath() { // left. if (amount == 1) { float newXPosition = (float) (entity.getPosition().x - OFFSET_DISTANCE); - float newYPosition = (float) (entity.getPosition().y); + float newYPosition = (entity.getPosition().y); if (withinBounds(newXPosition, newYPosition)) { spawnAdditionalMob(newXPosition, newYPosition, initialScaleX, initialScaleY); @@ -133,42 +133,35 @@ private void onDeath() { */ public void spawnAdditionalMob(float positionX, float positionY, float initialScaleX, float initialScaleY) { - // Entity waterSlime = NPCFactory.createBaseWaterSlime(60); Entity entityType; switch (mobType) { - case WATER_SLIME -> { + case WATER_SLIME -> entityType = NPCFactory.createBaseWaterSlime(baseMoblingHealth); - } - case NIGHT_BORNE -> { + case NIGHT_BORNE -> entityType = NPCFactory.createNightBorne(baseMoblingHealth); - } - case ROCKY -> { + case ROCKY -> entityType = NPCFactory.createRocky(baseMoblingHealth); - } - default -> { + default -> entityType = NPCFactory.createBaseWaterSlime(baseMoblingHealth); - } } - + entityType.setPosition(positionX, positionY); switch (mobType) { - case NIGHT_BORNE -> { + case NIGHT_BORNE -> entityType.setScale(initialScaleX, initialScaleY); - } - default -> { + + default -> entityType.setScale(initialScaleX * scaleX, initialScaleY * scaleY); - } - } + } ServiceLocator.getEntityService().register(entityType); - // ServiceLocator.getWaveService().setEnemyCount(ServiceLocator.getWaveService().getEnemyCount() + 1); - //ServiceLocator.getWaveService().setEnemyCount(ServiceLocator.getWaveService().getEnemyCount() + 1); + ServiceLocator.getWaveService().setEnemyCount(ServiceLocator.getWaveService().getEnemyCount() + 1); } /** @@ -181,12 +174,9 @@ public void spawnAdditionalMob(float positionX, float positionY, * False otherwise. */ private boolean withinBounds(float currX, float currY) { - if (currX >= MIN_X_BOUNDS + return currX >= MIN_X_BOUNDS && currX <= MAX_X_BOUNDS && currY >= MIN_Y_BOUNDS - && currY <= MAX_Y_BOUNDS) { - return true; - } - return false; + && currY <= MAX_Y_BOUNDS; } } diff --git a/source/core/src/main/com/csse3200/game/components/npc/WaterQueenAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/WaterQueenAnimationController.java index 0b8a00b75..294f312b1 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/WaterQueenAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/WaterQueenAnimationController.java @@ -4,19 +4,13 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.ServiceLocator; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one * of the events is triggered. */ public class WaterQueenAnimationController extends Component { - // // For on collision sounds later - // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; - // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( - // COLLISION_SFX, Sound.class); AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); private static final String ATTACK_SOUND = "sounds/mobs/waterQueenSpell.mp3"; Sound attackSound = ServiceLocator.getResourceService().getAsset( diff --git a/source/core/src/main/com/csse3200/game/components/npc/WaterSlimeAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/WaterSlimeAnimationController.java index 6909dad10..52163ddcb 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/WaterSlimeAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/WaterSlimeAnimationController.java @@ -2,19 +2,13 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one * of the events is triggered. */ public class WaterSlimeAnimationController extends Component { - // // For on collision sounds later - // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; - // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( - // COLLISION_SFX, Sound.class); AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); @Override public void create() { diff --git a/source/core/src/main/com/csse3200/game/components/npc/WizardAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/WizardAnimationController.java index c8c8e7073..9b4660afb 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/WizardAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/WizardAnimationController.java @@ -4,19 +4,13 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.ServiceLocator; -import java.security.SecureRandom; /** * This class listens to events relevant to a ghost entity's state and plays the animation when one * of the events is triggered. */ public class WizardAnimationController extends Component { - // // For on collision sounds later - // private static final String COLLISION_SFX = "sounds/projectiles/on_collision.mp3"; - // Sound onCollisionSound = ServiceLocator.getResourceService().getAsset( - // COLLISION_SFX, Sound.class); AnimationRenderComponent animator; - private SecureRandom rand = new SecureRandom(); /** Sound variables */ private static final String ATTACK_SOUND = "sounds/mobs/wizardSpell.mp3"; @@ -31,8 +25,6 @@ public void create() { entity.getEvents().addListener("mob_walk", this::animateWalk); entity.getEvents().addListener("mob_attack", this::animateAttack); entity.getEvents().addListener("mob_death", this::animateDeath); - - } void animateWalk() { diff --git a/source/core/src/main/com/csse3200/game/components/pausemenu/PauseMenuButtonComponent.java b/source/core/src/main/com/csse3200/game/components/pausemenu/PauseMenuButtonComponent.java index ce305311e..23fb243c9 100644 --- a/source/core/src/main/com/csse3200/game/components/pausemenu/PauseMenuButtonComponent.java +++ b/source/core/src/main/com/csse3200/game/components/pausemenu/PauseMenuButtonComponent.java @@ -1,13 +1,10 @@ package com.csse3200.game.components.pausemenu; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.InputEvent; -import com.badlogic.gdx.scenes.scene2d.InputListener; import com.badlogic.gdx.scenes.scene2d.Touchable; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; @@ -16,14 +13,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.Window; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.csse3200.game.GdxGame; -import com.csse3200.game.components.maingame.MainGameDisplay; -import com.csse3200.game.entities.factories.PauseMenuFactory; import com.csse3200.game.services.ServiceLocator; import com.csse3200.game.ui.ButtonFactory; import com.csse3200.game.ui.UIComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Implements the visual aspects of the pause menu, including button interactions. + */ public class PauseMenuButtonComponent extends UIComponent { private static final Logger logger = LoggerFactory.getLogger(PauseMenuButtonComponent.class); private static final float Z_INDEX = 2f; @@ -42,6 +40,9 @@ public PauseMenuButtonComponent(GdxGame screenSwitchHandle) { game = screenSwitchHandle; } + /** + * Sets up the buttons and window of the pause menu when it is first made. + */ @Override public void create() { super.create(); @@ -105,7 +106,6 @@ public void changed(ChangeEvent changeEvent, Actor actor) { } }); - window.setResizable(true); window.setModal(true); window.setTouchable(Touchable.enabled); @@ -119,14 +119,30 @@ public void changed(ChangeEvent changeEvent, Actor actor) { window.add(planetSelectBtn).center(); window.row(); window.add(mainMenuBtn).center(); + window.setWidth(WINDOW_SIZE_X); window.setHeight(WINDOW_SIZE_Y); window.setX((ServiceLocator.getRenderService().getStage().getWidth() / 2) - (WINDOW_SIZE_X / 2)); window.setY((ServiceLocator.getRenderService().getStage().getHeight() / 2) - (WINDOW_SIZE_Y / 2)); + // Animate the pause menu opening + window.setPosition(((float) Gdx.graphics.getWidth() / 2) - (WINDOW_SIZE_X / 2),0); + window.addAction(new SequenceAction(Actions.moveTo( + ( ((float) Gdx.graphics.getWidth() / 2) - (WINDOW_SIZE_X / 2) ), + ( ((float) Gdx.graphics.getHeight() / 2) - (WINDOW_SIZE_Y / 2) ), + 0.3f, + Interpolation.fastSlow), + Actions.fadeIn(0.3f))); + + + stage.addActor(window); } + /** + * Draws the pause menu on the game screen. + * @param batch Batch to render to. + */ @Override protected void draw(SpriteBatch batch) { // handled by stage @@ -142,11 +158,18 @@ public void loadSounds() { closeSound = ServiceLocator.getResourceService().getAsset(sounds[1], Sound.class); } + /** + * Gets the z-index of the pause menu + * @return The z-index of the pause menu + */ @Override public float getZIndex() { return Z_INDEX; } + /** + * Removes the pause menu when the entity is disposed. + */ @Override public void dispose() { click.play(0.5f); diff --git a/source/core/src/main/com/csse3200/game/components/pausemenu/PauseMenuTimeStopComponent.java b/source/core/src/main/com/csse3200/game/components/pausemenu/PauseMenuTimeStopComponent.java index b1be835cb..80ebb6db0 100644 --- a/source/core/src/main/com/csse3200/game/components/pausemenu/PauseMenuTimeStopComponent.java +++ b/source/core/src/main/com/csse3200/game/components/pausemenu/PauseMenuTimeStopComponent.java @@ -10,7 +10,6 @@ * Handles the pausing/resuming of time when the pause menu is brought up/put away. */ public class PauseMenuTimeStopComponent extends Component { - private Array freezeList; public PauseMenuTimeStopComponent() { // Not implemented diff --git a/source/core/src/main/com/csse3200/game/components/popupmenu/PopupMenuInputComponent.java b/source/core/src/main/com/csse3200/game/components/popupmenu/PopupMenuInputComponent.java index a12dd12ad..43907be2f 100644 --- a/source/core/src/main/com/csse3200/game/components/popupmenu/PopupMenuInputComponent.java +++ b/source/core/src/main/com/csse3200/game/components/popupmenu/PopupMenuInputComponent.java @@ -7,14 +7,12 @@ * This input handler only uses keyboard input. */ public class PopupMenuInputComponent extends InputComponent{ - /** TO DO: - * This component's end goal is to send a deactivation trigger when the - * user clicks on anything other than the menu entity, and reactivate it - * if the user clicks on a tower, with the new tower's stats as per its - * config file. - * Current implementation step: trigger a generic event whenever - * the mouse is clicked, with no checks for the entity clicked on. + /** + * !!! + * NOTE: THIS CLASS IS OBSOLETE + * !!! */ + public PopupMenuInputComponent() {super(1);} // Note: will need to change constructor's priority when merging with other // branches that add other input components. diff --git a/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java b/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java index a20c7464f..19f7fa624 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java @@ -21,7 +21,7 @@ public class CurrencyTask extends DefaultTask implements PriorityTask { private long endTime; private int interval; private final Scrap scrap = new Scrap(); // currency to update - private final int currencyAmount = 30; // amount of currency to update + private final int currencyAmount = 10; // amount of currency to update private static final String IDLE = "idleStartEco"; private static final String MOVE = "moveStartEco"; private static final String DEATH = "deathStartEco"; diff --git a/source/core/src/main/com/csse3200/game/components/tasks/DroidCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/DroidCombatTask.java index 502f1c4b7..3d33e15a2 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/DroidCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/DroidCombatTask.java @@ -33,7 +33,6 @@ public class DroidCombatTask extends DefaultTask implements PriorityTask { public static final String SHOOT_UP = "ShootUp"; public static final String SHOOT_DOWN = "ShootDown"; - // class attributes private final int priority; // The active priority this task will have private final float maxRange; @@ -90,7 +89,7 @@ public void update() { } else { endTime = timeSource.getTime() + (INTERVAL * 1000); } - } + } } /** @@ -104,65 +103,15 @@ public void updateTowerState() { towerState = STATE.DIE; return; } + switch (towerState) { - case WALK -> { - owner.getEntity().getEvents().trigger(WALK); - towerState = STATE.IDLE; - } - case IDLE -> { - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(ATTACK_UP); - owner.getEntity().getEvents().trigger(SHOOT_UP); - towerState = STATE.DOWN; - } else { - owner.getEntity().getEvents().trigger(IDLE); - } - } - case SHOOT_DOWN -> { - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(ATTACK_DOWN); - owner.getEntity().getEvents().trigger(SHOOT_DOWN); - towerState = STATE.UP; - } else { - owner.getEntity().getEvents().trigger(GO_UP); - towerState = STATE.UP; - } - } - case SHOOT_UP -> { - if (isTargetVisible()) { - - owner.getEntity().getEvents().trigger(ATTACK_UP); - owner.getEntity().getEvents().trigger(SHOOT_UP); - towerState = STATE.DOWN; - } else { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } - } - case DOWN -> { - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(GO_DOWN); - towerState = STATE.SHOOT_DOWN; - } else { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } - } - case UP -> { - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(GO_UP); - towerState = STATE.SHOOT_UP; - } else { - owner.getEntity().getEvents().trigger(GO_UP); - towerState = STATE.IDLE; - - } - } - case DIE -> { - if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { - owner.getEntity().setFlagForDelete(true); - } - } + case WALK -> handleWalkState(); + case IDLE -> handleIdleState(); + case SHOOT_DOWN -> handleShootDownState(); + case SHOOT_UP -> handleShootUpState(); + case DOWN -> handleDownState(); + case UP -> handleUpState(); + default -> handleDieState(); // DIE } } @@ -175,6 +124,10 @@ public STATE getState() { return this.towerState; } + /** + * Function for setting the tower's state. + * @param state The new state of this tower. + */ public void setState(STATE state) { this.towerState = state; } @@ -194,7 +147,9 @@ public int getPriority() { */ public boolean isTargetVisible() { // If there is an obstacle in the path to the max range point, mobs visible. - return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + boolean top = physics.raycast(towerPosition.add(0f,0.4f), maxRangePosition.add(0f,0.4f), TARGET, hit); + boolean bottom = physics.raycast(towerPosition.sub(0f,0.4f), maxRangePosition.sub(0f,0.4f), TARGET, hit); + return top || bottom; } private void changeFireRateInterval(int newInterval) { @@ -210,4 +165,87 @@ public float getFireRateInterval() { return fireRateInterval; } -} + /** + * Function triggers walk and changes state from WALK to IDLE + */ + private void handleWalkState() { + owner.getEntity().getEvents().trigger(WALK); + towerState = STATE.IDLE; + } + + /** + * Function triggers actions at IDLE state + */ + private void handleIdleState() { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(ATTACK_UP); + owner.getEntity().getEvents().trigger(SHOOT_UP); + towerState = STATE.DOWN; + } else { + owner.getEntity().getEvents().trigger(IDLE); + } + } + + /** + * Function triggers actions at SHOOT_DOWN state, then switch to UP + */ + private void handleShootDownState() { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(ATTACK_DOWN); + owner.getEntity().getEvents().trigger(SHOOT_DOWN); + } else { + owner.getEntity().getEvents().trigger(GO_UP); + } + + towerState = STATE.UP; + } + + /** + * Function triggers actions at SHOOT_UP state, then switch to DOWN or IDLE + */ + private void handleShootUpState() { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(ATTACK_UP); + owner.getEntity().getEvents().trigger(SHOOT_UP); + towerState = STATE.DOWN; + } else { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } + } + + /** + * Function triggers actions at DOWN state, then switch to SHOOT_DOWN or IDLE + */ + private void handleDownState() { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(GO_DOWN); + towerState = STATE.SHOOT_DOWN; + } else { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } + } + + /** + * Function triggers actions at UP state, then switch to SHOOT_UP or IDLE + */ + private void handleUpState() { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(GO_UP); + towerState = STATE.SHOOT_UP; + } else { + owner.getEntity().getEvents().trigger(GO_UP); + towerState = STATE.IDLE; + } + } + + /** + * Function handles DIE state + */ + private void handleDieState() { + if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { + owner.getEntity().setFlagForDelete(true); + } + } +} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java index 13aa11a18..5654f3b15 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java @@ -47,7 +47,7 @@ public class FireTowerCombatTask extends DefaultTask implements PriorityTask { public enum STATE { IDLE, PREP_ATTACK, ATTACK, DEATH } - public STATE towerState = STATE.IDLE; + private STATE towerState = STATE.IDLE; /** * Starts the task running, triggers the initial 'IDLE' event @@ -67,7 +67,7 @@ public FireTowerCombatTask(int priority, float maxRange) { public void start() { super.start(); // get the tower coordinates - this.towerPosition = owner.getEntity().getCenterPosition(); + this.towerPosition = owner.getEntity().getCenterPosition().sub(0.125f,0.125f); this.maxRangePosition.set(towerPosition.x + maxRange, towerPosition.y); owner.getEntity().getEvents().addListener("addFireRate",this::changeFireRateInterval); //default to idle state @@ -99,50 +99,19 @@ public void updateTowerState() { towerState = STATE.DEATH; return; } - switch (towerState) { - case IDLE -> { - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(PREP_ATTACK); - towerState = STATE.PREP_ATTACK; - } - } - case PREP_ATTACK -> { - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(ATTACK); - towerState = STATE.ATTACK; - } else { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } - } - case ATTACK -> { - if (shoot) { - if (!isTargetVisible()) { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } else { - owner.getEntity().getEvents().trigger(ATTACK); - Entity newProjectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, - new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), ProjectileEffects.BURN, false); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y)); - ServiceLocator.getEntityService().register(newProjectile); - } - } - shoot = !shoot; - } - case DEATH -> { - if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { - owner.getEntity().setFlagForDelete(true); - } - } + switch (towerState) { + case IDLE -> handleIdleState(); + case PREP_ATTACK -> handlePrepAttackState(); + case ATTACK -> handleAttackState(); + default -> handleDeathState(); // DEATH } } /** * stops the current animation. */ + @Override public void stop() { super.stop(); owner.getEntity().getEvents().trigger(IDLE); @@ -164,40 +133,87 @@ public int getPriority() { } /** - * not currently used. - * @return the priority for this task + * detects targets from the centre of the tower to maxRange in a straight line. + * @return true if mobs are present and false otherwise. */ - private int getActivePriority() { - return !isTargetVisible() ? 0 : priority; + public boolean isTargetVisible() { + boolean top = physics.raycast(towerPosition.add(0f,0.4f), maxRangePosition.add(0f,0.4f), TARGET, hit); + boolean bottom = physics.raycast(towerPosition.sub(0f,0.4f), maxRangePosition.sub(0f,0.4f), TARGET, hit); + return top || bottom; + } + + private void changeFireRateInterval(int newInterval) { + fireRateInterval = 1 / ((float) newInterval / 5); } /** - * not currently used. - * @return + * Function for getting the tower's state. + * + * @return The tower's state */ - private int getInactivePriority() { - return isTargetVisible() ? priority : 0; + public STATE getTowerState() { + return this.towerState; } /** - * detects targets from the centre of the tower to maxRange in a straight line. - * @return true if mobs are present and false otherwise. + * Function for setting the tower's state + * + * @param newState The new state of this tower */ - public boolean isTargetVisible() { - return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + public void setTowerState(STATE newState) { + this.towerState = newState; } - private void changeFireRateInterval(int newInterval) { - fireRateInterval = 1 / ((float) newInterval / 5); + /** + * Function triggers actions at IDLE state, then switch to PREP_ATTACK + */ + private void handleIdleState() { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(PREP_ATTACK); + towerState = STATE.PREP_ATTACK; + } } /** - * Function for getting the turret's fire rate. - * - * @return The fireRateInterval variable + * Functions triggers actions at PREP_ATTACH state, then switch to ATTACK or IDLE */ - public float getFireRateInterval() { - return fireRateInterval; + private void handlePrepAttackState() { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(ATTACK); + towerState = STATE.ATTACK; + } else { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } } + /** + * Functions trigger actions at ATTACK state + */ + private void handleAttackState() { + if (shoot) { + if (!isTargetVisible()) { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } else { + owner.getEntity().getEvents().trigger(ATTACK); + Entity newProjectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, + new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), ProjectileEffects.BURN, false); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), + (owner.getEntity().getPosition().y)); + ServiceLocator.getEntityService().register(newProjectile); + } + } + + shoot = !shoot; + } + + /** + * Functions triggers actions at DEATH state + */ + private void handleDeathState() { + if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { + owner.getEntity().setFlagForDelete(true); + } + } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/FireworksTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/FireworksTowerCombatTask.java index 8d10036ae..e8bcbe5de 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/FireworksTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/FireworksTowerCombatTask.java @@ -13,6 +13,8 @@ import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import static java.lang.Math.round; + /** * The FireworksTowerCombatTask runs the AI for the FireworksTower class. The tower scans for mobs and targets in a @@ -38,6 +40,7 @@ public class FireworksTowerCombatTask extends DefaultTask implements PriorityTas private final Vector2 maxRangePosition = new Vector2(); private PhysicsEngine physics; private GameTime timeSource; + private float fireRateInterval; private long endTime; private final RaycastHit hit = new RaycastHit(); private boolean shoot = true; @@ -45,7 +48,7 @@ public class FireworksTowerCombatTask extends DefaultTask implements PriorityTas public enum STATE { IDLE, ATTACK, DEATH } - public STATE towerState = STATE.IDLE; + private STATE towerState = STATE.IDLE; /** * @param priority Task priority when targets are detected (0 when nothing is present) @@ -54,6 +57,7 @@ public enum STATE { public FireworksTowerCombatTask(int priority, float maxRange) { this.priority = priority; this.maxRange = maxRange; + this.fireRateInterval = 1; physics = ServiceLocator.getPhysicsService().getPhysics(); timeSource = ServiceLocator.getTimeSource(); } @@ -77,10 +81,16 @@ public void start() { * updates the current state of the tower based on the current state of the game. If enemies are detected, attack * state is activated and otherwise idle state remains. */ + @Override public void update() { if (timeSource.getTime() >= endTime) { updateTowerState(); - endTime = timeSource.getTime() + (INTERVAL * 1000); + if (towerState == STATE.ATTACK) { + endTime = timeSource.getTime() + round(fireRateInterval * 1000); + } else { + endTime = timeSource.getTime() + (INTERVAL * 1000); + } + } } @@ -111,7 +121,7 @@ public void updateTowerState() { Entity newProjectile = ProjectileFactory.createSplitFireWorksFireball(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), 3); newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y)); + (owner.getEntity().getPosition().y)); ServiceLocator.getEntityService().register(newProjectile); } else { owner.getEntity().getEvents().trigger(IDLE); @@ -139,6 +149,7 @@ public STATE getState() { /** * stops the current animation and switches back the state of the tower to IDLE. */ + @Override public void stop() { super.stop(); owner.getEntity().getEvents().trigger(IDLE); @@ -157,6 +168,25 @@ public int getPriority() { * @return true if targets are detected, false otherwise */ public boolean isTargetVisible() { - return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + boolean top = physics.raycast(towerPosition.add(0f,0.4f), maxRangePosition.add(0f,0.4f), TARGET, hit); + boolean bottom = physics.raycast(towerPosition.sub(0f,0.4f), maxRangePosition.sub(0f,0.4f), TARGET, hit); + return top || bottom; + } + + /** + * Function for getting the tower's state + * + * @return The state of this tower + */ + public STATE getTowerState() { + return this.towerState; + } + + /** + * Function for setting the tower's state + * @param newState The new state of this tower + */ + public void setTowerState(STATE newState) { + this.towerState = newState; } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobDeathTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobDeathTask.java index 5782ca8f9..85d29c15b 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobDeathTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobDeathTask.java @@ -1,5 +1,6 @@ package com.csse3200.game.components.tasks; +import com.badlogic.gdx.math.MathUtils; import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; import com.csse3200.game.components.CombatStatsComponent; @@ -11,6 +12,8 @@ import com.csse3200.game.services.GameTime; +/// THIS CODE IS REDUNDANT /// + /** * Task that prints a message to the terminal whenever it is called. */ @@ -97,10 +100,18 @@ private void killMob() { } private void dropCurrency() { + float randomValue = MathUtils.random(0,1); + Entity currency; + if (randomValue <= 0.1f) { + currency = DropFactory.createCrystalDrop(); + + } + else { + currency = DropFactory.createScrapDrop(); - Entity scrap = DropFactory.createScrapDrop(); - scrap.setPosition(mobPosition.x,mobPosition.y); - ServiceLocator.getEntityService().register(scrap); + } + currency.setPosition(mobPosition.x,mobPosition.y); + ServiceLocator.getEntityService().register(currency); } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobTask/MobTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobTask/MobTask.java index 08aa0b627..bd150803f 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobTask/MobTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobTask/MobTask.java @@ -1,13 +1,16 @@ package com.csse3200.game.components.tasks.MobTask; +import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Timer; import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.components.ProjectileEffects; +import com.csse3200.game.components.npc.DodgingComponent; import com.csse3200.game.components.tasks.MovementTask; import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.factories.DropFactory; import com.csse3200.game.entities.factories.ProjectileFactory; import com.csse3200.game.physics.PhysicsLayer; import com.csse3200.game.physics.components.HitboxComponent; @@ -15,6 +18,10 @@ import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.csse3200.game.components.tasks.MobTask.MobType; /** @@ -31,10 +38,17 @@ public class MobTask extends DefaultTask implements PriorityTask { private static final int MELEE_DAMAGE = 10; private static final long MELEE_ATTACK_SPEED = 2000; private static final long RANGE_ATTACK_SPEED = 5000; - private static final float MELEE_ATTACK_RANGE = 0.2f; + private static final float MELEE_ATTACK_RANGE = 0f; + + private static final float CRYSTAL_DROP_RATE = 0.1f; + private static final float SCRAP_DROP_RATE = 0.6f; + + private static final Logger logger = LoggerFactory.getLogger(MobTask.class); + // Private variables private final MobType mobType; + private State state = State.DEFAULT; private Entity mob; private AnimationRenderComponent animation; @@ -56,7 +70,7 @@ public class MobTask extends DefaultTask implements PriorityTask { // Enums private enum State { - RUN, ATTACK, DEATH, DEFAULT + RUN, ATTACK, DEATH, DEFAULT, DODGE } /** @@ -88,7 +102,6 @@ public void start() { super.start(); mob = owner.getEntity(); animation = mob.getComponent(AnimationRenderComponent.class); - mob.getComponent(PhysicsMovementComponent.class).setSpeed(MELEE_MOB_SPEED); melee = mobType.isMelee(); movementTask = new MovementTask(new Vector2(0f, mob.getPosition().y)); @@ -101,8 +114,10 @@ public void start() { if (melee) { mob.getComponent(PhysicsMovementComponent.class).setSpeed(MELEE_MOB_SPEED); + mob.getComponent(PhysicsMovementComponent.class).setNormalSpeed(MELEE_MOB_SPEED); } else { mob.getComponent(PhysicsMovementComponent.class).setSpeed(MELEE_RANGE_SPEED); + mob.getComponent(PhysicsMovementComponent.class).setNormalSpeed(MELEE_RANGE_SPEED); } } @@ -112,22 +127,38 @@ public void start() { @Override public void update() { + if(mob.getCenterPosition().x <= 1) { + mob.getComponent(CombatStatsComponent.class).setHealth(0); + ServiceLocator.getGameEndService().updateEngineerCount(); + } + // death check - if (mob.getComponent(CombatStatsComponent.class).getHealth() <= 0 && !deathFlag) { + if ((mob.getComponent(CombatStatsComponent.class).getHealth() <= 0 && !deathFlag)) { + // decrement engineer count + // ! tests failing because of textbox + changeState(State.DEATH); animate(); movementTask.stop(); deathFlag = true; + } else if (deathFlag && animation.isFinished()) { ServiceLocator.getWaveService().updateEnemyCount(); mob.setFlagForDelete(true); + dropCurrency(); } + // Uhhh if(gameTime.getTime() >= dodgeEndTime) { if (canDodge) { mob.getEvents().trigger("dodgeIncomingEntity", mob.getCenterPosition()); - } + if(mob.getComponent(DodgingComponent.class).isTargetVisible(mob.getCenterPosition())) { + changeState(State.DODGE); + animate(); + // movementTask.stop(); + } + } dodgeEndTime = gameTime.getTime() + 500; // 500ms } @@ -158,9 +189,16 @@ public void update() { rangeAttack(); rangeAttackFlag = false; } + if (animation.isFinished()) { + changeState(State.RUN); + runFlag = true; + } + } + case DODGE -> { if (animation.isFinished()) { movementTask.start(); changeState(State.RUN); + animate(); runFlag = true; } } @@ -178,6 +216,7 @@ private void animate() { owner.getEntity().getEvents().trigger("mob_death"); owner.getEntity().getEvents().trigger("splitDeath"); } + case DODGE -> owner.getEntity().getEvents().trigger("mob_dodge"); case DEFAULT -> owner.getEntity().getEvents().trigger("mob_default"); } } @@ -268,4 +307,25 @@ public int getPriority() { public void setDodge(boolean dodgeFlag) { this.canDodge = dodgeFlag; } + + private void dropCurrency() { + float randomValue = MathUtils.random(0f,1f); + logger.info("Random value: " + randomValue); + Entity currency; + if (randomValue <= CRYSTAL_DROP_RATE) { + currency = DropFactory.createCrystalDrop(); + currency.setPosition(mob.getPosition().x,mob.getPosition().y); + ServiceLocator.getEntityService().register(currency); + + } + else if (randomValue <= SCRAP_DROP_RATE) { + currency = DropFactory.createScrapDrop(); + currency.setPosition(mob.getPosition().x,mob.getPosition().y); + ServiceLocator.getEntityService().register(currency); + + } + + + + } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/PierceTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/PierceTowerCombatTask.java index cdefde434..02d36a77c 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/PierceTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/PierceTowerCombatTask.java @@ -13,6 +13,8 @@ import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import static java.lang.Math.round; + /** * The PierceTowerCombatTask runs the AI for the PierceTower class. The tower scans for mobs and targets in a straight * line from its centre coordinate and executes the trigger phrases for animations depeending on the current state of @@ -31,6 +33,7 @@ public class PierceTowerCombatTask extends DefaultTask implements PriorityTask { // Class attributes private final int priority; + private float fireRateInterval; private final float maxRange; private Vector2 towerPosition = new Vector2(10, 10); private final Vector2 maxRangePosition = new Vector2(); @@ -43,7 +46,7 @@ public class PierceTowerCombatTask extends DefaultTask implements PriorityTask { public enum STATE { IDLE, ATTACK, DEATH } - public STATE towerState = STATE.IDLE; + private STATE towerState = STATE.IDLE; /** * @param priority Task priority when targets are detected (0 when nothing is present) @@ -52,6 +55,7 @@ public enum STATE { public PierceTowerCombatTask(int priority, float maxRange) { this.priority = priority; this.maxRange = maxRange; + this.fireRateInterval = 1; physics = ServiceLocator.getPhysicsService().getPhysics(); timeSource = ServiceLocator.getTimeSource(); } @@ -63,7 +67,7 @@ public PierceTowerCombatTask(int priority, float maxRange) { public void start() { super.start(); // Get the tower coordinates - this.towerPosition = owner.getEntity().getCenterPosition(); + this.towerPosition = owner.getEntity().getCenterPosition().sub(0.25f, 0.25f); this.maxRangePosition.set(towerPosition.x + maxRange, towerPosition.y); // Set the default state to IDLE state owner.getEntity().getEvents().trigger(IDLE); @@ -75,9 +79,13 @@ public void start() { * updates the current state of the tower based on the current state of the game. If enemies are detected, attack * state is activated and otherwise idle state remains. */ + @Override public void update() { if (timeSource.getTime() >= endTime) { updateTowerState(); + if (towerState == STATE.ATTACK) { + endTime = timeSource.getTime() + round(fireRateInterval * 1000); + } endTime = timeSource.getTime() + (INTERVAL * 1000); } } @@ -113,14 +121,14 @@ public void updateTowerState() { Entity newProjectile = ProjectileFactory.createPierceFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f)); newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y)); + (owner.getEntity().getPosition().y)); ServiceLocator.getEntityService().register(newProjectile); } } shoot = !shoot; } - case DEATH -> { + default -> { // DEATH if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { owner.getEntity().setFlagForDelete(true); } @@ -139,6 +147,7 @@ public STATE getState() { /** * stops the current animation and switches back the state of the tower to IDLE. */ + @Override public void stop() { super.stop(); owner.getEntity().getEvents().trigger(IDLE); @@ -157,6 +166,25 @@ public int getPriority() { * @return true if targets are detected, false otherwise */ public boolean isTargetVisible() { - return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + boolean top = physics.raycast(towerPosition.add(0f,0.4f), maxRangePosition.add(0f,0.4f), TARGET, hit); + boolean bottom = physics.raycast(towerPosition.sub(0f,0.4f), maxRangePosition.sub(0f,0.4f), TARGET, hit); + return top || bottom; + } + + /** + * Function for getting the tower's state + * + * @return The state of this tower + */ + public STATE getTowerState() { + return this.towerState; + } + + /** + * Function for setting the tower's state + * @param newState The new state of this tower + */ + public void setTowerState(STATE newState) { + this.towerState = newState; } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/RicochetTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/RicochetTowerCombatTask.java index 7fc3e5728..004ab84d8 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/RicochetTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/RicochetTowerCombatTask.java @@ -13,6 +13,8 @@ import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import static java.lang.Math.round; + /** * The RicochetTowerCombatTask runs the AI for the RicochetTower class. The tower scans for mobs and targets in a @@ -37,6 +39,7 @@ public class RicochetTowerCombatTask extends DefaultTask implements PriorityTask private final Vector2 maxRangePosition = new Vector2(); private PhysicsEngine physics; private GameTime timeSource; + private float fireRateInterval; private long endTime; private final RaycastHit hit = new RaycastHit(); private boolean shoot = true; @@ -45,7 +48,7 @@ public class RicochetTowerCombatTask extends DefaultTask implements PriorityTask public enum STATE { IDLE, ATTACK, DEATH } - public STATE towerState = STATE.IDLE; + private STATE towerState = STATE.IDLE; /** * @param priority Task priority when targets are detected (0 when nothing is present) @@ -54,6 +57,7 @@ public enum STATE { public RicochetTowerCombatTask(int priority, float maxRange) { this.priority = priority; this.maxRange = maxRange; + this.fireRateInterval = 1; physics = ServiceLocator.getPhysicsService().getPhysics(); timeSource = ServiceLocator.getTimeSource(); } @@ -65,7 +69,7 @@ public RicochetTowerCombatTask(int priority, float maxRange) { public void start() { super.start(); // Get the tower coordinates - this.towerPosition = owner.getEntity().getCenterPosition(); + this.towerPosition = owner.getEntity().getCenterPosition().sub(0.25f, 0.25f); this.maxRangePosition.set(towerPosition.x + maxRange, towerPosition.y); // Set the default state to IDLE state owner.getEntity().getEvents().trigger(IDLE); @@ -77,10 +81,15 @@ public void start() { * updates the current state of the tower based on the current state of the game. If enemies are detected, attack * state is activated and otherwise idle state remains. */ + @Override public void update() { if (timeSource.getTime() >= endTime) { updateTowerState(); - endTime = timeSource.getTime() + (INTERVAL * 1000); + if (towerState == STATE.ATTACK) { + endTime = timeSource.getTime() + round(fireRateInterval * 1000); + } else { + endTime = timeSource.getTime() + (INTERVAL * 1000); + } } } @@ -89,7 +98,6 @@ public void update() { * of the game. If enemies are detected, state of the tower is changed to attack state. */ public void updateTowerState() { - if (owner.getEntity().getComponent(CombatStatsComponent.class).getHealth() <= 0 && towerState != STATE.DEATH) { owner.getEntity().getEvents().trigger(DEATH); towerState = STATE.DEATH; @@ -114,13 +122,13 @@ public void updateTowerState() { // NEED TO DO USER TESTING TO FIGURE OUT THE BOUNCE COUNT new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), 3); newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y)); + (owner.getEntity().getPosition().y)); ServiceLocator.getEntityService().register(newProjectile); } } shoot = !shoot; } - case DEATH -> { + default -> { // DEATH if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { owner.getEntity().setFlagForDelete(true); } @@ -128,13 +136,27 @@ public void updateTowerState() { } } + /** + * Function for getting the tower's state + * + * @return The state of this tower + */ public STATE getState() { return this.towerState; } + /** + * Function for setting the tower's state + * @param newState The new state of this tower + */ + public void setState(STATE newState) { + this.towerState = newState; + } + /** * stops the current animation and switches back the state of the tower to IDLE. */ + @Override public void stop() { super.stop(); owner.getEntity().getEvents().trigger(IDLE); @@ -153,6 +175,8 @@ public int getPriority() { * @return true if targets are detected, false otherwise */ public boolean isTargetVisible() { - return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + boolean top = physics.raycast(towerPosition.add(0f,0.4f), maxRangePosition.add(0f,0.4f), TARGET, hit); + boolean bottom = physics.raycast(towerPosition.sub(0f,0.4f), maxRangePosition.sub(0f,0.4f), TARGET, hit); + return top || bottom; } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/SpawnWaveTask.java b/source/core/src/main/com/csse3200/game/components/tasks/SpawnWaveTask.java index 912a2451b..201e3823f 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/SpawnWaveTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/SpawnWaveTask.java @@ -4,8 +4,6 @@ import com.csse3200.game.ai.tasks.PriorityTask; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class SpawnWaveTask extends DefaultTask implements PriorityTask { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java index ec469b269..5a1de08a2 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java @@ -46,7 +46,7 @@ public class StunTowerCombatTask extends DefaultTask implements PriorityTask { public enum STATE { IDLE, ATTACK, DIE } - public STATE towerState = STATE.IDLE; + private STATE towerState = STATE.IDLE; /** * @param priority Task priority when targets are detected (0 when nothing is present) @@ -67,7 +67,7 @@ public StunTowerCombatTask(int priority, float maxRange) { public void start() { super.start(); //get the tower coordinates - this.towerPosition = owner.getEntity().getCenterPosition(); + this.towerPosition = owner.getEntity().getCenterPosition().sub(0.25f, 0.25f); this.maxRangePosition.set(towerPosition.x + maxRange, towerPosition.y); owner.getEntity().getEvents().addListener("addFireRate",this::changeFireRateInterval); //set the default state to IDLE state @@ -80,6 +80,7 @@ public void start() { * updates the current state of the tower based on the current state of the game. If enemies are detected, attack * state is activated and otherwise idle state remains. */ + @Override public void update() { if (timeSource.getTime() >= endTime) { updateTowerState(); @@ -96,7 +97,6 @@ public void update() { * of the game. If enemies are detected, state of the tower is changed to attack state. */ public void updateTowerState() { - if (owner.getEntity().getComponent(CombatStatsComponent.class).getHealth() <= 0 && towerState != STATE.DIE) { owner.getEntity().getEvents().trigger(DEATH); @@ -124,15 +124,16 @@ public void updateTowerState() { new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f), ProjectileEffects.STUN, false); newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25), - (float) (owner.getEntity().getPosition().y)); + (owner.getEntity().getPosition().y)); ServiceLocator.getEntityService().register(newProjectile); owner.getEntity().getEvents().trigger(IDLE); towerState = STATE.IDLE; } } + shoot = !shoot; } - case DIE -> { + default -> { // DIE if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { owner.getEntity().setFlagForDelete(true); } @@ -140,13 +141,27 @@ public void updateTowerState() { } } + /** + * Function for getting the tower's state + * + * @return The state of this tower + */ public STATE getState() { return this.towerState; } + /** + * Function for setting the tower's state + * @param newState The new state of this tower + */ + public void setState(STATE newState) { + this.towerState = newState; + } + /** * stops the current animation and switches back the state of the tower to IDLE. */ + @Override public void stop() { super.stop(); owner.getEntity().getEvents().trigger(IDLE); @@ -160,32 +175,18 @@ public int getPriority() { return !isTargetVisible() ? 0 : priority; } - public int getActivePriority() { - return !isTargetVisible() ? 0 : priority; - } - - public int getInactivePriority() { - return isTargetVisible() ? priority : 0; - } - /** * Searches for enemies/mobs in a straight line from the centre of the tower to maxRange in a straight line. * @return true if targets are detected, false otherwise */ public boolean isTargetVisible() { - return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + boolean top = physics.raycast(towerPosition.add(0f,0.4f), maxRangePosition.add(0f,0.4f), TARGET, hit); + boolean bottom = physics.raycast(towerPosition.sub(0f,0.4f), maxRangePosition.sub(0f,0.4f), TARGET, hit); + return top || bottom; } private void changeFireRateInterval(int newInterval) { fireRateInterval = 1 / ((float) newInterval / 5); } - /** - * Function for getting the turret's fire rate. - * - * @return The fireRateInterval variable - */ - public float getFireRateInterval() { - return fireRateInterval; - } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/TNTTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/TNTTowerCombatTask.java index 48e28fdd9..db7f6a06a 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/TNTTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/TNTTowerCombatTask.java @@ -25,7 +25,6 @@ public class TNTTowerCombatTask extends DefaultTask implements PriorityTask { public static final String DEFAULT = "defaultStart"; public static final String DAMAGE = "TNTDamageStart"; - // class attributes private final int priority; // The active priority this task will have private final float maxRange; @@ -51,7 +50,6 @@ public TNTTowerCombatTask(int priority, float maxRange) { this.maxRange = maxRange; physics = ServiceLocator.getPhysicsService().getPhysics(); timeSource = ServiceLocator.getTimeSource(); - } /** @@ -87,7 +85,6 @@ public void update() { */ public void updateTowerState() { // configure tower state depending on target visibility - switch (towerState) { case IDLE -> { // targets detected in idle mode - start deployment @@ -103,7 +100,7 @@ public void updateTowerState() { owner.getEntity().getEvents().trigger(DAMAGE); towerState = STATE.REMOVE; } - case REMOVE -> readToDelete = true; + default -> readToDelete = true; // REMOVE } } @@ -136,17 +133,12 @@ public STATE getState() { */ public boolean isTargetVisible() { // If there is an obstacle in the path to the max range point, mobs visible. - return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + boolean top = physics.raycast(towerPosition.add(0f,0.4f), maxRangePosition.add(0f,0.4f), TARGET, hit); + boolean bottom = physics.raycast(towerPosition.sub(0f,0.4f), maxRangePosition.sub(0f,0.4f), TARGET, hit); + return top || bottom; } public boolean isReadyToDelete() { - return readToDelete; } - - -} - - - - +} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java index 6ea6dd9d3..a882cd1bb 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java @@ -3,7 +3,6 @@ import com.badlogic.gdx.math.Vector2; import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; -import com.csse3200.game.areas.ForestGameArea; import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.entities.Entity; import com.csse3200.game.entities.factories.ProjectileFactory; @@ -57,7 +56,6 @@ private enum STATE { * @param maxRange Maximum effective range of the weapon tower. This determines the detection distance of targets */ public TowerCombatTask(int priority, float maxRange) { - this.priority = priority; this.maxRange = maxRange; this.fireRateInterval = 1; @@ -123,61 +121,16 @@ public void updateTowerState() { towerState = STATE.DEATH; return; } + switch (towerState) { - case IDLE -> { - // targets detected in idle mode - start deployment - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(DEPLOY); - towerState = STATE.DEPLOY; - } - } - case DEPLOY -> { - // currently deploying, - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(FIRING); - towerState = STATE.FIRING; - } else { - owner.getEntity().getEvents().trigger(STOW); - towerState = STATE.STOW; - } - } - case FIRING -> { - if (shoot) { - // targets gone - stop firing - if (!isTargetVisible()) { - - owner.getEntity().getEvents().trigger(STOW); - towerState = STATE.STOW; - } else { - owner.getEntity().getEvents().trigger(FIRING); - // this might be changed to an event which gets triggered everytime the tower enters the firing state - - Entity newProjectile = ProjectileFactory.createFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f)); - newProjectile.setScale(1.1f, 0.8f); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.5), (owner.getEntity().getPosition().y)); - ServiceLocator.getEntityService().register(newProjectile); - } - } - shoot = !shoot; - } - case STOW -> { - // currently stowing - if (isTargetVisible()) { - - owner.getEntity().getEvents().trigger(DEPLOY); - towerState = STATE.DEPLOY; - } else { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } - } - case DEATH -> { - if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { - owner.getEntity().setFlagForDelete(true); - } - } + case IDLE -> handleIdleState(); + case DEPLOY -> handleDeployState(); + case FIRING -> handleFiringState(); + case STOW -> handleStowState(); + default -> handleDeathState(); // DEATH } } + /** * For stopping the running task */ @@ -218,7 +171,9 @@ private int getInactivePriority() { */ private boolean isTargetVisible() { // If there is an obstacle in the path to the max range point, mobs visible. - return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + boolean top = physics.raycast(towerPosition.add(0f,0.4f), maxRangePosition.add(0f,0.4f), TARGET, hit); + boolean bottom = physics.raycast(towerPosition.sub(0f,0.4f), maxRangePosition.sub(0f,0.4f), TARGET, hit); + return top || bottom; } /** @@ -227,7 +182,7 @@ private boolean isTargetVisible() { * @param newInterval The rate at which the tower should fire projectiles in shots per second. */ private void changeFireRateInterval(int newInterval) { - logger.info("Changing fire rate to: " + newInterval); + logger.info(String.format("Changing fire rate to: %d", newInterval)); fireRateInterval = 1 / ((float) newInterval / 5); } @@ -240,4 +195,74 @@ public float getFireRateInterval() { return fireRateInterval; } -} + /** + * Function triggers actions at IDLE state, then switch to DEPLOY + */ + private void handleIdleState() { + // targets detected in idle mode - start deployment + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(DEPLOY); + towerState = STATE.DEPLOY; + } + } + + /** + * Function triggers actions at DEPLOY state, then switch to FIRING or STOW + */ + private void handleDeployState() { + // currently deploying, + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(FIRING); + towerState = STATE.FIRING; + } else { + owner.getEntity().getEvents().trigger(STOW); + towerState = STATE.STOW; + } + } + + /** + * Function triggers actions at FIRING state + */ + private void handleFiringState() { + if (shoot) { + // targets gone - stop firing + if (!isTargetVisible()) { + owner.getEntity().getEvents().trigger(STOW); + towerState = STATE.STOW; + } else { + owner.getEntity().getEvents().trigger(FIRING); + // this might be changed to an event which gets triggered everytime the tower enters the firing state + + Entity newProjectile = ProjectileFactory.createFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f)); + newProjectile.setScale(1.1f, 0.8f); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.5), (owner.getEntity().getPosition().y)); + ServiceLocator.getEntityService().register(newProjectile); + } + } + + shoot = !shoot; + } + + /** + * Function triggers actions at STOW state, then switch to DEPLOY or IDLE + */ + private void handleStowState() { + // currently stowing + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(DEPLOY); + towerState = STATE.DEPLOY; + } else { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } + } + + /** + * Function handle DEATH state + */ + private void handleDeathState() { + if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { + owner.getEntity().setFlagForDelete(true); + } + } +} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/components/tasks/WallTowerDestructionTask.java b/source/core/src/main/com/csse3200/game/components/tasks/WallTowerDestructionTask.java index 749647851..1e2f3ff90 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/WallTowerDestructionTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/WallTowerDestructionTask.java @@ -4,8 +4,6 @@ import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; import com.csse3200.game.components.CombatStatsComponent; -import com.csse3200.game.entities.Entity; -import com.csse3200.game.entities.factories.ProjectileFactory; import com.csse3200.game.physics.PhysicsEngine; import com.csse3200.game.physics.PhysicsLayer; import com.csse3200.game.physics.raycast.RaycastHit; @@ -43,7 +41,7 @@ public class WallTowerDestructionTask extends DefaultTask implements PriorityTas public enum STATE { IDLE, DEATH } - public STATE towerState = STATE.IDLE; + private STATE towerState = STATE.IDLE; /** * @param priority Task priority when targets are detected (0 when nothing is present) @@ -75,6 +73,7 @@ public void start() { * updates the current state of the tower based on the current state of the game. If enemies are detected, attack * state is activated and otherwise idle state remains. */ + @Override public void update() { if (timeSource.getTime() >= endTime) { updateTowerState(); @@ -87,22 +86,19 @@ public void update() { * of the game. If enemies are detected, state of the tower is changed to attack state. */ public void updateTowerState() { - if (owner.getEntity().getComponent(CombatStatsComponent.class).getHealth() <= 0 && towerState != STATE.DEATH) { owner.getEntity().getEvents().trigger(DEATH); towerState = STATE.DEATH; return; } - switch (towerState) { - case IDLE -> { - owner.getEntity().getEvents().trigger(IDLE); - towerState = STATE.IDLE; - } - case DEATH -> { - if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { - owner.getEntity().setFlagForDelete(true); - } + // Replace "switch" statement by "if" statements to increase readability. + if (towerState == STATE.IDLE) { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } else { // DEATH + if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { + owner.getEntity().setFlagForDelete(true); } } } @@ -115,9 +111,18 @@ public STATE getState() { return this.towerState; } + /** + * Function for setting the tower's state. + * @param newState The new state of this tower. + */ + public void setState(STATE newState) { + this.towerState = newState; + } + /** * stops the current animation and switches back the state of the tower to IDLE. */ + @Override public void stop() { super.stop(); owner.getEntity().getEvents().trigger(IDLE); diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipCombatTask.java index 0c044d89f..3dd7a3124 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipCombatTask.java @@ -4,28 +4,18 @@ import com.badlogic.gdx.math.Vector2; import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; -import com.csse3200.game.entities.Entity; -import com.csse3200.game.entities.factories.ProjectileFactory; import com.csse3200.game.physics.PhysicsEngine; -import com.csse3200.game.physics.PhysicsLayer; -import com.csse3200.game.physics.raycast.RaycastHit; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; - -import java.util.ArrayList; - /** * The AI Task for the Engineer entity. The Engineer will scan for targets within its detection range * and trigger events to change its state accordingly. This task must be called once the Engineer has * appropiately moved into position. */ public class BombshipCombatTask extends DefaultTask implements PriorityTask { - private static final int INTERVAL = 1; // The time interval for each target scan from the Engineer. private static final int PRIORITY = 3; // Default priority of the combat task when mobs are in range. - private static final short TARGET1 = PhysicsLayer.BOSS; // The type of targets that the Engineer will detect. - private static final short TARGET2 = PhysicsLayer.XENO; // Animation event names for the Engineer's state machine. private static final String START = "start"; @@ -34,18 +24,11 @@ public class BombshipCombatTask extends DefaultTask implements PriorityTask { // The Engineer's attributes. private final float maxRange; // The maximum range of the bombship. - - private Vector2 bombShipPosition = new Vector2(0, 0); // Placeholder value for the Bombship's position. private final Vector2 maxRangePosition = new Vector2(); private PhysicsEngine physics; private GameTime timeSource; private long endTime; - private long reloadTime; -/** - private ArrayList hits = new ArrayList<>(); - private final RaycastHit hit = new RaycastHit(); - private ArrayList targets = new ArrayList<>(); -*/ + /** The Engineer's states. */ private enum STATE { IDLE, START , DESTROY @@ -64,8 +47,11 @@ public BombshipCombatTask(float maxRange) { @Override public void start() { super.start(); - this.bombShipPosition = owner.getEntity().getCenterPosition(); + + // Placeholder value for the Bombship's position. + Vector2 bombShipPosition = owner.getEntity().getCenterPosition(); this.maxRangePosition.set(bombShipPosition.x + maxRange, bombShipPosition.y); + // Default to idle mode owner.getEntity().getEvents().trigger(IDLE); endTime = timeSource.getTime() + (INTERVAL * 500); @@ -104,9 +90,7 @@ public void updateBombshipState() { owner.getEntity().getEvents().trigger(START); } } - case DESTROY -> { - owner.getEntity().getEvents().trigger(DESTROY); - } + default -> owner.getEntity().getEvents().trigger(DESTROY); // DESTROY } } @@ -117,13 +101,6 @@ private void combatState() { owner.getEntity().getEvents().trigger(START); bombshipState = STATE.START; } - /** - * For stopping the running task - */ - @Override - public void stop() { - super.stop(); - } /** * Simplified getPriority function, returns the priority of the task @@ -141,32 +118,7 @@ public int getPriority() { * @return true if a target is detected, false otherwise */ public boolean isEngineerDied() { - //if (engineerCount < maxEngineers) { - return true; - //} - } - - /** - * Fetches the nearest target from the array of detected target positions created during the last call of - * this could be done in the next sprint , the scan doesnt work as of now ! - * @return a Vector2 position of the nearest mob detected. - */ - /** public Vector2 fetchTarget() { - // Initial nearest position for comparison - int lowest = 10; - - Vector2 nearest = new Vector2(owner.getEntity().getCenterPosition().x, - owner.getEntity().getCenterPosition().y); - - // Find the nearest target from the array of targets - for (Vector2 tgt : targets){ - if (Math.abs(tgt.y - nearest.y) < lowest) { - lowest = (int)Math.abs(tgt.y - nearest.y); - nearest = tgt; - } - } - return nearest; + return true; } - */ } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipWanderTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipWanderTask.java index 63c611885..faf62ba6c 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipWanderTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bombship/BombshipWanderTask.java @@ -4,12 +4,10 @@ import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; import com.csse3200.game.ai.tasks.Task; -import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.physics.PhysicsLayer; import com.csse3200.game.physics.components.ColliderComponent; import com.csse3200.game.physics.components.HitboxComponent; import com.csse3200.game.rendering.AnimationRenderComponent; -import com.csse3200.game.services.ServiceLocator; /** * BombshipWanderTask is the entry point for the engineer entity's behaviour. Instantiates subtasks HumanWaitTask, @@ -17,7 +15,6 @@ * handled in this class. */ public class BombshipWanderTask extends DefaultTask implements PriorityTask { - private static final int TOLERANCE = 1; private static final float STOP_DISTANCE = 0.5f; private static final int DEFAULT_PRIORITY = 1; private static final String START = "start"; @@ -85,28 +82,18 @@ public void start() { */ @Override public void update() { - if (!isDestroyed) { - startDestroying(); - } - // Check if bombship has destroyed since last update if (!isDestroyed) { - startDestroying(); - } else if (isDestroyed && animator.isFinished()) { - owner.getEntity().setFlagForDelete(true); - } - - // otherwise doing engineer things since engineer is alive - else if (!isDestroyed){ doBombshipThings(); - + startDestroying();; currentTask.update(); + } else if (isDestroyed && animator.isFinished()) { + owner.getEntity().setFlagForDelete(true); } } private void doBombshipThings() { if (currentTask.getStatus() != Status.ACTIVE) { - // if the engineer is in move state and update has been called, engineer has arrived at destination if (currentTask == movementTask) { startWaiting(); @@ -117,6 +104,7 @@ private void doBombshipThings() { } } } + /** * Handle the dying phase of the entity. Triggers an event to play the appropriate media, * sets HitBox and Collider components to ignore contact (stops the body being pushed around) @@ -137,22 +125,6 @@ private void startWaiting() { swapTask(waitTask); } - /** - * Starts the movement task, to a particular destination - * @param destination the Vector2 position to which the entity needs to move - */ - private void startMoving(Vector2 destination) { - movementTask.setTarget(destination); - swapTask(movementTask); - } - - /** - * Starts the combat task. - */ - private void startCombat() { - swapTask(combatTask); - } - /** * Allows manual switching of tasks, from the current task to the supplied newTask. * @param newTask the task being switched to. @@ -161,6 +133,7 @@ private void swapTask(Task newTask) { if (currentTask != null) { currentTask.stop(); } + currentTask = newTask; currentTask.start(); } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/DemonBossTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/DemonBossTask.java index 38896b2b4..a861a3a5c 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/DemonBossTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/DemonBossTask.java @@ -10,6 +10,7 @@ import com.csse3200.game.components.ProjectileEffects; import com.csse3200.game.components.tasks.MovementTask; import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.factories.DropFactory; import com.csse3200.game.entities.factories.MobBossFactory; import com.csse3200.game.entities.factories.ProjectileFactory; import com.csse3200.game.physics.PhysicsLayer; @@ -140,6 +141,8 @@ public void update() { slimey.setScale(5f, 5f); ServiceLocator.getEntityService().register(slimey); demon.setFlagForDelete(true); + dropCurrency(); + } // detect half health @@ -495,4 +498,19 @@ public void run() { }, (float) (i + 1) * 2); } } + + private void dropCurrency() { + // Create and register 5 crystal drops around the bossPosition + for (int i = 0; i < 5; i++) { + Entity crystal = DropFactory.createCrystalDrop(); + + // Calculate positions around the bossPosition + float offsetX = MathUtils.random(-1f, 1f); // Adjust the range as needed + float offsetY = MathUtils.random(-1f, 1f); + float dropX = owner.getEntity().getPosition().x + offsetX; + float dropY = owner.getEntity().getPosition().y + offsetY; + crystal.setPosition(dropX, dropY); + ServiceLocator.getEntityService().register(crystal); + } + } } \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/IceBabyTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/IceBabyTask.java index 80e703ebf..6b4410a1d 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/IceBabyTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/IceBabyTask.java @@ -9,6 +9,7 @@ import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.components.tasks.MovementTask; import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.factories.DropFactory; import com.csse3200.game.entities.factories.NPCFactory; import com.csse3200.game.physics.PhysicsLayer; import com.csse3200.game.physics.components.HitboxComponent; @@ -71,6 +72,7 @@ public void start() { animation = iceBaby.getComponent(AnimationRenderComponent.class); currentPos = iceBaby.getPosition(); iceBaby.getComponent(PhysicsMovementComponent.class).setSpeed(ICEBABY_SPEED); + iceBaby.getComponent(PhysicsMovementComponent.class).setNormalSpeed(ICEBABY_SPEED); Timer.schedule(new Timer.Task() { @Override public void run() { @@ -114,6 +116,7 @@ public void update() { animate(); if (animation.isFinished()) { iceBaby.setFlagForDelete(true); + dropCurrency(); } } @@ -264,6 +267,7 @@ private void spawnMob() { Entity newMob = NPCFactory.createSplittingWaterSlime(80); newMob.setPosition((float) (iceBaby.getPosition().x + 0.5), (float) (iceBaby.getPosition().y + 0.5)); ServiceLocator.getEntityService().register(newMob); + ServiceLocator.getWaveService().setEnemyCount(ServiceLocator.getWaveService().getEnemyCount() + 1); } /** @@ -317,4 +321,20 @@ public int getPriority() { return PRIORITY; } + + private void dropCurrency() { + // Create and register 5 crystal drops around the bossPosition + for (int i = 0; i < 5; i++) { + Entity crystal = DropFactory.createCrystalDrop(); + + // Calculate positions around the bossPosition + float offsetX = MathUtils.random(-1f, 1f); // Adjust the range as needed + float offsetY = MathUtils.random(-1f, 1f); + float dropX = owner.getEntity().getPosition().x + offsetX; + float dropY = owner.getEntity().getPosition().y + offsetY; + crystal.setPosition(dropX, dropY); + ServiceLocator.getEntityService().register(crystal); + } + } + } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/MobBossDeathTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/MobBossDeathTask.java index 719c2436a..1bc2db0c3 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/MobBossDeathTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/MobBossDeathTask.java @@ -1,5 +1,6 @@ package com.csse3200.game.components.tasks.bosstask; +import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; @@ -9,6 +10,8 @@ import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +//CODE IS REDUNDANT /// + /** * Task that prints a message to the terminal whenever it is called. */ @@ -93,10 +96,18 @@ private void killboss() { } private void dropCurrency() { + // Create and register 5 crystal drops around the bossPosition + for (int i = 0; i < 5; i++) { + Entity crystal = DropFactory.createCrystalDrop(); + + // Calculate positions around the bossPosition + float offsetX = MathUtils.random(-1f, 1f); // Adjust the range as needed - Entity scrap = DropFactory.createScrapDrop(); - scrap.setPosition(bossPosition.x,bossPosition.y); - ServiceLocator.getEntityService().register(scrap.setScale(2,2)); + float dropX = bossPosition.x + offsetX; + crystal.setPosition(dropX, bossPosition.y); + ServiceLocator.getEntityService().register(crystal); + } } + } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickDeathTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickDeathTask.java index 97f7dacc4..92da2af17 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickDeathTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickDeathTask.java @@ -1,8 +1,12 @@ package com.csse3200.game.components.tasks.bosstask; +import com.badlogic.gdx.math.MathUtils; import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.factories.DropFactory; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; public class PatrickDeathTask extends DefaultTask implements PriorityTask { @@ -27,6 +31,8 @@ public void update() { if (startFlag && owner.getEntity().getComponent(AnimationRenderComponent.class). isFinished()) { owner.getEntity().setFlagForDelete(true); + ServiceLocator.getGameEndService().updateEngineerCount(); + dropCurrency(); } } @@ -37,4 +43,19 @@ public void update() { public int getPriority() { return PRIORITY; } + + private void dropCurrency() { + // Create and register 5 crystal drops around the bossPosition + for (int i = 0; i < 5; i++) { + Entity crystal = DropFactory.createCrystalDrop(); + + // Calculate positions around the bossPosition + float offsetX = MathUtils.random(-1f, 1f); // Adjust the range as needed + float offsetY = MathUtils.random(-1f, 1f); + float dropX = owner.getEntity().getPosition().x + offsetX; + float dropY = owner.getEntity().getPosition().y + offsetY; + crystal.setPosition(dropX, dropY); + ServiceLocator.getEntityService().register(crystal); + } + } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickTask.java index bf5e6c30c..cb3f27b8f 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickTask.java @@ -64,6 +64,7 @@ public void start() { patrick = owner.getEntity(); animation = owner.getEntity().getComponent(AnimationRenderComponent.class); // get animation patrick.getComponent(PhysicsMovementComponent.class).setSpeed(PATRICK_SPEED); // set speed + patrick.getComponent(PhysicsMovementComponent.class).setNormalSpeed(PATRICK_SPEED); // give game time to load Timer.schedule(new Timer.Task() { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/SlimeyBoyTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/SlimeyBoyTask.java index fe8cefae4..bf607a123 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/SlimeyBoyTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/SlimeyBoyTask.java @@ -1,5 +1,6 @@ package com.csse3200.game.components.tasks.bosstask; +import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Timer; @@ -8,6 +9,7 @@ import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.components.tasks.MovementTask; import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.factories.DropFactory; import com.csse3200.game.physics.PhysicsLayer; import com.csse3200.game.physics.components.PhysicsMovementComponent; import com.csse3200.game.rendering.AnimationRenderComponent; @@ -186,4 +188,6 @@ private void applyAoeDamage(Array targets, int damage) { public int getPriority() { return PRIORITY; } + + } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/waves/LevelWaves.java b/source/core/src/main/com/csse3200/game/components/tasks/waves/LevelWaves.java index 7d9e0e731..cca65b2e5 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/waves/LevelWaves.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/waves/LevelWaves.java @@ -124,11 +124,11 @@ public List getWaves() { @Override public String toString() { - String result = ""; - for (WaveClass wave : waves) { - result += wave.toString() + "\n"; - } - return result; + StringBuilder result = new StringBuilder(); + for (WaveClass wave : waves) { + result.append(wave.toString()).append("\n"); + } + return result.toString(); } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java index 3e197601e..635834811 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java @@ -1,15 +1,10 @@ package com.csse3200.game.components.tasks.waves; - -import com.csse3200.game.services.GameTime; - - import java.util.*; public class WaveClass { private HashMap entities; private List wave; - private int mobIndex; /** * Constructor for the WaveClass @@ -18,7 +13,6 @@ public class WaveClass { public WaveClass(HashMap entities) { this.entities = entities; this.wave = entitiesToWave(); - this.mobIndex = 0; } /** diff --git a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java index d49816692..04353f589 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java @@ -1,18 +1,14 @@ package com.csse3200.game.components.tasks.waves; -import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.audio.Sound; import com.csse3200.game.ai.tasks.DefaultTask; import com.csse3200.game.ai.tasks.PriorityTask; -import com.csse3200.game.ai.tasks.Task; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ResourceService; import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; - public class WaveTask extends DefaultTask implements PriorityTask { private static final Logger logger = LoggerFactory.getLogger(WaveTask.class); private LevelWaves level; @@ -21,10 +17,6 @@ public class WaveTask extends DefaultTask implements PriorityTask { private long nextWaveAt = 0; private int currentWaveIndex = 0; private boolean waveInProgress; - private float startTime = 0; - private float endTime = 0; - private final float INITIAL_WAIT_INTERVAL = 10; - private final int SPAWNING_INTERVAL = 10; private static final String[] waveSounds = { "sounds/waves/wave-start/Wave_Start_Alarm.ogg", @@ -83,7 +75,6 @@ public void start() { this.currentWave = level.getWave(currentWaveIndex); ServiceLocator.getWaveService().setEnemyCount(currentWave.getSize()); logger.info("Wave {} starting with {} enemies", currentWaveIndex, ServiceLocator.getWaveService().getEnemyCount()); - // endTime = globalTime.getTime() + (SPAWNING_INTERVAL * 1000); } /** @@ -101,7 +92,6 @@ public void update() { } else { // Spawn the next wave -// logger.info("No enemies remaining, begin next wave"); if (nextWaveAt == 0) { logger.info("Next wave in 10 seconds"); this.waveEnd.play(); @@ -121,16 +111,11 @@ public void update() { this.currentWave = this.level.getWave(currentWaveIndex); ServiceLocator.getWaveService().setEnemyCount(currentWave.getSize()); logger.info("Next wave {} starting with {} enemies", currentWaveIndex, ServiceLocator.getWaveService().getEnemyCount()); - //endTime = globalTime.getTime() + (SPAWNING_INTERVAL * 1000L); // reset end time } } } } else { - //logger.info("{} enemies remaining in wave {}", ServiceLocator.getWaveService().getEnemyCount(), currentWaveIndex); - //logger.info("WAVE SERVICE NUMBER: Wave Number {}",ServiceLocator.getWaveService().getWaveCount()); - //logger.info("NEXT WAVE AT {}", ServiceLocator.getWaveService().getNextWaveTime()); - //logger.info("TIME IS {}", ServiceLocator.getTimeSource().getTime()); if (waveInProgress) { this.level.spawnWave(); } diff --git a/source/core/src/main/com/csse3200/game/components/tower/DroidAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/DroidAnimationController.java index efd00a117..8ed009a12 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/DroidAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/DroidAnimationController.java @@ -1,5 +1,6 @@ package com.csse3200.game.components.tower; +import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.math.Vector2; import com.csse3200.game.components.Component; import com.csse3200.game.components.ProjectileEffects; @@ -16,6 +17,11 @@ public class DroidAnimationController extends Component { private AnimationRenderComponent animator; + private static final String FIRE_SINGLE_SFX = "sounds/towers/5.56_single_shot.mp3"; + + private final Sound fireSingleSound = ServiceLocator.getResourceService().getAsset( + FIRE_SINGLE_SFX, Sound.class); + /** * Creation call for a DroidAnimationController, fetches the animationRenderComponent that this controller will * be attached to and registers all the event listeners required to trigger the animations and sounds. @@ -66,6 +72,7 @@ void animateGoDown() { */ void animateAttackUp() { animator.startAnimation("attackUp"); + fireSingleSound.play(); } /** @@ -74,6 +81,7 @@ void animateAttackUp() { */ void animateAttackDown() { animator.startAnimation("attackDown"); + fireSingleSound.play(); } /** diff --git a/source/core/src/main/com/csse3200/game/components/tower/EconTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/EconTowerAnimationController.java index 3fcd566f5..3e9a3a785 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/EconTowerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/EconTowerAnimationController.java @@ -1,7 +1,9 @@ package com.csse3200.game.components.tower; +import com.badlogic.gdx.audio.Sound; import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; /** * Listens for events relevant to a weapon tower state. @@ -15,6 +17,11 @@ public class EconTowerAnimationController extends Component { private static final String ECO_MOVE = "move1"; private static final String ECO_IDLE = "idle"; + private static final String PING = "sounds/towers/eco_tower_ping.mp3"; + + private final Sound ping = ServiceLocator.getResourceService().getAsset( + PING, Sound.class); + AnimationRenderComponent animator; /** @@ -36,7 +43,8 @@ void animateIdle() { animator.startAnimation(ECO_IDLE); } - void animateMove() { animator.startAnimation(ECO_MOVE); } + void animateMove() { animator.startAnimation(ECO_MOVE); + ping.play();} } \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/components/tower/FireTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/FireTowerAnimationController.java index 0bfe1fe11..a2cd29c89 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/FireTowerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/FireTowerAnimationController.java @@ -21,7 +21,11 @@ public class FireTowerAnimationController extends Component{ private static final String PREP_ATTACK_ANIM = "prepAttack"; private static final String ATTACK_ANIM = "attack"; private static final String DEATH_ANIM = "death"; - //here we can add the sounds for the implemented animations + + private static final String FIRE_SINGLE_SFX = "sounds/towers/Desert-Eagle-Far-Single-Gunshot.mp3"; + + private final Sound fireSingleSound = ServiceLocator.getResourceService().getAsset( + FIRE_SINGLE_SFX, Sound.class); AnimationRenderComponent animator; @@ -57,6 +61,7 @@ void animatePrepAttack() { */ void animateAttack() { animator.startAnimation(ATTACK_ANIM); + fireSingleSound.play(); } void animateDeath() { diff --git a/source/core/src/main/com/csse3200/game/components/tower/FireworksTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/FireworksTowerAnimationController.java index cd701b0db..e9ec5c653 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/FireworksTowerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/FireworksTowerAnimationController.java @@ -1,7 +1,9 @@ package com.csse3200.game.components.tower; +import com.badlogic.gdx.audio.Sound; import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; /** * This class listens to events relevant to DroidTower entity's state and plays the animation when one @@ -10,6 +12,11 @@ public class FireworksTowerAnimationController extends Component { private AnimationRenderComponent animator; + private static final String FIRE_SINGLE_SFX = "sounds/towers/5.56_single_shot.mp3"; + + private final Sound fireSingleSound = ServiceLocator.getResourceService().getAsset( + FIRE_SINGLE_SFX, Sound.class); + /** * Creation call for a DroidAnimationController, fetches the animationRenderComponent that this controller will * be attached to and registers all the event listeners required to trigger the animations and sounds. @@ -30,6 +37,7 @@ public void create() { */ void animateAttack() { animator.startAnimation("Attack"); + fireSingleSound.play(); } diff --git a/source/core/src/main/com/csse3200/game/components/tower/PierceTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/PierceTowerAnimationController.java index 9daa39acb..f9018e0af 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/PierceTowerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/PierceTowerAnimationController.java @@ -1,7 +1,9 @@ package com.csse3200.game.components.tower; +import com.badlogic.gdx.audio.Sound; import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; /** * Listens to triggers phrases and executes the required animations. @@ -19,7 +21,10 @@ public class PierceTowerAnimationController extends Component { private static final String ALERT_ANIM = "Warning"; //further sounds can be added for the tower attacks/movement + private static final String FIRE_SINGLE_SFX = "sounds/towers/5.56_single_shot.mp3"; + private final Sound fireSingleSound = ServiceLocator.getResourceService().getAsset( + FIRE_SINGLE_SFX, Sound.class); AnimationRenderComponent animator; /** @@ -48,6 +53,7 @@ void animateIdle() { */ void animateAttack() { animator.startAnimation(ATTACK_ANIM); + fireSingleSound.play(); } /** diff --git a/source/core/src/main/com/csse3200/game/components/tower/RicochetTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/RicochetTowerAnimationController.java index 1a197868b..8210e7d73 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/RicochetTowerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/RicochetTowerAnimationController.java @@ -1,13 +1,19 @@ package com.csse3200.game.components.tower; +import com.badlogic.gdx.audio.Sound; import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; /** * This class listens to events relevant to DroidTower entity's state and plays the animation when one * of the events is triggered. */ public class RicochetTowerAnimationController extends Component { + private static final String FIRE_SINGLE_SFX = "sounds/towers/5.56_single_shot.mp3"; + + private final Sound fireSingleSound = ServiceLocator.getResourceService().getAsset( + FIRE_SINGLE_SFX, Sound.class); private AnimationRenderComponent animator; /** @@ -30,6 +36,7 @@ public void create() { */ void animateAttack() { animator.startAnimation("Attack"); + fireSingleSound.play(); } diff --git a/source/core/src/main/com/csse3200/game/components/tower/StunTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/StunTowerAnimationController.java index 846d344dd..1fc59068a 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/StunTowerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/StunTowerAnimationController.java @@ -18,7 +18,10 @@ public class StunTowerAnimationController extends Component { private static final String ATTACK_ANIM = "attack"; private static final String DEATH_ANIM = "death"; - //further sounds can be added for the tower attacks/movement + private static final String FIRE_SINGLE_SFX = "sounds/towers/ar15_single_shot_far.mp3"; + + private final Sound fireSingleSound = ServiceLocator.getResourceService().getAsset( + FIRE_SINGLE_SFX, Sound.class); AnimationRenderComponent animator; @@ -47,6 +50,7 @@ void animateIdle() { */ void animateAttack() { animator.startAnimation(ATTACK_ANIM); + fireSingleSound.play(); } /** diff --git a/source/core/src/main/com/csse3200/game/components/tower/TNTAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/TNTAnimationController.java index 1f092dab5..4ebfa2bb8 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/TNTAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/TNTAnimationController.java @@ -1,7 +1,9 @@ package com.csse3200.game.components.tower; +import com.badlogic.gdx.audio.Sound; import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; /** * This class listens to events relevant to TNTTower entity's state and plays the animation when one @@ -9,6 +11,10 @@ */ public class TNTAnimationController extends Component { private AnimationRenderComponent animator; + private static final String EXPLOSION = "sounds/towers/explosion.mp3"; + + private final Sound explosion = ServiceLocator.getResourceService().getAsset( + EXPLOSION, Sound.class); /** * Creation call for a TNTAnimationController, fetches the animationRenderComponent that this controller will @@ -43,7 +49,7 @@ void animateDig() { * This method should be invoked when the entity enters the explosion state. */ void animateExplode() { animator.startAnimation("explode"); - + explosion.play(); } } diff --git a/source/core/src/main/com/csse3200/game/components/tower/TowerUpgraderComponent.java b/source/core/src/main/com/csse3200/game/components/tower/TowerUpgraderComponent.java index e83210b48..a7d07d076 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/TowerUpgraderComponent.java +++ b/source/core/src/main/com/csse3200/game/components/tower/TowerUpgraderComponent.java @@ -3,17 +3,21 @@ import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.components.Component; -import static com.csse3200.game.screens.TowerType.INCOME; - /** * Listens for an event from the popup menu to upgrade * the turret entity this component is attached to. */ public class TowerUpgraderComponent extends Component { + /** + * Enum for specifying what type of upgrade to implement + */ public enum UPGRADE { ATTACK, MAXHP, FIRERATE, REPAIR, INCOME } + /** + * Creates the component and sets it up to respond to upgrade event triggers. + */ @Override public void create() { super.create(); @@ -29,12 +33,11 @@ public void create() { */ public void upgradeTower(UPGRADE upgradeType, int value) { switch (upgradeType) { - case INCOME -> {getEntity().getEvents().trigger("addIncome", value);} - case ATTACK -> {upgradeTowerAttack(value);} - case MAXHP -> {upgradeTowerMaxHealth( value);} - case FIRERATE -> {getEntity().getEvents().trigger("addFireRate", value);} - case REPAIR -> {repairTower();} - + case INCOME -> getEntity().getEvents().trigger("addIncome", value); + case ATTACK -> upgradeTowerAttack(value); + case MAXHP -> upgradeTowerMaxHealth( value); + case FIRERATE -> getEntity().getEvents().trigger("addFireRate", value); + case REPAIR -> repairTower(); } } diff --git a/source/core/src/main/com/csse3200/game/components/tower/WallTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/WallTowerAnimationController.java index 4f22bfaf5..69624ad41 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/WallTowerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/WallTowerAnimationController.java @@ -14,7 +14,7 @@ public class WallTowerAnimationController extends Component{ //animation name constants private static final String DEATH_ANIM = "Death"; - private static final String Idle_ANIM = "Idle"; + private static final String IDLE_ANIM = "Idle"; //here we can add the sounds for the implemented animations AnimationRenderComponent animator; @@ -29,13 +29,15 @@ public void create() { entity.getEvents().addListener(DEATH, this::animateDeath); entity.getEvents().addListener(IDLE, this::animateIdle); } + /** * Starts the idle animation. */ void animateDeath() { animator.startAnimation(DEATH_ANIM); } + void animateIdle(){ - animator.startAnimation(Idle_ANIM); + animator.startAnimation(IDLE_ANIM); } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/BaseTowerConfigs.java b/source/core/src/main/com/csse3200/game/entities/configs/BaseTowerConfigs.java new file mode 100644 index 000000000..03530fef3 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/entities/configs/BaseTowerConfigs.java @@ -0,0 +1,105 @@ +package com.csse3200.game.entities.configs; + +/** + * Defines all tower configs to be loaded by the Tower Factory. + */ +public class BaseTowerConfigs { + private WeaponTowerConfig weapon = new WeaponTowerConfig(); + private WallTowerConfig wall = new WallTowerConfig(); + private IncomeTowerConfig income = new IncomeTowerConfig(); + private FireTowerConfig fireTower = new FireTowerConfig(); + private StunTowerConfig stunTower = new StunTowerConfig(); + private TNTTowerConfigs TNTTower = new TNTTowerConfigs(); + private DroidTowerConfig DroidTower = new DroidTowerConfig(); + private FireworksTowerConfig fireworksTower = new FireworksTowerConfig(); + private PierceTowerConfig pierceTower = new PierceTowerConfig(); + private RicochetTowerConfig ricochetTower = new RicochetTowerConfig(); + private HealTowerConfig healTower = new HealTowerConfig(); + + /** + * Function for getting the wall tower's config + * @return The config of wall tower + */ + public WallTowerConfig getWall() { + return wall; + } + + /** + * Function for getting the weapon tower's config + * @return The config of weapon tower + */ + public WeaponTowerConfig getWeapon() { + return weapon; + } + + /** + * Function for getting the income tower's config + * @return The config of income tower + */ + public IncomeTowerConfig getIncome() { + return income; + } + + /** + * Function for getting the fire tower's config + * @return The config of fire tower + */ + public FireTowerConfig getFireTower() { + return fireTower; + } + + /** + * Function for getting the stun tower's config + * @return The config of stun tower + */ + public StunTowerConfig getStunTower() { + return stunTower; + } + + /** + * Function for getting the TNT tower's config + * @return The config of TNT tower */ + public TNTTowerConfigs getTNTTower() { + return TNTTower; + } + + /** + * Function for getting the droid tower's config + * @return The config of droid tower + */ + public DroidTowerConfig getDroidTower() { + return DroidTower; + } + + /** + * Function for getting the fireworks tower's config + * @return The config of fireworks tower + */ + public FireworksTowerConfig getFireworksTower() { + return fireworksTower; + } + + /** + * Function for getting the pierce tower's config + * @return The config of pierce tower + */ + public PierceTowerConfig getPierceTower() { + return pierceTower; + } + + /** + * Function for getting the ricochet tower's config + * @return The config of ricochet tower + */ + public RicochetTowerConfig getRicochetTower() { + return ricochetTower; + } + + /** + * Function for getting the heal tower's config + * @return The config of heal tower + */ + public HealTowerConfig getHealTower() { + return healTower; + } +} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/entities/configs/DroidTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/DroidTowerConfig.java index 3349a149c..804e72d7d 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/DroidTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/DroidTowerConfig.java @@ -4,9 +4,40 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class DroidTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; + private int health = 1; + private int baseAttack = 0; + private int cost = 1; + private float attackRate = 1; - public float attackRate = 1; + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Function for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/FireTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/FireTowerConfig.java index cc5b75284..48af9db9d 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/FireTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/FireTowerConfig.java @@ -1,9 +1,40 @@ package com.csse3200.game.entities.configs; public class FireTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; + private int health = 1; + private int baseAttack = 0; + private int cost = 1; + private float attackRate = 1; - public float attackRate = 1; + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Function for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/FireworksTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/FireworksTowerConfig.java index c1bde5dd3..dd345afae 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/FireworksTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/FireworksTowerConfig.java @@ -1,9 +1,49 @@ package com.csse3200.game.entities.configs; public class FireworksTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; - public int attackRate =0; - public int incomeRate =0; + private int health = 1; + private int baseAttack = 1; + private int cost = 1; + private int attackRate = 1; + private int incomeRate = 0; + + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Function for getting tower's attack rate + * @return The attack rate of this tower + */ + public int getAttackRate() { + return this.attackRate; + } + + /** + * Function for getting tower's income rate + * @return The income rate of this tower + */ + public int getIncomeRate() { + return this.incomeRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/HealTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/HealTowerConfig.java index 0eb826bcc..c3e5c6f22 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/HealTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/HealTowerConfig.java @@ -1,8 +1,31 @@ package com.csse3200.game.entities.configs; public class HealTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; - //comment to commit message + private int health = 1; + private int baseAttack = 0; + private int cost = 1; + + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/IncomeTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/IncomeTowerConfig.java index bdcf77c06..ed1500176 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/IncomeTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/IncomeTowerConfig.java @@ -4,11 +4,49 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class IncomeTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; + private int health = 1; + private int baseAttack = 0; + private int cost = 1; + private float attackRate = 0; + public float incomeRate = 3; - public float attackRate = 0; - public float incomeRate = 10; + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Function for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } + + /** + * Function for getting tower's income rate + * @return The income rate of this tower + */ + public float getIncomeRate() { + return this.incomeRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/PierceTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/PierceTowerConfig.java index 8baf1cb52..329b226c2 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/PierceTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/PierceTowerConfig.java @@ -1,7 +1,40 @@ package com.csse3200.game.entities.configs; public class PierceTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; + private int health = 1; + private int baseAttack = 1; + private int cost = 1; + private float attackRate = 1; + + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Functino for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/RicochetTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/RicochetTowerConfig.java index 3a637c7e2..07946bc4f 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/RicochetTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/RicochetTowerConfig.java @@ -1,7 +1,40 @@ package com.csse3200.game.entities.configs; public class RicochetTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; + private int health = 1; + private int baseAttack = 1; + private int cost = 1; + private float attackRate = 1; + + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Functino for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/StunTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/StunTowerConfig.java index adf01c4f4..a84a1bb9e 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/StunTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/StunTowerConfig.java @@ -1,9 +1,40 @@ package com.csse3200.game.entities.configs; public class StunTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; + private int health = 1; + private int baseAttack = 0; + private int cost = 1; + private float attackRate = 1; - public float attackRate = 1; + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Function for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/TNTTowerConfigs.java b/source/core/src/main/com/csse3200/game/entities/configs/TNTTowerConfigs.java index 9385fc512..c6d82c1a1 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/TNTTowerConfigs.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/TNTTowerConfigs.java @@ -4,9 +4,40 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class TNTTowerConfigs { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; + private int health = 1; + private int baseAttack = 0; + private int cost = 1; + private float attackRate = 1; - public float attackRate = 1; + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Function for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/WallTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/WallTowerConfig.java index 59c830d4f..82d1f00ee 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/WallTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/WallTowerConfig.java @@ -4,9 +4,40 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class WallTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; + private int health = 1; + private int baseAttack = 0; + private int cost = 1; + private float attackRate = 0; - public float attackRate = 0; + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Function for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/WeaponTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/WeaponTowerConfig.java index 7f0547769..b1c123f39 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/WeaponTowerConfig.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/WeaponTowerConfig.java @@ -4,8 +4,40 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class WeaponTowerConfig { - public int health = 1; - public int baseAttack = 0; - public int cost = 1; - public float attackRate = 1; + private int health = 1; + private int baseAttack = 0; + private int cost = 1; + private float attackRate = 1; + + /** + * Function for getting tower's health + * @return The health of this tower + */ + public int getHealth() { + return this.health; + } + + /** + * Function for getting tower's base attack + * @return The base attach of this tower + */ + public int getBaseAttack() { + return this.baseAttack; + } + + /** + * Function for getting tower's cost + * @return The cost of this tower + */ + public int getCost() { + return this.cost; + } + + /** + * Function for getting tower's attack rate + * @return The attack rate of this tower + */ + public float getAttackRate() { + return this.attackRate; + } } diff --git a/source/core/src/main/com/csse3200/game/entities/configs/baseTowerConfigs.java b/source/core/src/main/com/csse3200/game/entities/configs/baseTowerConfigs.java deleted file mode 100644 index c1b3f997a..000000000 --- a/source/core/src/main/com/csse3200/game/entities/configs/baseTowerConfigs.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.csse3200.game.entities.configs; - -/** - * Defines all tower configs to be loaded by the Tower Factory. - */ -public class baseTowerConfigs { - public WeaponTowerConfig weapon = new WeaponTowerConfig(); - public WallTowerConfig wall = new WallTowerConfig(); - public IncomeTowerConfig income = new IncomeTowerConfig(); - public FireTowerConfig fireTower = new FireTowerConfig(); - public StunTowerConfig stunTower = new StunTowerConfig(); - public TNTTowerConfigs TNTTower = new TNTTowerConfigs(); - public DroidTowerConfig DroidTower = new DroidTowerConfig(); - public FireworksTowerConfig fireworksTower = new FireworksTowerConfig(); - public PierceTowerConfig pierceTower = new PierceTowerConfig(); - public RicochetTowerConfig ricochetTower = new RicochetTowerConfig(); - public HealTowerConfig HealTower = new HealTowerConfig(); -} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/entities/factories/BombshipFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/BombshipFactory.java index b96ad1e59..f2e9a50a1 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/BombshipFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/BombshipFactory.java @@ -11,7 +11,6 @@ import com.csse3200.game.entities.configs.*; import com.csse3200.game.files.FileLoader; import com.csse3200.game.physics.PhysicsLayer; -import com.csse3200.game.physics.PhysicsUtils; import com.csse3200.game.physics.components.ColliderComponent; import com.csse3200.game.physics.components.HitboxComponent; import com.csse3200.game.physics.components.PhysicsComponent; @@ -20,7 +19,6 @@ /** * Factory to create non-playable human character (NPC) entities with predefined components. - * * These may be modified to become controllable characters in future sprints. * *

Each NPC entity type should have a creation method that returns a corresponding entity. @@ -31,19 +29,16 @@ * similar characteristics. */ public class BombshipFactory { - private static final int COMBAT_TASK_PRIORITY = 2; private static final int BOMBSHIP_RANGE = 30; private static final BombshipConfigs configs = FileLoader.readClass(BombshipConfigs.class, "configs/Bombship.json"); - private static final float HUMAN_SCALE_X = 1f; private static final float HUMAN_SCALE_Y = 0.8f; /** * Creates an Engineer entity, based on a base Human entity, with the appropriate components and animations * - * * @return entity */ public static Entity createBombship() { @@ -75,17 +70,12 @@ public static Entity createBombship() { * @return entity */ public static Entity createBaseshipNPC() { - - - Entity ship = - new Entity() - .addComponent(new PhysicsComponent()) - .addComponent(new PhysicsMovementComponent()) - .addComponent(new ColliderComponent()) - .addComponent(new HitboxComponent().setLayer(PhysicsLayer.BOMBSHIP)) - .addComponent(new TouchAttackComponent(PhysicsLayer.NPC, 1.5f)); - - return ship; + return new Entity() + .addComponent(new PhysicsComponent()) + .addComponent(new PhysicsMovementComponent()) + .addComponent(new ColliderComponent()) + .addComponent(new HitboxComponent().setLayer(PhysicsLayer.BOMBSHIP)) + .addComponent(new TouchAttackComponent(PhysicsLayer.NPC, 1.5f)); } private BombshipFactory() { diff --git a/source/core/src/main/com/csse3200/game/entities/factories/MobBossFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/MobBossFactory.java index f42babb8a..136dba625 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/MobBossFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/MobBossFactory.java @@ -216,6 +216,7 @@ public static Entity createIceBoss(int health) { * @return a base mob boss entity */ public static Entity createBaseBoss() { + return new Entity() .addComponent(new PhysicsComponent()) // .addComponent(new ColliderComponent()) diff --git a/source/core/src/main/com/csse3200/game/entities/factories/NPCFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/NPCFactory.java index 65185b27e..f4dab8d2b 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/NPCFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/NPCFactory.java @@ -64,9 +64,7 @@ public static Entity createGhost() { **/ ghost .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - // .addComponent(animator) .addComponent(new TextureRenderComponent("images/mobs/satyr.png")); - // .addComponent(new GhostAnimationController()); ghost.getComponent(TextureRenderComponent.class).scaleEntity(); @@ -103,8 +101,6 @@ public static Entity createGhostKing() { * * @return entity */ -// public static Entity createSkeleton(int health) { -// Entity skeleton = createBaseNPC(int health); public static Entity createSkeleton(int health) { Entity skeleton = createBaseNPC(); ArrayList drops = new ArrayList<>(); @@ -396,7 +392,7 @@ public static Entity createNecromancer(int health) { } public static Entity createFirewizard(int health) { - Entity Firewizard = createBaseNPC(); + Entity fireWizard = createBaseNPC(); ArrayList drops = new ArrayList<>(); AnimationRenderComponent animator = @@ -410,16 +406,16 @@ public static Entity createFirewizard(int health) { AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new MobTask(MobType.FIREWIZARD)); - Firewizard + fireWizard .addComponent(new CombatStatsComponent(health, 0, drops)) .addComponent(animator) .addComponent(new FirewizardAnimationController()) .addComponent(aiTaskComponent); - Firewizard.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); - Firewizard.getComponent(AnimationRenderComponent.class).scaleEntity(); + fireWizard.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); + fireWizard.getComponent(AnimationRenderComponent.class).scaleEntity(); - return Firewizard; + return fireWizard; } public static Entity createArcaneArcher(int health) { @@ -503,7 +499,6 @@ public static Entity createXenoGrunt(int health) { animator.addAnimation(DEFAULT, 0.1f); xenoGrunt .addComponent(new CombatStatsComponent(health, config.baseAttack, drops, melee, projectiles)) -// .addComponent(new CombatStatsComponent(config.fullHeath, config.baseAttack, drops, melee, projectiles)) .addComponent(animator) .addComponent(new XenoAnimationController()); @@ -536,10 +531,7 @@ public static Entity createMeleeBaseNPC() { new AITaskComponent() .addTask(new MobWanderTask(2f)) .addTask(new MobMeleeAttackTask(2)); - // .addTask(new MobAttackTask(2, 2f)); - // .addTask(new MeleeMobTask(new Vector2(2f, 2f), 2f)); - // .addTask(new MobAttackTask(2, 40)); Entity npc = new Entity() .addComponent(new PhysicsComponent()) @@ -560,11 +552,8 @@ public static Entity createRangedBaseNPC() { AITaskComponent aiComponent = new AITaskComponent() .addTask(new MobWanderTask(2f)) - // .addTask(new MobAttackTask(2, 2f)); .addTask(new MobRangedAttackTask(2)); - // .addTask(new MeleeMobTask(new Vector2(2f, 2f), 2f)); - // .addTask(new MobAttackTask(2, 40)); Entity npc = new Entity() .addComponent(new PhysicsComponent()) @@ -633,13 +622,10 @@ public static Entity createSplittingNightBorne(int health) { public static Entity createDodgingDragonKnight(int health) { Entity dodgeKnight = createDragonKnight(health); - dodgeKnight.addComponent(new DodgingComponent(PhysicsLayer.PROJECTILE, 0.25f)); - // dodgeKnight.getComponent(AITaskComponent.class).addTask(new MobDodgeTask(new Vector2(2f, 2f), 2f, 5)); - // dodgeKnight.getComponent(AITaskComponent.class). - // addTask(new MobDodgeTask(MobType.DRAGON_KNIGHT, 5)); + dodgeKnight.addComponent(new DodgingComponent(PhysicsLayer.PROJECTILE, 0.25f, 5f)); dodgeKnight.getComponent(AITaskComponent.class).getTask(MobTask.class).setDodge(true); - PhysicsUtils.setScaledCollider(dodgeKnight, 0.3f, 0.7f); - dodgeKnight.setScale(0.3f, 0.7f); + // PhysicsUtils.setScaledCollider(dodgeKnight, 0.3f, 1f); + dodgeKnight.setScale(0.5f, 1.2f); return dodgeKnight; } @@ -653,9 +639,6 @@ public static Entity createDodgingArcaneArcher(int health) { Entity dodgeKnight = createArcaneArcher(health); dodgeKnight.addComponent(new DodgingComponent(PhysicsLayer.PROJECTILE, 0.25f)); - // dodgeKnight.getComponent(AITaskComponent.class).addTask(new MobDodgeTask(new Vector2(2f, 2f), 2f, 5)); - // dodgeKnight.getComponent(AITaskComponent.class). - // addTask(new MobDodgeTask(MobType.DRAGON_KNIGHT, 5)); dodgeKnight.getComponent(AITaskComponent.class).getTask(MobTask.class).setDodge(true); PhysicsUtils.setScaledCollider(dodgeKnight, 0.3f, 0.7f); dodgeKnight.setScale(0.3f, 0.7f); @@ -663,9 +646,6 @@ public static Entity createDodgingArcaneArcher(int health) { return dodgeKnight; } -// public static Entity createDeflectXenoGrunt(int health) { -// Entity deflectXenoGrunt = createXenoGrunt(health); -// deflectXenoGrunt.addComponent(new DeflectingComponent( /** * Creates a wizard that can deflect bullets * @return Deflecting wizard diff --git a/source/core/src/main/com/csse3200/game/entities/factories/ProjectileFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/ProjectileFactory.java index ce160b65b..b64959976 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/ProjectileFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/ProjectileFactory.java @@ -343,7 +343,7 @@ public static Entity createBaseProjectile(short targetLayer, Vector2 // This is the component that allows the projectile to damage a // specified target. // Original knockback value: 1.5f - .addComponent(new TouchAttackComponent(targetLayer, 1.5f, true)) + .addComponent(new TouchAttackComponent(targetLayer, 0f, true)) .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) // *TEMPORARY .addComponent(new DeleteOnMapEdgeComponent()); diff --git a/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java index b98c5bde0..387d9c59e 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java @@ -1,9 +1,7 @@ package com.csse3200.game.entities.factories; import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.physics.box2d.Filter; import com.csse3200.game.components.EffectComponent; -import com.csse3200.game.components.EffectsComponent; import com.csse3200.game.components.tasks.DroidCombatTask; import com.csse3200.game.components.tasks.TNTTowerCombatTask; import com.csse3200.game.components.tasks.*; @@ -23,28 +21,24 @@ import com.csse3200.game.physics.components.PhysicsComponent; import com.csse3200.game.files.FileLoader; import com.csse3200.game.rendering.AnimationRenderComponent; -import com.csse3200.game.rendering.TextureRenderComponent; import com.csse3200.game.services.ServiceLocator; -import com.csse3200.game.input.UpgradeUIComponent;import java.util.HashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.HashSet; import java.util.Set; - /** * Factory to create a tower entity. * * Predefined tower properties are loaded from a config stored as a json file and should have - * the properties stores in 'baseTowerConfigs'. + * the properties stores in 'BaseTowerConfigs'. */ public class TowerFactory { - // Define a set to keep track of occupied lanes - private static final Set occupiedLanes = new HashSet<>(); private static final int COMBAT_TASK_PRIORITY = 2; private static final int WEAPON_TOWER_MAX_RANGE = 40; private static final int TNT_TOWER_MAX_RANGE = 6; private static final int TNT_TOWER_RANGE = 6; private static final int TNT_KNOCK_BACK_FORCE = 10; - private static final String WALL_IMAGE = "images/towers/wall_tower.png"; - private static final String RESOURCE_TOWER = "images/towers/mine_tower.png"; private static final String TURRET_ATLAS = "images/towers/turret01.atlas"; private static final String FIRE_TOWER_ATLAS = "images/towers/fire_tower_atlas.atlas"; private static final String STUN_TOWER_ATLAS = "images/towers/stun_tower.atlas"; @@ -105,29 +99,29 @@ public class TowerFactory { private static final float RICOCHET_TOWER_ANIM_ATTACK_SPEED = 0.12f; private static final String PIERCE_TOWER_ALERT_ANIM ="Warning"; private static final float PIERCE_TOWER_ANIM_ATTACK_SPEED = 0.12f; - private static final int INCOME_INTERVAL = 300; + // private static final int INCOME_INTERVAL = 300; private static final int INCOME_TASK_PRIORITY = 1; private static final String ECO_ATLAS = "images/economy/econ-tower.atlas"; private static final String ECO_MOVE = "move1"; private static final String ECO_IDLE = "idle"; private static final float ECO_IDLE_SPEED = 0.3f; - private static final baseTowerConfigs configs = - FileLoader.readClass(baseTowerConfigs.class, "configs/tower.json"); + private static final BaseTowerConfigs configs = + FileLoader.readClass(BaseTowerConfigs.class, "configs/tower.json"); + /** * Creates an income tower that generates scrap * @return income */ public static Entity createIncomeTower() { Entity income = createBaseTower(); - IncomeTowerConfig config = configs.income; + IncomeTowerConfig config = configs.getIncome(); // Create the CurrencyIncomeTask and add it to the AITaskComponent - CurrencyTask currencyTask = new CurrencyTask(INCOME_TASK_PRIORITY, (int) config.incomeRate); + CurrencyTask currencyTask = new CurrencyTask(INCOME_TASK_PRIORITY, (int) config.getIncomeRate()); AITaskComponent aiTaskComponent = new AITaskComponent().addTask(currencyTask); - // Contains all the animations that the tower will have AnimationRenderComponent animator = new AnimationRenderComponent( @@ -137,10 +131,10 @@ public static Entity createIncomeTower() { animator.addAnimation(ECO_MOVE, ECO_IDLE_SPEED, Animation.PlayMode.NORMAL); income - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(new UpgradableStatsComponent(config.attackRate)) - .addComponent(new CostComponent(config.cost)) - .addComponent(new IncomeUpgradeComponent(config.incomeRate)) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CostComponent(config.getCost())) + .addComponent(new IncomeUpgradeComponent(config.getIncomeRate())) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new EconTowerAnimationController()); @@ -148,9 +142,13 @@ public static Entity createIncomeTower() { return income; } + /** + * Create wall tower + * @return entity + */ public static Entity createWallTower() { Entity wall = createBaseTower(); - WallTowerConfig config = configs.wall; + WallTowerConfig config = configs.getWall(); AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new WallTowerDestructionTask(COMBAT_TASK_PRIORITY,TNT_TOWER_MAX_RANGE)); @@ -164,9 +162,9 @@ public static Entity createWallTower() { wall .addComponent(aiTaskComponent) - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(new UpgradableStatsComponent(config.attackRate)) - .addComponent(new CostComponent(config.cost)) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CostComponent(config.getCost())) .addComponent(animator) .addComponent(new WallTowerAnimationController()); @@ -175,7 +173,6 @@ public static Entity createWallTower() { return wall; } - /** * Create a type of TNT that explodes once it detects a mob within a certain range. * Upon detonation, the TNT will apply both knock-back and health damage to the affected mobs @@ -187,7 +184,7 @@ public static Entity createTNTTower() { .setLayer(PhysicsLayer.NONE) .setSensor(true); TNTTower.getComponent(ColliderComponent.class).setSensor(true); - TNTTowerConfigs config = configs.TNTTower; + TNTTowerConfigs config = configs.getTNTTower(); AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new TNTTowerCombatTask(COMBAT_TASK_PRIORITY,TNT_TOWER_MAX_RANGE)); @@ -202,15 +199,16 @@ public static Entity createTNTTower() { animator.addAnimation(EXPLODE_ANIM,EXPLODE_SPEED, Animation.PlayMode.NORMAL); TNTTower - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(new UpgradableStatsComponent(config.attackRate)) - .addComponent(new CostComponent(config.cost)) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CostComponent(config.getCost())) .addComponent(new TNTDamageComponent(PhysicsLayer.NPC,TNT_KNOCK_BACK_FORCE,TNT_TOWER_RANGE)) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new TNTAnimationController()); TNTTower.getComponent(AnimationRenderComponent.class).scaleEntity(); + TNTTower.removeComponent(TowerUpgraderComponent.class); return TNTTower; } @@ -222,8 +220,8 @@ public static Entity createTNTTower() { * @return entity */ public static Entity createDroidTower() { - Entity DroidTower = createBaseTower(); - DroidTowerConfig config = configs.DroidTower; + Entity droidTower = createBaseTower(); + DroidTowerConfig config = configs.getDroidTower(); AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new DroidCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); @@ -241,17 +239,15 @@ public static Entity createDroidTower() { animator.addAnimation(GO_UP,DROID_SPEED, Animation.PlayMode.NORMAL); animator.addAnimation(GO_DOWN,DROID_SPEED, Animation.PlayMode.NORMAL); - - - DroidTower - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(new UpgradableStatsComponent(config.attackRate)) - .addComponent(new CostComponent(config.cost)) + droidTower + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CostComponent(config.getCost())) .addComponent(new DroidAnimationController()) .addComponent(animator) .addComponent(aiTaskComponent); - return DroidTower; + return droidTower; } @@ -262,7 +258,7 @@ public static Entity createDroidTower() { */ public static Entity createWeaponTower() { Entity weapon = createBaseTower(); - WeaponTowerConfig config = configs.weapon; + WeaponTowerConfig config = configs.getWeapon(); // AiTaskComponent will run the tower task which carries out detection of targets and trigger events AITaskComponent aiTaskComponent = new AITaskComponent() @@ -279,16 +275,14 @@ public static Entity createWeaponTower() { animator.addAnimation(FIRE_ANIM, (2*FIRE_SPEED), Animation.PlayMode.LOOP); weapon - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(new UpgradableStatsComponent(config.attackRate)) - .addComponent(new CostComponent(config.cost)) - .addComponent(new UpgradableStatsComponent(config.attackRate)) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CostComponent(config.getCost())) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new TowerAnimationController()); return weapon; - } /** @@ -297,7 +291,7 @@ public static Entity createWeaponTower() { */ public static Entity createFireTower() { Entity fireTower = createBaseTower(); - FireTowerConfig config = configs.fireTower; + FireTowerConfig config = configs.getFireTower(); //Component that handles triggering events and animations AITaskComponent aiTaskComponent = new AITaskComponent() @@ -313,12 +307,13 @@ public static Entity createFireTower() { animator.addAnimation(FIRE_TOWER_DEATH_ANIM, FIRE_TOWER_DEATH_SPEED, Animation.PlayMode.NORMAL); fireTower - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(new UpgradableStatsComponent(config.attackRate)) - .addComponent(new CostComponent(config.cost)) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CostComponent(config.getCost())) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new FireTowerAnimationController()); + fireTower.setScale(1.25f, 1.25f); return fireTower; } @@ -329,7 +324,7 @@ public static Entity createFireTower() { */ public static Entity createStunTower() { Entity stunTower = createBaseTower(); - StunTowerConfig config = configs.stunTower; + StunTowerConfig config = configs.getStunTower(); AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new StunTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); @@ -339,13 +334,13 @@ public static Entity createStunTower() { ServiceLocator.getResourceService() .getAsset(STUN_TOWER_ATLAS, TextureAtlas.class)); animator.addAnimation(STUN_TOWER_IDLE_ANIM, STUN_TOWER_IDLE_SPEED, Animation.PlayMode.LOOP); - animator.addAnimation(STUN_TOWER_ATTACK_ANIM, ((STUN_TOWER_ATTACK_SPEED+ 0.20f)), Animation.PlayMode.LOOP); + animator.addAnimation(STUN_TOWER_ATTACK_ANIM, (STUN_TOWER_ATTACK_SPEED+ 0.20f), Animation.PlayMode.LOOP); animator.addAnimation(STUN_TOWER_DEATH_ANIM, STUN_TOWER_DEATH_SPEED, Animation.PlayMode.NORMAL); stunTower - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(new UpgradableStatsComponent(config.attackRate)) - .addComponent((new CostComponent(config.cost))) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CostComponent(config.getCost())) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new StunTowerAnimationController()); @@ -360,12 +355,11 @@ public static Entity createStunTower() { */ public static Entity createFireworksTower() { Entity fireworksTower = createBaseTower(); - FireworksTowerConfig config = configs.fireworksTower; + FireworksTowerConfig config = configs.getFireworksTower(); AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new FireworksTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); - AnimationRenderComponent animator = new AnimationRenderComponent( ServiceLocator.getResourceService() @@ -375,8 +369,9 @@ public static Entity createFireworksTower() { animator.addAnimation(FIREWORKS_TOWER_DEATH_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.NORMAL); fireworksTower - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent((new CostComponent(config.cost))) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CostComponent(config.getCost())) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new FireworksTowerAnimationController()); @@ -390,7 +385,7 @@ public static Entity createFireworksTower() { */ public static Entity createPierceTower() { Entity pierceTower = createBaseTower(); - PierceTowerConfig config = configs.pierceTower; + PierceTowerConfig config = configs.getPierceTower(); AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new PierceTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); @@ -404,12 +399,12 @@ public static Entity createPierceTower() { animator.addAnimation(PIERCE_TOWER_DEATH_ANIM, PIERCE_TOWER_ANIM_ATTACK_SPEED, Animation.PlayMode.NORMAL); animator.addAnimation(PIERCE_TOWER_ALERT_ANIM, PIERCE_TOWER_ANIM_ATTACK_SPEED, Animation.PlayMode.NORMAL); - pierceTower .addComponent(animator) .addComponent(new PierceTowerAnimationController()) - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent((new CostComponent(config.cost))) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new CostComponent(config.getCost())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) .addComponent(aiTaskComponent); pierceTower.setScale(1.5f, 1.5f); @@ -422,7 +417,7 @@ public static Entity createPierceTower() { */ public static Entity createRicochetTower() { Entity ricochetTower = createBaseTower(); - RicochetTowerConfig config = configs.ricochetTower; + RicochetTowerConfig config = configs.getRicochetTower(); AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new RicochetTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); @@ -432,13 +427,14 @@ public static Entity createRicochetTower() { animator.addAnimation(RICOCHET_TOWER_ATTACK_ANIM,(2*RICOCHET_TOWER_ANIM_ATTACK_SPEED),Animation.PlayMode.LOOP); animator.addAnimation(RICOCHET_TOWER_DEATH_ANIM,RICOCHET_TOWER_ANIM_ATTACK_SPEED,Animation.PlayMode.NORMAL); animator.addAnimation(RICOCHET_TOWER_IDLE_ANIM,RICOCHET_TOWER_ANIM_ATTACK_SPEED,Animation.PlayMode.LOOP); + ricochetTower .addComponent(animator) .addComponent(new RicochetTowerAnimationController()) - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent((new CostComponent(config.cost))) + .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) + .addComponent(new CostComponent(config.getCost())) + .addComponent(new UpgradableStatsComponent(config.getAttackRate())) .addComponent(aiTaskComponent); - // ADD ANIMATION COMPONENTS ricochetTower.setScale(1.5f, 1.5f); return ricochetTower; @@ -451,7 +447,6 @@ public static Entity createRicochetTower() { public static Entity createBaseTower() { // we're going to add more components later on - Entity tower = new Entity() .addComponent(new ColliderComponent()) .addComponent(new EffectComponent(false)) @@ -466,27 +461,4 @@ public static Entity createBaseTower() { tower.getComponent(ColliderComponent.class).setAsBoxAligned(new Vector2(1f, 1f), PhysicsComponent.AlignX.CENTER, PhysicsComponent.AlignY.CENTER); return tower; } - public static Entity createAndPlaceTower(int lane) { - if (isLaneOccupied(lane)) { - System.out.println("Lane " + lane + " is already occupied by a tower"); - return null; - } - - Entity tower = createBaseTower(); - // Customize the tower creation here based on the chosen tower type - - // Add the lane to the set of occupied lanes - occupiedLanes.add(lane); - - return tower; - } - - /** - * Checks if a lane is already occupied by a tower. - * @param lane The lane to check. - * @return True if the lane is occupied, false otherwise. - */ - public static boolean isLaneOccupied(int lane) { - return occupiedLanes.contains(lane); - } } \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java index 53ea2007a..0b9f6db73 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java @@ -40,8 +40,8 @@ public class WaveFactory { )); private static final ArrayList> lvl2Structure = new ArrayList<>(Arrays.asList( - new ArrayList<>(Arrays.asList("Skeleton" - )), new ArrayList<>(Arrays.asList("Skeleton", "ArcaneArcher" + new ArrayList<>(Arrays.asList("Skeleton" + )), new ArrayList<>(Arrays.asList("Skeleton", "ArcaneArcher" )), new ArrayList<>(Arrays.asList("Skeleton", "Wizard" )), new ArrayList<>(Arrays.asList("Skeleton", "SplittingNightBorne" )), new ArrayList<>(Arrays.asList("Wizard", "SplittingNightBorne" @@ -130,9 +130,9 @@ public static LevelWaves createLevel(int chosenLevel) { int bossHealth; int minMobs; // Base health of the bosses - int LVL1_BOSS_BASE_HEALTH = 500; - int LVL2_BOSS_BASE_HEALTH = 1000; - int LVL3_BOSS_BASE_HEALTH = 2000; + final int LVL1_BOSS_BASE_HEALTH = 500; + final int LVL2_BOSS_BASE_HEALTH = 1000; + final int LVL3_BOSS_BASE_HEALTH = 2000; switch (chosenLevel) { case 2: @@ -155,7 +155,6 @@ public static LevelWaves createLevel(int chosenLevel) { break; } -// int totalMobs = 0; // Create mxWaves number of waves with mob stats increasing int atWave = 1; for (ArrayList wave : possibleMobs) { @@ -171,26 +170,23 @@ public static LevelWaves createLevel(int chosenLevel) { // Calculate the number of mobs for the wave if (leftToSort == 0) { num = minMobs - currentMobs; - System.out.println(num + " for " + mob + " at wave " + atWave); } else { num = rand.nextInt(minMobs - currentMobs - (2 * leftToSort) - 2) + 2; - System.out.println(num + " for " + mob + " at wave " + atWave); currentMobs += num; } // Calculate the health - int RANGE_BASE_HEALTH = 60; + final int RANGE_BASE_HEALTH = 60; int health = RANGE_BASE_HEALTH; if (MELEE_MOBS.contains(mob)) { // The base health for the different mobs - int MELEE_BASE_HEALTH = 80; + final int MELEE_BASE_HEALTH = 80; health = MELEE_BASE_HEALTH; } int[] mobStats = {num, health + (atWave * chosenLevel)}; mobs.put(mob, mobStats); leftToSort --; -// totalMobs += num; } minMobs ++; level.addWave(new WaveClass(mobs)); @@ -200,9 +196,7 @@ public static LevelWaves createLevel(int chosenLevel) { // Add boss wave HashMap bossMob = new HashMap<>(); bossMob.put(boss, new int[]{1, bossHealth}); -// totalMobs ++; -// ServiceLocator.getWaveService().setTotalMobs(totalMobs); level.addWave(new WaveClass(bossMob)); diff --git a/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java b/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java index 0dcb71dec..2d514c43a 100644 --- a/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java +++ b/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java @@ -13,8 +13,6 @@ import com.csse3200.game.screens.TowerType; import com.csse3200.game.services.CurrencyService; import com.csse3200.game.services.ServiceLocator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** @@ -22,7 +20,6 @@ * DropInputComponent */ public class BuildInputComponent extends InputComponent { - private static final Logger logger = LoggerFactory.getLogger(BuildInputComponent.class); private final EntityService entityService; private final Camera camera; private final String[] sounds = { @@ -44,7 +41,6 @@ public BuildInputComponent(Camera camera) { loadSounds(); towers.addAll(ServiceLocator.getTowerTypes()); - logger.debug(String.format("selected towers in buildInputComponent are %s", towers)); TowerType[] defaultTowerTypes = { TowerType.TNT, TowerType.DROID, @@ -55,10 +51,15 @@ public BuildInputComponent(Camera camera) { Array defaultTowers = new Array<>(); defaultTowers.addAll(defaultTowerTypes); - if (towers.isEmpty()) { - ServiceLocator.setTowerTypes(defaultTowers); - towers = defaultTowers; + if (towers.isEmpty() || towers.size < 5) { + for (TowerType tower : defaultTowers) { + if (towers.size < 5 && !towers.contains(tower, true)) { + towers.add(tower); + } + } } + + ServiceLocator.setTowerTypes(towers); } /** @@ -90,11 +91,9 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { // determine if the tile is unoccupied boolean tileOccupied = entityService.entitiesInTile((int)cursorPosition.x, (int)cursorPosition.y); - logger.debug(String.format("Tile is occupied: %s", tileOccupied)); // check that no entities are occupying the tile if (!tileOccupied) { - logger.debug(String.format("spawning a tower at %f, %f", cursorPosition.x, cursorPosition.y)); return buildTower((int)cursorPosition.x, (int)cursorPosition.y); } else { return false; @@ -111,31 +110,35 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { @Override public boolean keyUp(int keycode) { switch (keycode) { - case Input.Keys.NUM_1: + case Input.Keys.NUM_1 -> { ServiceLocator.getCurrencyService().setTowerType(towers.get(0)); - return true; - case Input.Keys.NUM_2: + } + case Input.Keys.NUM_2 -> { ServiceLocator.getCurrencyService().setTowerType(towers.get(1)); return true; - case Input.Keys.NUM_3: + } + case Input.Keys.NUM_3 -> { ServiceLocator.getCurrencyService().setTowerType(towers.get(2)); return true; - case Input.Keys.NUM_4: + } + case Input.Keys.NUM_4 -> { ServiceLocator.getCurrencyService().setTowerType(towers.get(3)); return true; - case Input.Keys.NUM_5: + } + case Input.Keys.NUM_5 -> { ServiceLocator.getCurrencyService().setTowerType(towers.get(4)); return true; - case Input.Keys.CONTROL_LEFT: + } + case Input.Keys.CONTROL_LEFT -> { // After multiple placement, deselect tower and prevent further builds ServiceLocator.getCurrencyService().setTowerType(null); multipleTowerBuild = false; return true; - case Input.Keys.ESCAPE: - - default: + } + default -> { return false; + } } } @@ -161,53 +164,26 @@ public boolean keyDown(int keycode) { * @param y y-coordinate int value */ public boolean buildTower(int x, int y) { - TowerType tower; - CurrencyService currencyService; // fetch the currently set TowerType in the currency service, and its associated build cost. - currencyService = ServiceLocator.getCurrencyService(); - if (currencyService == null) { - // if the currency service fails or is not running - return false; - } - tower = currencyService.getTower(); + CurrencyService currencyService = ServiceLocator.getCurrencyService(); + TowerType tower = currencyService.getTower(); if (tower != null) { // fetch the price of the selected tower and attempt to instantiate int cost = Integer.parseInt(currencyService.getTower().getPrice()); - if (cost <= currencyService.getScrap().getAmount()) { - Entity newTower = switch (tower) { - case WEAPON -> TowerFactory.createWeaponTower(); - case INCOME -> TowerFactory.createIncomeTower(); - case TNT -> TowerFactory.createTNTTower(); - case DROID -> TowerFactory.createDroidTower(); - case WALL -> TowerFactory.createWallTower(); - case FIRE -> TowerFactory.createFireTower(); - case STUN -> TowerFactory.createStunTower(); - case PIERCE -> TowerFactory.createPierceTower(); - case FIREWORK -> TowerFactory.createFireworksTower(); - case RICOCHET -> TowerFactory.createRicochetTower(); - }; - // build the selected tower - newTower.setPosition(x, y); - - if (entityService == null){ - return false; - } - entityService.register(newTower); - // Decrement currency and show a popup that reflects the cost of the build - ServiceLocator.getCurrencyService().getScrap().modify(-cost); - ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats(); - ServiceLocator.getCurrencyService().getDisplay().currencyPopUp(x, y, -cost, 10); + if (canAfford(cost)) { + createTower(tower, x, y, cost); long soundId = buildSound.play(); buildSound.setVolume(soundId, 0.4f); - // deselect the tower after building + // deselect the tower after building if not in multiple placement mode if (!multipleTowerBuild) { ServiceLocator.getCurrencyService().setTowerType(null); } return true; + } else { // play a sound to indicate an invalid action long soundId = errorSound.play(); @@ -218,6 +194,47 @@ public boolean buildTower(int x, int y) { return false; } + /** + * Creates the new tower instance + * @param tower the TowerType currently set + * @param x the x position int the tower will occupy + * @param y the y position int the tower will occupy + */ + private void createTower(TowerType tower, int x, int y, int cost) { + if (tower == null) { + return; + } + Entity newTower = switch (tower) { + case WEAPON -> TowerFactory.createWeaponTower(); + case INCOME -> TowerFactory.createIncomeTower(); + case TNT -> TowerFactory.createTNTTower(); + case DROID -> TowerFactory.createDroidTower(); + case WALL -> TowerFactory.createWallTower(); + case FIRE -> TowerFactory.createFireTower(); + case STUN -> TowerFactory.createStunTower(); + case PIERCE -> TowerFactory.createPierceTower(); + case FIREWORK -> TowerFactory.createFireworksTower(); + case RICOCHET -> TowerFactory.createRicochetTower(); + }; + // build the selected tower + newTower.setPosition(x, y); + entityService.register(newTower); + + // Decrement currency and show a popup that reflects the cost of the build + ServiceLocator.getCurrencyService().getScrap().modify(-cost); + ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats(); + ServiceLocator.getCurrencyService().getDisplay().currencyPopUp(x, y, -cost, 10); + } + + /** + * Determines if there are sufficient resources for a tower build + * @param cost integer representing the cost of the intended build + * @return true if the cost is less than or equal to the current balance, false otherwise + */ + private boolean canAfford(int cost) { + return (cost <= ServiceLocator.getCurrencyService().getScrap().getAmount()); + } + /** * Load the sound assets related to in-game tower building activity */ diff --git a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java index 9d4c42f50..857a14919 100644 --- a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java +++ b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java @@ -1,5 +1,6 @@ package com.csse3200.game.input; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; @@ -19,7 +20,7 @@ import com.badlogic.gdx.utils.Scaling; import com.csse3200.game.ai.tasks.AITaskComponent; import com.csse3200.game.ai.tasks.PriorityTask; -import com.csse3200.game.areas.ForestGameArea; +import com.csse3200.game.areas.*; import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.components.tasks.TowerCombatTask; import com.csse3200.game.components.tower.*; @@ -33,7 +34,25 @@ import java.util.Iterator; import java.util.Map; +import static java.lang.Math.round; + public class UpgradeUIComponent extends InputComponent { + + // CONSTANTS + + /** + * The cost for all upgrades are 10 crystals + */ + private static final int UPGRADE_COST = 10; // Crystal + + /** + * The cost for repairing a turret is 50 scrap + */ + private static final int REPAIR_COST = 50; // Scrap + private static final float ATTACK_RATE_INCREASE = 0.2f; + private static final int ATTACK_INCREASE = 10; // Damage + private static final int HEALTH_INCREASE = 10; // Health + private static final int TIME_DECREASE = 5; // Scrap private static final Logger logger = LoggerFactory.getLogger(ForestGameArea.class); private final EntityService entityService; private final Camera camera; @@ -85,21 +104,10 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { Vector2 cursorPosition = new Vector2(worldCoordinates.x, worldCoordinates.y); Entity clickedEntity = entityService.getEntityAtPosition(cursorPosition.x, cursorPosition.y); - //temp fix to prevent upgrading of new towers - if (clickedEntity!= null && (clickedEntity.getComponent(RicochetTowerAnimationController.class) != null || - clickedEntity.getComponent(PierceTowerAnimationController.class) != null || - clickedEntity.getComponent(FireworksTowerAnimationController.class) != null)) { - return false; - } - // - // If the clicked position contains a turret, and the turret is upgradable and not a TNT tower if (clickedEntity != null && clickedEntity.getComponent(TowerUpgraderComponent.class) != null - && clickedEntity.getComponent(TNTDamageComponent.class) == null) { - // TNT TowerUpgraderComponent can be removed later, but possibly useful for future sprint. - // Clear all existing upgrade tables - logger.info("clickedEntity: " + clickedEntity); - + ) { +// clearUpgradeTables(); // Check if there is an existing upgrade table for this turret entity Table existingUpgradeTable = upgradeTables.get(clickedEntity); @@ -110,8 +118,6 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { } else { // If no upgrade table exists, create and store a new one Table newUpgradeTable = createUpgradeTable(clickedEntity); - Vector2 UICoordinates = stage.screenToStageCoordinates(new Vector2(screenX, screenY)); - newUpgradeTable.setPosition(UICoordinates.x, UICoordinates.y); stage.addActor(newUpgradeTable); // Store the new upgrade table in the map @@ -149,9 +155,11 @@ private void clearUpgradeTables() { private Table createUpgradeTable(Entity turretEntity) { // This is the overarching table that contains the close button, the inner table, and the cost display Table upgradeTable = new Table(); - upgradeTable.top(); + upgradeTable.top().left(); upgradeTable.defaults().pad(0).space(0); upgradeTable.setSize(60, 60); + upgradeTable.padTop(30f).padLeft(5f); + upgradeTable.setPosition(0, round((float) Gdx.graphics.getHeight() / 1.3f)); // The inner table contains the upgrade buttons and the stats display Table innerUpgradeTable = new Table(); @@ -180,11 +188,12 @@ private Table createUpgradeTable(Entity turretEntity) { costDisplay.setWidth(0); costDisplay.setBackground(drawableBackground); // Create an Image for the scrap icon - Drawable costDrawable = new TextureRegionDrawable(new TextureRegion(new Texture("images/economy/scrap.png"))); + Drawable costDrawable = new TextureRegionDrawable(new TextureRegion(new Texture("images/economy/crystal.png"))); + Drawable costDrawableScrap = new TextureRegionDrawable(new TextureRegion(new Texture("images/economy/scrap.png"))); Image costImage = new Image(costDrawable); costDisplay.add(costImage).center(); costImage.setScaling(Scaling.none); - Label costDisplayLabel = new Label("100", createLabelStyle()); + Label costDisplayLabel = new Label("You shouldn't see this", createLabelStyle()); costDisplay.add(costDisplayLabel).padLeft(0); TextButton closeButton = new TextButton("X", style); @@ -217,14 +226,15 @@ public void clicked(InputEvent event, float x, float y) { upgradeHealth.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { - value = ServiceLocator.getCurrencyService().getScrap().getAmount(); + value = ServiceLocator.getCurrencyService().getCrystal().getAmount(); logger.info("clicked"); - if (value >= 100) { - value -= 100; - ServiceLocator.getCurrencyService().getScrap().setAmount(value); - ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats(); + if (value >= UPGRADE_COST) { + value -= UPGRADE_COST; + ServiceLocator.getCurrencyService().getCrystal().setAmount(value); + ServiceLocator.getCurrencyService().getDisplay().updateCrystalsStats(); - turretEntity.getComponent(TowerUpgraderComponent.class).upgradeTower(TowerUpgraderComponent.UPGRADE.MAXHP, 10); + turretEntity.getComponent(TowerUpgraderComponent.class) + .upgradeTower(TowerUpgraderComponent.UPGRADE.MAXHP, HEALTH_INCREASE); int currentHealth = turretEntity.getComponent(CombatStatsComponent.class).getHealth(); int maxHealth = turretEntity.getComponent(CombatStatsComponent.class).getMaxHealth(); healthLabel.setText(String.format("%d/%d", currentHealth, maxHealth)); @@ -232,7 +242,7 @@ public void clicked(InputEvent event, float x, float y) { } @Override public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { - costDisplayLabel.setText("10"); + costDisplayLabel.setText(String.format("%d", UPGRADE_COST)); costDisplay.setVisible(true); } @Override @@ -247,12 +257,13 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) upgradeAttack.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { - value = ServiceLocator.getCurrencyService().getScrap().getAmount(); - if (value >= 10) { - value -= 10; - ServiceLocator.getCurrencyService().getScrap().setAmount(value); - ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats(); - turretEntity.getComponent(TowerUpgraderComponent.class).upgradeTower(TowerUpgraderComponent.UPGRADE.ATTACK, 5); + value = ServiceLocator.getCurrencyService().getCrystal().getAmount(); + if (value >= UPGRADE_COST) { + value -= UPGRADE_COST; + ServiceLocator.getCurrencyService().getCrystal().setAmount(value); + ServiceLocator.getCurrencyService().getDisplay().updateCrystalsStats(); + turretEntity.getComponent(TowerUpgraderComponent.class) + .upgradeTower(TowerUpgraderComponent.UPGRADE.ATTACK, ATTACK_INCREASE); int attack = turretEntity.getComponent(CombatStatsComponent.class).getBaseAttack(); attackLabel.setText(String.format("%d", attack)); @@ -260,7 +271,7 @@ public void clicked(InputEvent event, float x, float y) { } @Override public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { - costDisplayLabel.setText("10"); + costDisplayLabel.setText(String.format("%d", UPGRADE_COST)); costDisplay.setVisible(true); } @Override @@ -276,14 +287,18 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) upgradeFireRate.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { - value = ServiceLocator.getCurrencyService().getScrap().getAmount(); - if (value >= 10) { - value -= 10; - ServiceLocator.getCurrencyService().getScrap().setAmount(value); - ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats(); - float newFireRate = turretEntity.getComponent(UpgradableStatsComponent.class).getAttackRate() + 0.2f; - turretEntity.getComponent(UpgradableStatsComponent.class).setAttackRate(newFireRate); - turretEntity.getComponent(TowerUpgraderComponent.class).upgradeTower(TowerUpgraderComponent.UPGRADE.FIRERATE, (int) newFireRate * 5); + value = ServiceLocator.getCurrencyService().getCrystal().getAmount(); + if (value >= UPGRADE_COST) { + value -= UPGRADE_COST; + ServiceLocator.getCurrencyService().getCrystal().setAmount(value); + ServiceLocator.getCurrencyService().getDisplay().updateCrystalsStats(); + float newFireRate = turretEntity.getComponent(UpgradableStatsComponent.class) + .getAttackRate() + ATTACK_RATE_INCREASE; + turretEntity.getComponent(UpgradableStatsComponent.class) + .setAttackRate(newFireRate); + turretEntity.getComponent(TowerUpgraderComponent.class) + .upgradeTower(TowerUpgraderComponent.UPGRADE.FIRERATE, + (int) newFireRate * 5); float fireRate = turretEntity.getComponent(UpgradableStatsComponent.class).getAttackRate(); fireRateLabel.setText(String.format("%.2f", fireRate)); @@ -293,7 +308,7 @@ public void clicked(InputEvent event, float x, float y) { @Override public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { - costDisplayLabel.setText("10"); + costDisplayLabel.setText(String.format("%d", UPGRADE_COST)); costDisplay.setVisible(true); } @Override @@ -309,11 +324,12 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) @Override public void clicked(InputEvent event, float x, float y) { value = ServiceLocator.getCurrencyService().getScrap().getAmount(); - if (value >= 100) { - value -= 100; + if (value >= REPAIR_COST) { + value -= REPAIR_COST; ServiceLocator.getCurrencyService().getScrap().setAmount(value); ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats(); - turretEntity.getComponent(TowerUpgraderComponent.class).upgradeTower(TowerUpgraderComponent.UPGRADE.REPAIR, 0); + turretEntity.getComponent(TowerUpgraderComponent.class) + .upgradeTower(TowerUpgraderComponent.UPGRADE.REPAIR, 0); int currentHealth = turretEntity.getComponent(CombatStatsComponent.class).getHealth(); healthLabel.setText(String.format("%d/%d", currentHealth, maxHealth)); } @@ -321,11 +337,13 @@ public void clicked(InputEvent event, float x, float y) { @Override public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { - costDisplayLabel.setText("10"); + costDisplayLabel.setText(String.format("%d", REPAIR_COST)); + costImage.setDrawable(costDrawableScrap); costDisplay.setVisible(true); } @Override public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { + costImage.setDrawable(costDrawable); costDisplay.setVisible(false); } @@ -353,12 +371,12 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) upgradeIncome.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { - value = ServiceLocator.getCurrencyService().getScrap().getAmount(); - if (value >= 10 && turretEntity.getComponent(IncomeUpgradeComponent.class).getIncomeRate() >= 10) { - value -= 10; - ServiceLocator.getCurrencyService().getScrap().setAmount(value); - ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats(); - float newIncome = turretEntity.getComponent(IncomeUpgradeComponent.class).getIncomeRate() - 5; + value = ServiceLocator.getCurrencyService().getCrystal().getAmount(); + if (value >= UPGRADE_COST && turretEntity.getComponent(IncomeUpgradeComponent.class).getIncomeRate() >= 10) { + value -= UPGRADE_COST; + ServiceLocator.getCurrencyService().getCrystal().setAmount(value); + ServiceLocator.getCurrencyService().getDisplay().updateCrystalsStats(); + float newIncome = turretEntity.getComponent(IncomeUpgradeComponent.class).getIncomeRate() - TIME_DECREASE; turretEntity.getComponent(IncomeUpgradeComponent.class).setIncomeRate(newIncome); turretEntity.getComponent(TowerUpgraderComponent.class).upgradeTower(TowerUpgraderComponent.UPGRADE.INCOME, (int) newIncome); incomeLabel.setText(String.format("%.2f", newIncome)); @@ -369,7 +387,7 @@ public void clicked(InputEvent event, float x, float y) { @Override public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { - costDisplayLabel.setText("10"); + costDisplayLabel.setText(String.format("%d", UPGRADE_COST)); costDisplay.setVisible(true); } @Override @@ -378,6 +396,7 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) } }); } + logger.info(String.valueOf(attack)); if (attack != 0) { innerUpgradeTable.add(attackIconImage).padRight(5).width(32).height(32); // Add attack icon innerUpgradeTable.add(attackLabel).expandX().left(); diff --git a/source/core/src/main/com/csse3200/game/screens/AnimationTexturePair.java b/source/core/src/main/com/csse3200/game/screens/AnimationTexturePair.java new file mode 100644 index 000000000..1aebf5c26 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/AnimationTexturePair.java @@ -0,0 +1,45 @@ +/** + * Represents a pair of animation and texture for rendering in a game screen. + * Provides easy access to the animation and its associated texture. + * + * @param The type of texture region used in the animation. + */ +package com.csse3200.game.screens; + +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Animation; +import com.badlogic.gdx.graphics.g2d.TextureRegion; + +public class AnimationTexturePair { + public final Animation animation; + public final Texture texture; + + /** + * Creates an {@code AnimationTexturePair} with the specified animation and texture. + * + * @param animation The animation to be associated with this pair. + * @param texture The texture to be associated with this pair. + */ + public AnimationTexturePair(Animation animation, Texture texture) { + this.animation = animation; + this.texture = texture; + } + + /** + * Gets the animation associated with this pair. + * + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Gets the texture associated with this pair. + * + * @return The texture. + */ + public Texture getTexture() { + return texture; + } +} diff --git a/source/core/src/main/com/csse3200/game/screens/AssetLoader.java b/source/core/src/main/com/csse3200/game/screens/AssetLoader.java index 396f933e5..d224c8e78 100644 --- a/source/core/src/main/com/csse3200/game/screens/AssetLoader.java +++ b/source/core/src/main/com/csse3200/game/screens/AssetLoader.java @@ -1,13 +1,17 @@ package com.csse3200.game.screens; + import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.audio.Sound; -import com.csse3200.game.areas.ForestGameArea; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.csse3200.game.services.ResourceService; import com.csse3200.game.services.ServiceLocator; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; public class AssetLoader { + private static final Set loadedAssets = new HashSet<>(); // Define your asset file paths here public static final String[] textures = { "images/desert_bg.png", @@ -85,7 +89,8 @@ public class AssetLoader { "images/highlight_tile.png", "images/ui/Sprites/UI_Glass_Toggle_Bar_01a.png", "images/green_tile.png", - "images/red_tile.png" + "images/red_tile.png", + "images/HelpScreen/hs.jpg" }; public static final String[] textureAtlases = { @@ -136,6 +141,7 @@ public class AssetLoader { }; public static final String[] Sounds = { + "sounds/ui/Open_Close/NA_SFUI_Vol1_Open_01.ogg", "sounds/Impact4.ogg", "sounds/economy/click.wav", "sounds/economy/click_1.wav", @@ -235,5 +241,13 @@ public static Sound getSound(String assetPath) { public static Music getMusic(String assetPath) { return ServiceLocator.getResourceService().getAsset(assetPath, Music.class); } -} + public static boolean areAllAssetsLoaded() { + ResourceService resourceService = ServiceLocator.getResourceService(); + + return loadedAssets.containsAll(Arrays.asList(textures)) && + loadedAssets.containsAll(Arrays.asList(textureAtlases)) && + loadedAssets.containsAll(Arrays.asList(Sounds)) && + loadedAssets.containsAll(Arrays.asList(music)); + } +} diff --git a/source/core/src/main/com/csse3200/game/screens/HelpScreen.java b/source/core/src/main/com/csse3200/game/screens/HelpScreen.java deleted file mode 100644 index 14c8cd5dc..000000000 --- a/source/core/src/main/com/csse3200/game/screens/HelpScreen.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.csse3200.game.screens; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.ScreenAdapter; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.ui.TextButton; -import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; -import com.badlogic.gdx.utils.viewport.FitViewport; -import com.csse3200.game.GdxGame; -import com.csse3200.game.ui.ButtonFactory; - -public class HelpScreen extends ScreenAdapter { - private final GdxGame game; - private Stage stage; - private SpriteBatch spriteBatch; - - - public HelpScreen(GdxGame game) { - this.game = game; - stage = new Stage(new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); - spriteBatch = new SpriteBatch(); - - // Create a table to organize the image placeholder - Table table = new Table(); - table.setFillParent(true); // Makes the table the size of the stage - - // Create one image placeholder - Image image = new Image(new Texture("images/background/HelpScreenBG.png")); - - // Add the image placeholder to the table - table.add(image).expand().fill(); - - // Add the table to the stage - stage.addActor(table); - - TextButton BackButton = ButtonFactory.createButton("Back"); - BackButton.addListener(new ClickListener() { - @Override - public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { - game.setScreen(GdxGame.ScreenType.MAIN_MENU); - - } - }); - Table buttonTable = new Table(); - buttonTable.add(BackButton).padRight(10); - Table table1 = new Table(); - table1.setFillParent(true); - table1.top().right(); // Align to the top-right corner - table1.pad(20); // Add padding to the top-right corner - table1.add(buttonTable).row(); // Add button table and move to the next row - stage.addActor(table1); - } - @Override - public void show() { - // Set this screen as the input processor - Gdx.input.setInputProcessor(stage); - } - - @Override - public void render(float delta) { - // Clear the screen - spriteBatch.begin(); - spriteBatch.end(); - - // Draw the stage - stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); - stage.draw(); - } - - @Override - public void resize(int width, int height) { - stage.getViewport().update(width, height, true); - } - - @Override - public void dispose() { - stage.dispose(); - spriteBatch.dispose(); - } -} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/HelpScreen/BossDescriptionHelpScreen.java b/source/core/src/main/com/csse3200/game/screens/HelpScreen/BossDescriptionHelpScreen.java new file mode 100644 index 000000000..772c72e32 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/HelpScreen/BossDescriptionHelpScreen.java @@ -0,0 +1,164 @@ +package com.csse3200.game.screens.HelpScreen; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.csse3200.game.GdxGame; +/** + * A screen that displays information about boss characters in the game. + */ +public class BossDescriptionHelpScreen extends ScreenAdapter { + private final GdxGame game; + private Stage stage; + private SpriteBatch spriteBatch; + + /** + * Creates a new BossDescriptionHelpScreen. + * + * @param game The main game instance. + */ + public BossDescriptionHelpScreen(GdxGame game) { + this.game = game; + stage = new Stage(new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); + spriteBatch = new SpriteBatch(); + + // Create a table to organize the image placeholder + Table table = new Table(); + table.setFillParent(true); // Makes the table the size of the stage + + // Create one image placeholder + Image image = new Image(new Texture("images/lose-screen/desktop-wallpaper-simple-stars-video-background-loop-black-and-white-aesthetic-space.jpg")); + + // Add the image placeholder to the table + table.add(image).expand().fill(); + + // Add the table to the stage + stage.addActor(table); + + Skin skin = new Skin(Gdx.files.internal("images/ui/buttons/glass.json")); + TextButton BackButton = new TextButton("Back", skin); + BackButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.MAIN_MENU); + + } + }); + + Texture imageTexture = new Texture("images/ui/Sprites/UI_Glass_Arrow_Large_01a - Copy.png"); + Drawable drawable = new TextureRegionDrawable(new TextureRegion(imageTexture)); + ImageButton MobsButton = new ImageButton(drawable); + MobsButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.HELP_MOBS_SCREEN); + + } + }); + + Table buttonTable = new Table(); + buttonTable.add(BackButton).padRight(10); + Table table1 = new Table(); + table1.setFillParent(true); + table1.top().right(); // Align to the top-right corner + table1.pad(20); // Add padding to the top-right corner + table1.add(buttonTable).row(); // Add button table and move to the next row + stage.addActor(table1); + + Table buttonTable1 = new Table(); + buttonTable1.add(MobsButton).padRight(10); + Table table2 = new Table(); + table2.setFillParent(true); + table2.center().top(); // Align to the middle-right corner + table2.pad(20); // Add padding to the middle-right corner + table2.add(buttonTable1).row(); // Add button table and move to the next row + stage.addActor(table2); + + Table imageTextTable = new Table(); + imageTextTable.setFillParent(true); + imageTextTable.center(); + + float leftPadding = 30f; + imageTextTable.padLeft(leftPadding); + + // Create an array of image file names + String[] imageFileNames = { + "images/HelpScreen/Patrickbosshelp.png", + "images/HelpScreen/IceBosshelp.png", + "images/HelpScreen/Demonbosshelp.png" + }; + + // Create an array of text descriptions + String[] textDescriptions = { + "Patrick is able to teleport to the closest entity and do damage as well as shoot projectiles and melee attack. Once Patrick hits half health, it will shoot 5 projectiles of random effect.", + "The Ice Baby is able to spawn water mobs and do AOE damage.", + "Demon boss is able to shoot burn projectiles and do AOE damage. Demon boss is also able to regenerate health once it hits half health.", + }; + + // Add images and text to the table + for (int i = 0; i < imageFileNames.length; i++) { + // Create an image from the file + Image imager = new Image(new Texture(imageFileNames[i])); + float imageSize = 200f; + imager.setSize(imageSize, imageSize); + + // Create a label for text description + Label.LabelStyle labelStyle = new Label.LabelStyle(); + BitmapFont customFont = new BitmapFont(Gdx.files.internal("images/ui/buttons/dot_gothic_16.fnt")); // Replace "your-font.fnt" with your font file path + customFont.getData().setScale(1.2f); // Adjust the scale factor to change the text size + labelStyle.font = customFont; + + Label label = new Label(textDescriptions[i], labelStyle); + label.setWrap(true); + + // Add the image and label to the table in two columns + Cell imageCell = imageTextTable.add(imager).expandX().pad(10); // Add spacing around the image + Cell

+ * @param towerButton the ImageButton which is being set to on, all others will be toggled off. If null, all buttons + * will be set to off + */ + private void towerToggle(ImageButton towerButton) { + if (towerButton == null) { + // set all buttons to off, disable if isDisabled + for (ImageButton button : towerButtons) { + button.setChecked(false); + } + } else { + // set the button corresponding to towerButton to on, all others to off + for (ImageButton button : towerButtons) { + button.setChecked(button == towerButton); + } + } + } + @Override + public float getZIndex() { + return Z_INDEX; + } + + @Override + public void dispose() { + buttonTable.clear(); + towerTable.clear(); + unloadSounds(); + super.dispose(); + } + + /** + * Loads sound assets for use in the class + */ + public void loadSounds() { + ServiceLocator.getResourceService().loadSounds(sounds); + ServiceLocator.getResourceService().loadAll(); + click = ServiceLocator.getResourceService().getAsset(sounds[0], Sound.class); + openSound = ServiceLocator.getResourceService().getAsset(sounds[1], Sound.class); + } + + public void unloadSounds() { + ServiceLocator.getResourceService().unloadAssets(sounds); + } + + public void animateTowerButton(ImageButton button, float x, float y) { + button.setPosition(Gdx.graphics.getWidth() - x, Gdx.graphics.getHeight()); + button.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - x, + Gdx.graphics.getHeight() - y, 1f, Interpolation.fastSlow))); + } +} diff --git a/source/core/src/main/com/csse3200/game/screens/HelpScreen/HowToPlay.java b/source/core/src/main/com/csse3200/game/screens/HelpScreen/HowToPlay.java new file mode 100644 index 000000000..625ab1bd9 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/HelpScreen/HowToPlay.java @@ -0,0 +1,132 @@ +package com.csse3200.game.screens.HelpScreen; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.csse3200.game.GdxGame; +/** + * A screen that provides information on how to play the game. + */ +public class HowToPlay extends ScreenAdapter { + private final GdxGame game; + private Stage stage; + private SpriteBatch spriteBatch; + /** + * Creates a new HowToPlay screen. + * + * @param game The main game instance. + */ + + public HowToPlay(GdxGame game) { + this.game = game; + stage = new Stage(new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); + spriteBatch = new SpriteBatch(); + Skin skin = new Skin(Gdx.files.internal("images/ui/buttons/glass.json")); + + Label.LabelStyle labelStyle = new Label.LabelStyle(); + BitmapFont customFont = new BitmapFont(Gdx.files.internal("images/ui/buttons/dot_gothic_16.fnt")); + labelStyle.font = customFont; + + Texture backgroundTexture = new Texture("images/lose-screen/desktop-wallpaper-simple-stars-video-background-loop-black-and-white-aesthetic-space.jpg"); + Drawable backgroundDrawable = new TextureRegionDrawable(new TextureRegion(backgroundTexture)); + + // Create a table to hold the background image + Table backgroundTable = new Table(); + backgroundTable.setFillParent(true); + backgroundTable.add(new Image(backgroundDrawable)).expand().fill(); + + // Add the background table to the stage first + stage.addActor(backgroundTable); + // Create a table to organize the image placeholder + Table table = new Table(); + table.setFillParent(true); // Makes the table the size of the stage + + // Create one image placeholder + Image image = new Image(new Texture("images/HelpScreen/HTP.png")); + + // Add the image placeholder to the table + table.add(image).expand().fill(); + table.pad(60f); + + // Add the table to the stage + stage.addActor(table); + + + TextButton BackButton = new TextButton("Back", skin); + BackButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.MAIN_MENU); + + } + }); + + Texture imageTexture = new Texture("images/ui/Sprites/UI_Glass_Arrow_Large_01a - Copy.png"); + Drawable drawable = new TextureRegionDrawable(new TextureRegion(imageTexture)); + ImageButton HelpButton = new ImageButton(drawable); + HelpButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.HELP_SCREEN); + + } + }); + + + Table buttonTable = new Table(); + buttonTable.add(BackButton).padRight(10); + Table table1 = new Table(); + table1.setFillParent(true); + table1.top().right(); // Align to the top-right corner + table1.pad(20); // Add padding to the top-right corner + table1.add(buttonTable).row(); // Add button table and move to the next row + stage.addActor(table1); + + Table buttonTable1 = new Table(); + buttonTable1.add(HelpButton).padRight(10); + Table table2 = new Table(); + table2.setFillParent(true); + table2.center().top(); // Align to the middle-right corner + table2.pad(20); // Add padding to the middle-right corner + table2.add(buttonTable1).row(); // Add button table and move to the next row + stage.addActor(table2); + + } + @Override + public void show() { + // Set this screen as the input processor + Gdx.input.setInputProcessor(stage); + } + + @Override + public void render(float delta) { + // Clear the screen + spriteBatch.begin(); + spriteBatch.end(); + + // Draw the stage + stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); + stage.draw(); + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + } + + @Override + public void dispose() { + stage.dispose(); + spriteBatch.dispose(); + } +} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/HelpScreen/MobsDescriptionHelpScreen.java b/source/core/src/main/com/csse3200/game/screens/HelpScreen/MobsDescriptionHelpScreen.java new file mode 100644 index 000000000..1d89925fa --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/HelpScreen/MobsDescriptionHelpScreen.java @@ -0,0 +1,205 @@ +package com.csse3200.game.screens.HelpScreen; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.csse3200.game.GdxGame; +/** + * A screen that provides descriptions of different enemy mobs in the game. + */ + +public class MobsDescriptionHelpScreen extends ScreenAdapter { + private final GdxGame game; + private Stage stage; + private SpriteBatch spriteBatch; + + /** + * Creates a new MobsDescriptionHelpScreen. + * + * @param game The main game instance. + */ + public MobsDescriptionHelpScreen(GdxGame game) { + this.game = game; + stage = new Stage(new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); + spriteBatch = new SpriteBatch(); + + // Create a table to organize the image placeholder + Table table = new Table(); + table.setFillParent(true); // Makes the table the size of the stage + + // Create one image placeholder + Image image = new Image(new Texture("images/lose-screen/desktop-wallpaper-simple-stars-video-background-loop-black-and-white-aesthetic-space.jpg")); + + // Add the image placeholder to the table + table.add(image).expand().fill(); + + // Add the table to the stage + stage.addActor(table); + + Skin skin = new Skin(Gdx.files.internal("images/ui/buttons/glass.json")); + TextButton BackButton = new TextButton("Back", skin); + BackButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.MAIN_MENU); + } + }); + + TextButton TowersButton = new TextButton("Towers", skin); + TowersButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.HELP_TOWER_SCREEN); + } + }); + + TextButton BossButton = new TextButton("BossMobs", skin); + BossButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.HELP_BOSS_SCREEN); + } + }); + + Texture imageTexture = new Texture("images/ui/Sprites/UI_Glass_Arrow_Large_01a.png"); + Drawable drawable = new TextureRegionDrawable(new TextureRegion(imageTexture)); + ImageButton GameDescButton = new ImageButton(drawable); + GameDescButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.HELP_SCREEN); + } + }); + + Table buttonTable = new Table(); + buttonTable.add(BackButton).padRight(10); + Table table1 = new Table(); + table1.setFillParent(true); + table1.top().right(); // Align to the top-right corner + table1.pad(20); // Add padding to the top-right corner + table1.add(buttonTable).row(); // Add button table and move to the next row + stage.addActor(table1); + + Table buttonTable2 = new Table(); + buttonTable2.add(TowersButton).padRight(10); + Table table2 = new Table(); + table2.setFillParent(true); + table2.center().right(); // Align to the top-right corner + table2.pad(20); // Add padding to the top-right corner + table2.add(buttonTable2).row(); // Add button table and move to the next row + stage.addActor(table2); + + Table buttonTable3 = new Table(); + buttonTable3.add(GameDescButton).padRight(10); + Table table3 = new Table(); + table3.setFillParent(true); + table3.center().left(); // Align to the top-right corner + table3.pad(20); // Add padding to the top-right corner + table3.add(buttonTable3).row(); // Add button table and move to the next row + stage.addActor(table3); + + Table buttonTable4 = new Table(); + buttonTable4.add(BossButton).padRight(10); + Table table4 = new Table(); + table4.setFillParent(true); + table4.center().bottom(); // Align to the top-right corner + table4.pad(20); // Add padding to the top-right corner + table4.add(buttonTable4).row(); // Add button table and move to the next row + stage.addActor(table4); + + Table imageTextTable = new Table(); + imageTextTable.setFillParent(true); + imageTextTable.center(); + + float leftPadding = 30f; + imageTextTable.padLeft(leftPadding); + + // Create an array of image file names + String[] imageFileNames = { + "images/HelpScreen/Firewormhelp.png", + "images/HelpScreen/Dragonknighthelp.png", + "images/HelpScreen/Waterslimehelp.png", + "images/HelpScreen/WaterQueenhelp.png", + "images/HelpScreen/Skeletonhelp.png", + "images/HelpScreen/Wizardhelp.png", + }; + + // Create an array of text descriptions + String[] textDescriptions = { + "Fire Worm is able to shoot projectiles towards the towers.", + "DragonKnight is able to dodge projectiles.", + "Water slimes are able to split once dead", + "Water Queens are able to shoot towards the towers", + "Skeletons are able to do close range attack damage.", + "Wizards are able to deflect projectiles.", + }; + + // Add images and text to the table + for (int i = 0; i < imageFileNames.length; i++) { + // Create an image from the file + Image imager = new Image(new Texture( imageFileNames[i])); + float imageSize = 200f; + imager.setSize(imageSize, imageSize); + + // Create a label for text description + Label.LabelStyle labelStyle = new Label.LabelStyle(); + BitmapFont customFont = new BitmapFont(Gdx.files.internal("images/ui/buttons/dot_gothic_16.fnt")); // Replace "your-font.fnt" with your font file path + customFont.getData().setScale(1.2f); // Adjust the scale factor to change the text size + labelStyle.font = customFont; + + Label label = new Label(textDescriptions[i], labelStyle); + label.setWrap(true); + + // Add the image and label to the table in two columns + Cell imageCell = imageTextTable.add(imager).expandX().pad(10); // Add spacing around the image + Cell