diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..02e8b88ae Binary files /dev/null and b/.DS_Store differ diff --git a/source/core/assets/images/HelpScreen/Demonbosshelp.png b/source/core/assets/images/HelpScreen/Demonbosshelp.png deleted file mode 100644 index 502a41977..000000000 Binary files a/source/core/assets/images/HelpScreen/Demonbosshelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Dragonknighthelp.png b/source/core/assets/images/HelpScreen/Dragonknighthelp.png deleted file mode 100644 index 92594af03..000000000 Binary files a/source/core/assets/images/HelpScreen/Dragonknighthelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Econ.png b/source/core/assets/images/HelpScreen/Econ.png deleted file mode 100644 index 299bc7c22..000000000 Binary files a/source/core/assets/images/HelpScreen/Econ.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Engineer.png b/source/core/assets/images/HelpScreen/Engineer.png deleted file mode 100644 index 7bcb61922..000000000 Binary files a/source/core/assets/images/HelpScreen/Engineer.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Firewormhelp.png b/source/core/assets/images/HelpScreen/Firewormhelp.png deleted file mode 100644 index 1b1fb1be9..000000000 Binary files a/source/core/assets/images/HelpScreen/Firewormhelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/HTP.png b/source/core/assets/images/HelpScreen/HTP.png deleted file mode 100644 index fafc6b262..000000000 Binary files a/source/core/assets/images/HelpScreen/HTP.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/IceBosshelp.png b/source/core/assets/images/HelpScreen/IceBosshelp.png deleted file mode 100644 index af09d4c92..000000000 Binary files a/source/core/assets/images/HelpScreen/IceBosshelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Mob.png b/source/core/assets/images/HelpScreen/Mob.png deleted file mode 100644 index a0dfa6fda..000000000 Binary files a/source/core/assets/images/HelpScreen/Mob.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Patrickbosshelp.png b/source/core/assets/images/HelpScreen/Patrickbosshelp.png deleted file mode 100644 index d7d342e78..000000000 Binary files a/source/core/assets/images/HelpScreen/Patrickbosshelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Skeletonhelp.png b/source/core/assets/images/HelpScreen/Skeletonhelp.png deleted file mode 100644 index 258c6f730..000000000 Binary files a/source/core/assets/images/HelpScreen/Skeletonhelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Turret.png b/source/core/assets/images/HelpScreen/Turret.png deleted file mode 100644 index f8be39f9b..000000000 Binary files a/source/core/assets/images/HelpScreen/Turret.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/WaterQueenhelp.png b/source/core/assets/images/HelpScreen/WaterQueenhelp.png deleted file mode 100644 index 1481b12c0..000000000 Binary files a/source/core/assets/images/HelpScreen/WaterQueenhelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Waterslimehelp.png b/source/core/assets/images/HelpScreen/Waterslimehelp.png deleted file mode 100644 index 53884cbac..000000000 Binary files a/source/core/assets/images/HelpScreen/Waterslimehelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/Wizardhelp.png b/source/core/assets/images/HelpScreen/Wizardhelp.png deleted file mode 100644 index ab5be4a71..000000000 Binary files a/source/core/assets/images/HelpScreen/Wizardhelp.png and /dev/null differ diff --git a/source/core/assets/images/HelpScreen/hs.jpg b/source/core/assets/images/HelpScreen/hs.jpg deleted file mode 100644 index 44eb11456..000000000 Binary files a/source/core/assets/images/HelpScreen/hs.jpg and /dev/null differ diff --git a/source/core/assets/images/LoadingScreen.png b/source/core/assets/images/LoadingScreen.png deleted file mode 100644 index bfae39510..000000000 Binary files a/source/core/assets/images/LoadingScreen.png and /dev/null 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 54e011d2a..8fc9e4556 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 febd8eb6f..f0a0c5064 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/arcane_archer.atlas b/source/core/assets/images/mobs/arcane_archer.atlas index 5acf48d80..b43656e7f 100644 --- a/source/core/assets/images/mobs/arcane_archer.atlas +++ b/source/core/assets/images/mobs/arcane_archer.atlas @@ -1,223 +1,223 @@ - -arcane_archer.png -size: 512, 256 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -arcane_archer_attack - rotate: false - xy: 290, 2 - size: 65, 44 - orig: 65, 44 - offset: 0, 0 - index: -1 -arcane_archer_attack - rotate: false - xy: 362, 140 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_attack - rotate: false - xy: 146, 94 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_attack - rotate: false - xy: 74, 186 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_attack - rotate: false - xy: 362, 186 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_attack - rotate: false - xy: 218, 186 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_attack - rotate: false - xy: 362, 94 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_death - rotate: false - xy: 2, 2 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_death - rotate: false - xy: 2, 140 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_death - rotate: false - xy: 146, 48 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_death - rotate: false - xy: 74, 94 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_death - rotate: false - xy: 434, 186 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_death - rotate: false - xy: 218, 140 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_death - rotate: false - xy: 2, 94 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_death - rotate: false - xy: 146, 2 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_dodge - rotate: false - xy: 434, 140 - size: 69, 44 - orig: 69, 44 - offset: 0, 0 - index: -1 -arcane_archer_dodge - rotate: false - xy: 290, 140 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_dodge - rotate: false - xy: 146, 140 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_dodge - rotate: false - xy: 290, 48 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_dodge - rotate: false - xy: 74, 2 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_dodge - rotate: false - xy: 146, 186 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_dodge - rotate: false - xy: 290, 94 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_run - rotate: false - xy: 74, 48 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_run - rotate: false - xy: 2, 186 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_run - rotate: false - xy: 218, 94 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_run - rotate: false - xy: 2, 48 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_run - rotate: false - xy: 218, 2 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_run - rotate: false - xy: 290, 186 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_run - rotate: false - xy: 74, 140 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -arcane_archer_run - rotate: false - xy: 218, 48 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 218, 48 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 + +arcane_archer.png +size: 512, 256 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +arcane_archer_attack + rotate: false + xy: 290, 2 + size: 65, 44 + orig: 65, 44 + offset: 0, 0 + index: -1 +arcane_archer_attack + rotate: false + xy: 362, 140 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_attack + rotate: false + xy: 146, 94 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_attack + rotate: false + xy: 74, 186 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_attack + rotate: false + xy: 362, 186 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_attack + rotate: false + xy: 218, 186 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_attack + rotate: false + xy: 362, 94 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_death + rotate: false + xy: 2, 2 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_death + rotate: false + xy: 2, 140 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_death + rotate: false + xy: 146, 48 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_death + rotate: false + xy: 74, 94 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_death + rotate: false + xy: 434, 186 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_death + rotate: false + xy: 218, 140 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_death + rotate: false + xy: 2, 94 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_death + rotate: false + xy: 146, 2 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_dodge + rotate: false + xy: 434, 140 + size: 69, 44 + orig: 69, 44 + offset: 0, 0 + index: -1 +arcane_archer_dodge + rotate: false + xy: 290, 140 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_dodge + rotate: false + xy: 146, 140 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_dodge + rotate: false + xy: 290, 48 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_dodge + rotate: false + xy: 74, 2 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_dodge + rotate: false + xy: 146, 186 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_dodge + rotate: false + xy: 290, 94 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_run + rotate: false + xy: 74, 48 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_run + rotate: false + xy: 2, 186 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_run + rotate: false + xy: 218, 94 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_run + rotate: false + xy: 2, 48 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_run + rotate: false + xy: 218, 2 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_run + rotate: false + xy: 290, 186 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_run + rotate: false + xy: 74, 140 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +arcane_archer_run + rotate: false + xy: 218, 48 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 218, 48 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/mobs/coat.atlas b/source/core/assets/images/mobs/coat.atlas index f98ef17d8..ae65fd9ac 100644 --- a/source/core/assets/images/mobs/coat.atlas +++ b/source/core/assets/images/mobs/coat.atlas @@ -1,167 +1,167 @@ - -coat.png -size: 1024, 64 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -coat_attack - rotate: false - xy: 498, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 98, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 218, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 2, 25 - size: 54, 37 - orig: 54, 37 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 378, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 138, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 618, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 258, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 698, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_attack - rotate: false - xy: 418, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_death - rotate: false - xy: 578, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_death - rotate: false - xy: 298, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_death - rotate: false - xy: 738, 32 - size: 33, 30 - orig: 33, 30 - offset: 0, 0 - index: -1 -coat_death - rotate: false - xy: 773, 36 - size: 31, 26 - orig: 31, 26 - offset: 0, 0 - index: -1 -coat_death - rotate: false - xy: 2, 2 - size: 30, 21 - orig: 30, 21 - offset: 0, 0 - index: -1 -coat_death - rotate: false - xy: 806, 44 - size: 25, 18 - orig: 25, 18 - offset: 0, 0 - index: -1 -coat_run - rotate: false - xy: 458, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_run - rotate: false - xy: 178, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_run - rotate: false - xy: 658, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_run - rotate: false - xy: 338, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_run - rotate: false - xy: 58, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -coat_run - rotate: false - xy: 538, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 538, 24 - size: 38, 38 - orig: 38, 38 - offset: 0, 0 - index: -1 + +coat.png +size: 1024, 64 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +coat_attack + rotate: false + xy: 498, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 98, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 218, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 2, 25 + size: 54, 37 + orig: 54, 37 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 378, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 138, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 618, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 258, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 698, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_attack + rotate: false + xy: 418, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_death + rotate: false + xy: 578, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_death + rotate: false + xy: 298, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_death + rotate: false + xy: 738, 32 + size: 33, 30 + orig: 33, 30 + offset: 0, 0 + index: -1 +coat_death + rotate: false + xy: 773, 36 + size: 31, 26 + orig: 31, 26 + offset: 0, 0 + index: -1 +coat_death + rotate: false + xy: 2, 2 + size: 30, 21 + orig: 30, 21 + offset: 0, 0 + index: -1 +coat_death + rotate: false + xy: 806, 44 + size: 25, 18 + orig: 25, 18 + offset: 0, 0 + index: -1 +coat_run + rotate: false + xy: 458, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_run + rotate: false + xy: 178, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_run + rotate: false + xy: 658, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_run + rotate: false + xy: 338, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_run + rotate: false + xy: 58, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +coat_run + rotate: false + xy: 538, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 538, 24 + size: 38, 38 + orig: 38, 38 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/mobs/dragon_knight.atlas b/source/core/assets/images/mobs/dragon_knight.atlas index 59a0335b8..4d698370a 100644 --- a/source/core/assets/images/mobs/dragon_knight.atlas +++ b/source/core/assets/images/mobs/dragon_knight.atlas @@ -25,6 +25,13 @@ dragon_knight_attack orig: 99, 99 offset: 0, 0 index: -1 +dragon_knight_freeze + rotate: false + xy: 407, 2 + size: 99, 99 + orig: 99, 99 + offset: 0, 0 + index: -1 dragon_knight_attack rotate: false xy: 2, 308 diff --git a/source/core/assets/images/mobs/dragon_knight.png b/source/core/assets/images/mobs/dragon_knight.png index 85bcd9340..2a18fb0c0 100644 Binary files a/source/core/assets/images/mobs/dragon_knight.png and b/source/core/assets/images/mobs/dragon_knight.png differ diff --git a/source/core/assets/images/mobs/fire_worm.atlas b/source/core/assets/images/mobs/fire_worm.atlas index d647dd3a1..4014b6279 100644 --- a/source/core/assets/images/mobs/fire_worm.atlas +++ b/source/core/assets/images/mobs/fire_worm.atlas @@ -130,6 +130,13 @@ fire_worm_death orig: 75, 75 offset: 0, 0 index: -1 +fire_worm_freeze + rotate: false + xy: 770, 2 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 fire_worm_death rotate: false xy: 2, 156 diff --git a/source/core/assets/images/mobs/fire_worm.png b/source/core/assets/images/mobs/fire_worm.png index 9311b527a..ab3cf4698 100644 Binary files a/source/core/assets/images/mobs/fire_worm.png and b/source/core/assets/images/mobs/fire_worm.png differ diff --git a/source/core/assets/images/mobs/fire_worm_attack.atlas b/source/core/assets/images/mobs/fire_worm_attack.atlas index c8d2e2d1f..fcb3d0597 100644 --- a/source/core/assets/images/mobs/fire_worm_attack.atlas +++ b/source/core/assets/images/mobs/fire_worm_attack.atlas @@ -1,118 +1,118 @@ - -fire_worm_attack.png -size: 256, 512 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -fire_worm_attack1 - rotate: false - xy: 2, 156 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack10 - rotate: false - xy: 2, 79 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack11 - rotate: false - xy: 79, 387 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack12 - rotate: false - xy: 79, 79 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack13 - rotate: false - xy: 79, 233 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack14 - rotate: false - xy: 2, 387 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack15 - rotate: false - xy: 156, 233 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack16 - rotate: false - xy: 79, 310 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack2 - rotate: false - xy: 79, 2 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack3 - rotate: false - xy: 79, 156 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack4 - rotate: false - xy: 2, 233 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack5 - rotate: false - xy: 156, 156 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack6 - rotate: false - xy: 156, 310 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack7 - rotate: false - xy: 2, 310 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack8 - rotate: false - xy: 2, 2 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 -fire_worm_attack9 - rotate: false - xy: 156, 387 - size: 75, 75 - orig: 75, 75 - offset: 0, 0 - index: -1 + +fire_worm_attack.png +size: 256, 512 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +fire_worm_attack1 + rotate: false + xy: 2, 156 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack10 + rotate: false + xy: 2, 79 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack11 + rotate: false + xy: 79, 387 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack12 + rotate: false + xy: 79, 79 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack13 + rotate: false + xy: 79, 233 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack14 + rotate: false + xy: 2, 387 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack15 + rotate: false + xy: 156, 233 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack16 + rotate: false + xy: 79, 310 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack2 + rotate: false + xy: 79, 2 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack3 + rotate: false + xy: 79, 156 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack4 + rotate: false + xy: 2, 233 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack5 + rotate: false + xy: 156, 156 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack6 + rotate: false + xy: 156, 310 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack7 + rotate: false + xy: 2, 310 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack8 + rotate: false + xy: 2, 2 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 +fire_worm_attack9 + rotate: false + xy: 156, 387 + size: 75, 75 + orig: 75, 75 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/mobs/fire_worm_walk b/source/core/assets/images/mobs/fire_worm_walk index 0cb3f5ec3..bea8b8b25 100644 --- a/source/core/assets/images/mobs/fire_worm_walk +++ b/source/core/assets/images/mobs/fire_worm_walk @@ -1,69 +1,69 @@ - -fire_worm_walk.png -size: 1024, 128 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -fire_worm_walk1 - rotate: false - xy: 646, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 -fire_worm_walk2 - rotate: false - xy: 278, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 -fire_worm_walk3 - rotate: false - xy: 2, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 -fire_worm_walk4 - rotate: false - xy: 462, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 -fire_worm_walk5 - rotate: false - xy: 186, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 -fire_worm_walk6 - rotate: false - xy: 738, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 -fire_worm_walk7 - rotate: false - xy: 370, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 -fire_worm_walk8 - rotate: false - xy: 94, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 -fire_worm_walk9 - rotate: false - xy: 554, 2 - size: 90, 90 - orig: 90, 90 - offset: 0, 0 - index: -1 + +fire_worm_walk.png +size: 1024, 128 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +fire_worm_walk1 + rotate: false + xy: 646, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 +fire_worm_walk2 + rotate: false + xy: 278, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 +fire_worm_walk3 + rotate: false + xy: 2, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 +fire_worm_walk4 + rotate: false + xy: 462, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 +fire_worm_walk5 + rotate: false + xy: 186, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 +fire_worm_walk6 + rotate: false + xy: 738, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 +fire_worm_walk7 + rotate: false + xy: 370, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 +fire_worm_walk8 + rotate: false + xy: 94, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 +fire_worm_walk9 + rotate: false + xy: 554, 2 + size: 90, 90 + orig: 90, 90 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/mobs/firewizard.atlas b/source/core/assets/images/mobs/firewizard.atlas deleted file mode 100644 index dacee9afe..000000000 --- a/source/core/assets/images/mobs/firewizard.atlas +++ /dev/null @@ -1,160 +0,0 @@ - -firewizard.png -size: 2048, 128 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -firewizard_attack - rotate: false - xy: 492, 8 - size: 96, 72 - orig: 96, 72 - offset: 0, 0 - index: -1 -firewizard_attack - rotate: false - xy: 296, 8 - size: 96, 72 - orig: 96, 72 - offset: 0, 0 - index: -1 -firewizard_attack - rotate: false - xy: 2, 8 - size: 96, 72 - orig: 96, 72 - offset: 0, 0 - index: -1 -firewizard_attack - rotate: false - xy: 394, 8 - size: 96, 72 - orig: 96, 72 - offset: 0, 0 - index: -1 -firewizard_attack - rotate: false - xy: 198, 8 - size: 96, 72 - orig: 96, 72 - offset: 0, 0 - index: -1 -firewizard_attack - rotate: false - xy: 688, 11 - size: 96, 69 - orig: 96, 69 - offset: 0, 0 - index: -1 -firewizard_attack - rotate: false - xy: 590, 11 - size: 96, 69 - orig: 96, 69 - offset: 0, 0 - index: -1 -firewizard_attack - rotate: false - xy: 100, 8 - size: 96, 72 - orig: 96, 72 - offset: 0, 0 - index: -1 -firewizard_death - rotate: false - xy: 1389, 16 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -firewizard_death - rotate: false - xy: 1521, 16 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -firewizard_death - rotate: false - xy: 1323, 16 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -firewizard_death - rotate: false - xy: 1587, 16 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -firewizard_death - rotate: false - xy: 1455, 16 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -firewizard_move - rotate: false - xy: 1189, 2 - size: 65, 78 - orig: 65, 78 - offset: 0, 0 - index: -1 -firewizard_move - rotate: false - xy: 988, 2 - size: 65, 78 - orig: 65, 78 - offset: 0, 0 - index: -1 -firewizard_mov - rotate: false - xy: 786, 2 - size: 66, 78 - orig: 66, 78 - offset: 0, 0 - index: -1 -firewizard_move - rotate: false - xy: 1122, 2 - size: 65, 78 - orig: 65, 78 - offset: 0, 0 - index: -1 -firewizard_move - rotate: false - xy: 921, 2 - size: 65, 78 - orig: 65, 78 - offset: 0, 0 - index: -1 -firewizard_move - rotate: false - xy: 1256, 2 - size: 65, 78 - orig: 65, 78 - offset: 0, 0 - index: -1 -firewizard_move - rotate: false - xy: 1055, 2 - size: 65, 78 - orig: 65, 78 - offset: 0, 0 - index: -1 -firewizard_move - rotate: false - xy: 854, 2 - size: 65, 78 - orig: 65, 78 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 854, 2 - size: 65, 78 - orig: 65, 78 - offset: 0, 0 - index: -1 \ No newline at end of file diff --git a/source/core/assets/images/mobs/firewizard.png b/source/core/assets/images/mobs/firewizard.png deleted file mode 100644 index d612b5352..000000000 Binary files a/source/core/assets/images/mobs/firewizard.png and /dev/null differ diff --git a/source/core/assets/images/mobs/necromancer.atlas b/source/core/assets/images/mobs/necromancer.atlas deleted file mode 100644 index b83e6c86f..000000000 --- a/source/core/assets/images/mobs/necromancer.atlas +++ /dev/null @@ -1,167 +0,0 @@ - -necromancer.png -size: 2048, 256 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -necromancer_attack - rotate: false - xy: 304, 5 - size: 70, 105 - orig: 70, 105 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 1558, 116 - size: 70, 110 - orig: 70, 110 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 1702, 121 - size: 70, 105 - orig: 70, 105 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 1630, 121 - size: 70, 105 - orig: 70, 105 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 1774, 121 - size: 70, 105 - orig: 70, 105 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 160, 5 - size: 70, 105 - orig: 70, 105 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 88, 5 - size: 70, 105 - orig: 70, 105 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 232, 5 - size: 70, 105 - orig: 70, 105 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 2, 112 - size: 1554, 114 - orig: 1554, 114 - offset: 0, 0 - index: -1 -necromancer_attack - rotate: false - xy: 2, 2 - size: 84, 108 - orig: 84, 108 - offset: 0, 0 - index: -1 -necromancer_death - rotate: false - xy: 601, 37 - size: 73, 73 - orig: 73, 73 - offset: 0, 0 - index: -1 -necromancer_death - rotate: false - xy: 451, 37 - size: 73, 73 - orig: 73, 73 - offset: 0, 0 - index: -1 -necromancer_death - rotate: false - xy: 376, 37 - size: 73, 73 - orig: 73, 73 - offset: 0, 0 - index: -1 -necromancer_death - rotate: false - xy: 526, 37 - size: 73, 73 - orig: 73, 73 - offset: 0, 0 - index: -1 -necromancer_death - rotate: false - xy: 1921, 153 - size: 73, 73 - orig: 73, 73 - offset: 0, 0 - index: -1 -necromancer_death - rotate: false - xy: 1846, 153 - size: 73, 73 - orig: 73, 73 - offset: 0, 0 - index: -1 -necromancer_walk - rotate: false - xy: 676, 37 - size: 69, 73 - orig: 69, 73 - offset: 0, 0 - index: -1 -necromancer_walk - rotate: false - xy: 960, 37 - size: 69, 73 - orig: 69, 73 - offset: 0, 0 - index: -1 -necromancer_walk - rotate: false - xy: 818, 37 - size: 69, 73 - orig: 69, 73 - offset: 0, 0 - index: -1 -necromancer_walk - rotate: false - xy: 1031, 37 - size: 69, 73 - orig: 69, 73 - offset: 0, 0 - index: -1 -necromancer_walk - rotate: false - xy: 889, 37 - size: 69, 73 - orig: 69, 73 - offset: 0, 0 - index: -1 -necromancer_walk - rotate: false - xy: 747, 37 - size: 69, 73 - orig: 69, 73 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 747, 37 - size: 69, 73 - orig: 69, 73 - offset: 0, 0 - index: -1 \ No newline at end of file diff --git a/source/core/assets/images/mobs/necromancer.png b/source/core/assets/images/mobs/necromancer.png deleted file mode 100644 index c86c5cc2c..000000000 Binary files a/source/core/assets/images/mobs/necromancer.png and /dev/null differ diff --git a/source/core/assets/images/mobs/night_borne.atlas b/source/core/assets/images/mobs/night_borne.atlas index bc5f17c49..e01ece4c4 100644 --- a/source/core/assets/images/mobs/night_borne.atlas +++ b/source/core/assets/images/mobs/night_borne.atlas @@ -1,251 +1,251 @@ - -night_borne.png -size: 2048, 128 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -night_borne_attack - rotate: false - xy: 84, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 2, 54 - size: 80, 61 - orig: 80, 61 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 1232, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 740, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 822, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 330, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 1068, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 658, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 166, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 904, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 412, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_attack - rotate: false - xy: 1150, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 1232, 19 - size: 70, 44 - orig: 70, 44 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 904, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 904, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 412, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 740, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 248, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 986, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 576, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 84, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 822, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 330, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 1068, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 576, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 576, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 166, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_death - rotate: false - xy: 494, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_run - rotate: false - xy: 1150, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_run - rotate: false - xy: 658, 13 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_run - rotate: false - xy: 248, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_run - rotate: false - xy: 986, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_run - rotate: false - xy: 494, 65 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -night_borne_run - rotate: false - xy: 2, 2 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 2, 2 - size: 80, 50 - orig: 80, 50 - offset: 0, 0 - index: -1 + +night_borne.png +size: 2048, 128 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +night_borne_attack + rotate: false + xy: 84, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 2, 54 + size: 80, 61 + orig: 80, 61 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 1232, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 740, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 822, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 330, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 1068, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 658, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 166, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 904, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 412, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_attack + rotate: false + xy: 1150, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 1232, 19 + size: 70, 44 + orig: 70, 44 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 904, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 904, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 412, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 740, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 248, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 986, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 576, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 84, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 822, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 330, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 1068, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 576, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 576, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 166, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_death + rotate: false + xy: 494, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_run + rotate: false + xy: 1150, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_run + rotate: false + xy: 658, 13 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_run + rotate: false + xy: 248, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_run + rotate: false + xy: 986, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_run + rotate: false + xy: 494, 65 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +night_borne_run + rotate: false + xy: 2, 2 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 2, 2 + size: 80, 50 + orig: 80, 50 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/mobs/rangeBossRight.atlas b/source/core/assets/images/mobs/rangeBossRight.atlas index e96a1893f..7403df738 100644 --- a/source/core/assets/images/mobs/rangeBossRight.atlas +++ b/source/core/assets/images/mobs/rangeBossRight.atlas @@ -1,54 +1,54 @@ -rangeBossRight.png -size: 243, 62 -format: RGBA8888 -filter: Linear,Linear -repeat: none -Walk - rotate: false - xy: 205, 0 - size: 38, 61 - orig: 96, 114 - offset: 15, 30 - index: -1 -Walk - rotate: false - xy: 123, 0 - size: 35, 62 - orig: 96, 114 - offset: 15, 30 - index: -1 -Walk - rotate: false - xy: 0, 0 - size: 43, 62 - orig: 96, 114 - offset: 10, 30 - index: -1 -Walk - rotate: false - xy: 158, 0 - size: 47, 61 - orig: 96, 114 - offset: 8, 30 - index: -1 -Walk - rotate: false - xy: 43, 0 - size: 43, 62 - orig: 96, 114 - offset: 10, 30 - index: -1 -Walk - rotate: false - xy: 86, 0 - size: 37, 62 - orig: 96, 114 - offset: 15, 30 - index: -1 -default - rotate: false - xy: 86, 0 - size: 37, 62 - orig: 96, 114 - offset: 15, 30 - index: -1 +rangeBossRight.png +size: 243, 62 +format: RGBA8888 +filter: Linear,Linear +repeat: none +Walk + rotate: false + xy: 205, 0 + size: 38, 61 + orig: 96, 114 + offset: 15, 30 + index: -1 +Walk + rotate: false + xy: 123, 0 + size: 35, 62 + orig: 96, 114 + offset: 15, 30 + index: -1 +Walk + rotate: false + xy: 0, 0 + size: 43, 62 + orig: 96, 114 + offset: 10, 30 + index: -1 +Walk + rotate: false + xy: 158, 0 + size: 47, 61 + orig: 96, 114 + offset: 8, 30 + index: -1 +Walk + rotate: false + xy: 43, 0 + size: 43, 62 + orig: 96, 114 + offset: 10, 30 + index: -1 +Walk + rotate: false + xy: 86, 0 + size: 37, 62 + orig: 96, 114 + offset: 15, 30 + index: -1 +default + rotate: false + xy: 86, 0 + size: 37, 62 + orig: 96, 114 + offset: 15, 30 + index: -1 diff --git a/source/core/assets/images/mobs/robot.atlas b/source/core/assets/images/mobs/robot.atlas index 843e14ce1..9021ebcc7 100644 --- a/source/core/assets/images/mobs/robot.atlas +++ b/source/core/assets/images/mobs/robot.atlas @@ -1,56 +1,56 @@ -robot.png -size: 1024, 256 -format: RGBA8888 -filter: Linear,Linear -repeat: none -Walk - rotate: false - xy: 334, 34 - size: 30, 74 - orig: 30, 74 - offset: 46, -54 - index: -1 -Walk - rotate: false - xy: 632, 34 - size: 30, 73 - orig: 30, 73 - offset: 46, -55 - index: -1 -Walk - rotate: false - xy: 781, 34 - size: 32, 72 - orig: 32, 72 - offset: 46, -56 - index: -1 -Walk - rotate: false - xy: 483, 34 - size: 30, 73 - orig: 30, 73 - offset: 46, -55 - index: -1 -Walk - rotate: false - xy: 185, 34 - size: 30, 74 - orig: 30, 74 - offset: 46, -54 - index: -1 -Walk - rotate: false - xy: 34, 34 - size: 32, 75 - orig: 32, 75 - offset: 46, -53 - index: -1 -default - rotate: false - xy: 34, 34 - size: 32, 75 - orig: 32, 75 - offset: 46, -53 - index: -1 - - +robot.png +size: 1024, 256 +format: RGBA8888 +filter: Linear,Linear +repeat: none +Walk + rotate: false + xy: 334, 34 + size: 30, 74 + orig: 30, 74 + offset: 46, -54 + index: -1 +Walk + rotate: false + xy: 632, 34 + size: 30, 73 + orig: 30, 73 + offset: 46, -55 + index: -1 +Walk + rotate: false + xy: 781, 34 + size: 32, 72 + orig: 32, 72 + offset: 46, -56 + index: -1 +Walk + rotate: false + xy: 483, 34 + size: 30, 73 + orig: 30, 73 + offset: 46, -55 + index: -1 +Walk + rotate: false + xy: 185, 34 + size: 30, 74 + orig: 30, 74 + offset: 46, -54 + index: -1 +Walk + rotate: false + xy: 34, 34 + size: 32, 75 + orig: 32, 75 + offset: 46, -53 + index: -1 +default + rotate: false + xy: 34, 34 + size: 32, 75 + orig: 32, 75 + offset: 46, -53 + index: -1 + + diff --git a/source/core/assets/images/mobs/rocky.atlas b/source/core/assets/images/mobs/rocky.atlas deleted file mode 100644 index c29e734ba..000000000 --- a/source/core/assets/images/mobs/rocky.atlas +++ /dev/null @@ -1,174 +0,0 @@ - -rocky.png -size: 512, 32 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -rocky_death - rotate: false - xy: 359, 7 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -rocky_death - rotate: false - xy: 449, 7 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -rocky_death - rotate: false - xy: 395, 7 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -rocky_death - rotate: false - xy: 341, 6 - size: 16, 17 - orig: 16, 17 - offset: 0, 0 - index: -1 -rocky_death - rotate: false - xy: 431, 7 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -rocky_death - rotate: false - xy: 377, 7 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -rocky_death - rotate: false - xy: 467, 7 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -rocky_death - rotate: false - xy: 413, 7 - size: 16, 16 - orig: 16, 16 - offset: 0, 0 - index: -1 -rocky_move - rotate: false - xy: 231, 3 - size: 20, 20 - orig: 20, 20 - offset: 0, 0 - index: -1 -rocky_move - rotate: false - xy: 319, 3 - size: 20, 20 - orig: 20, 20 - offset: 0, 0 - index: -1 -rocky_move - rotate: false - xy: 275, 3 - size: 20, 20 - orig: 20, 20 - offset: 0, 0 - index: -1 -rocky_move - rotate: false - xy: 209, 3 - size: 20, 20 - orig: 20, 20 - offset: 0, 0 - index: -1 -rocky_move - rotate: false - xy: 297, 3 - size: 20, 20 - orig: 20, 20 - offset: 0, 0 - index: -1 -rocky_move - rotate: false - xy: 253, 3 - size: 20, 20 - orig: 20, 20 - offset: 0, 0 - index: -1 -rocky_move - rotate: false - xy: 187, 3 - size: 20, 20 - orig: 20, 20 - offset: 0, 0 - index: -1 -rocky_attack - rotate: false - xy: 164, 2 - size: 21, 21 - orig: 21, 21 - offset: 0, 0 - index: -1 -rocky_attack - rotate: false - xy: 95, 2 - size: 21, 21 - orig: 21, 21 - offset: 0, 0 - index: -1 -rocky_attack - rotate: false - xy: 49, 2 - size: 21, 21 - orig: 21, 21 - offset: 0, 0 - index: -1 -rocky_attack - rotate: false - xy: 141, 2 - size: 21, 21 - orig: 21, 21 - offset: 0, 0 - index: -1 -rocky_attack - rotate: false - xy: 2, 2 - size: 22, 21 - orig: 22, 21 - offset: 0, 0 - index: -1 -rocky_attack - rotate: false - xy: 26, 2 - size: 21, 21 - orig: 21, 21 - offset: 0, 0 - index: -1 -rocky_attack - rotate: false - xy: 118, 2 - size: 21, 21 - orig: 21, 21 - offset: 0, 0 - index: -1 -rocky_attack - rotate: false - xy: 72, 2 - size: 21, 21 - orig: 21, 21 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 253, 3 - size: 20, 20 - orig: 20, 20 - offset: 0, 0 - index: -1 \ No newline at end of file diff --git a/source/core/assets/images/mobs/rocky.png b/source/core/assets/images/mobs/rocky.png deleted file mode 100644 index 86375354a..000000000 Binary files a/source/core/assets/images/mobs/rocky.png and /dev/null differ diff --git a/source/core/assets/images/mobs/skeleton.atlas b/source/core/assets/images/mobs/skeleton.atlas index 9e1c78e17..75c312c80 100644 --- a/source/core/assets/images/mobs/skeleton.atlas +++ b/source/core/assets/images/mobs/skeleton.atlas @@ -46,6 +46,13 @@ skeleton_attack orig: 62, 48 offset: 0, 0 index: -1 +skeleton_freeze + rotate: false + xy: 1152, 2 + size: 62, 48 + orig: 62, 48 + offset: 0, 0 + index: -1 skeleton_attack rotate: false xy: 642, 2 @@ -69,7 +76,7 @@ skeleton_attack index: -1 skeleton_attack rotate: false - xy: 578, 52 + xy: 514, 2 size: 62, 48 orig: 62, 48 offset: 0, 0 @@ -83,7 +90,7 @@ skeleton_attack index: -1 skeleton_attack rotate: false - xy: 834, 52 + xy: 770, 2 size: 62, 48 orig: 62, 48 offset: 0, 0 @@ -95,6 +102,41 @@ 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 @@ -153,7 +195,7 @@ skeleton_walk index: -1 skeleton_walk rotate: false - xy: 514, 2 + xy: 514, 52 size: 62, 48 orig: 62, 48 offset: 0, 0 @@ -167,7 +209,7 @@ skeleton_walk index: -1 skeleton_walk rotate: false - xy: 770, 2 + xy: 770, 52 size: 62, 48 orig: 62, 48 offset: 0, 0 @@ -202,21 +244,21 @@ skeleton_walk index: -1 skeleton_walk rotate: false - xy: 514, 52 + xy: 578, 52 size: 62, 48 orig: 62, 48 offset: 0, 0 index: -1 skeleton_walk rotate: false - xy: 66, 52 + xy: 130, 2 size: 62, 48 orig: 62, 48 offset: 0, 0 index: -1 skeleton_walk rotate: false - xy: 770, 52 + xy: 834, 2 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 9d75bb066..dd724a4bb 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/mobs/water_queen.atlas b/source/core/assets/images/mobs/water_queen.atlas index f3d5ea8fc..03e97ae14 100644 --- a/source/core/assets/images/mobs/water_queen.atlas +++ b/source/core/assets/images/mobs/water_queen.atlas @@ -151,6 +151,13 @@ water_queen_walk orig: 90, 60 offset: 0, 0 index: -1 +water_queen_freeze + rotate: false + xy: 1104, 2 + size: 90, 60 + orig: 90, 60 + offset: 0, 0 + index: -1 water_queen_walk rotate: false xy: 554, 2 diff --git a/source/core/assets/images/mobs/water_queen.png b/source/core/assets/images/mobs/water_queen.png index bbed31311..bf4ae7659 100644 Binary files a/source/core/assets/images/mobs/water_queen.png and b/source/core/assets/images/mobs/water_queen.png differ diff --git a/source/core/assets/images/mobs/water_slime.atlas b/source/core/assets/images/mobs/water_slime.atlas index 767f1cd29..dec3cd62d 100644 --- a/source/core/assets/images/mobs/water_slime.atlas +++ b/source/core/assets/images/mobs/water_slime.atlas @@ -53,6 +53,13 @@ water_slime_death orig: 32, 25 offset: 0, 0 index: -1 +water_slime_freeze + rotate: false + xy: 442, 2 + size: 32, 25 + orig: 32, 25 + offset: 0, 0 + index: -1 water_slime_death rotate: false xy: 240, 2 diff --git a/source/core/assets/images/mobs/water_slime.png b/source/core/assets/images/mobs/water_slime.png index 66b1b071f..eff01c635 100644 Binary files a/source/core/assets/images/mobs/water_slime.png and b/source/core/assets/images/mobs/water_slime.png differ diff --git a/source/core/assets/images/mobs/wizard.atlas b/source/core/assets/images/mobs/wizard.atlas index f9a87a81f..74cccd6e8 100644 --- a/source/core/assets/images/mobs/wizard.atlas +++ b/source/core/assets/images/mobs/wizard.atlas @@ -102,6 +102,13 @@ wizard_death orig: 110, 90 offset: 0, 0 index: -1 +wizard_freeze + rotate: false + xy: 1250, 94 + size: 110, 90 + orig: 110, 90 + offset: 0, 0 + index: -1 wizard_death rotate: false xy: 804, 2 diff --git a/source/core/assets/images/mobs/wizard.png b/source/core/assets/images/mobs/wizard.png index bcb6208b0..e948ce12e 100644 Binary files a/source/core/assets/images/mobs/wizard.png and b/source/core/assets/images/mobs/wizard.png differ diff --git a/source/core/assets/images/mobs/xeno-Grunt.png b/source/core/assets/images/mobs/xeno-Grunt.png index 543bae78e..ec430c93e 100644 Binary files a/source/core/assets/images/mobs/xeno-Grunt.png and b/source/core/assets/images/mobs/xeno-Grunt.png differ diff --git a/source/core/assets/images/mobs/xenoGrunt.atlas b/source/core/assets/images/mobs/xenoGrunt.atlas index c57686a05..8a1f824e7 100644 --- a/source/core/assets/images/mobs/xenoGrunt.atlas +++ b/source/core/assets/images/mobs/xenoGrunt.atlas @@ -59,6 +59,13 @@ xeno_run orig: 200, 200 offset: 0, 0 index: 7 +xeno_freeze + rotate: false + xy: 1600, 0 + size: 200, 200 + orig: 200, 200 + offset: 0, 0 + index: -1 xeno_hurt rotate: false xy: 0, 200 diff --git a/source/core/assets/images/projectiles/arrow.atlas b/source/core/assets/images/projectiles/arrow.atlas new file mode 100644 index 000000000..1a1eaef13 --- /dev/null +++ b/source/core/assets/images/projectiles/arrow.atlas @@ -0,0 +1,54 @@ +arrow.png +size: 390, 44 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +arrow + rotate: false + xy: 65, 0 + size: 65, 44 + orig: 65, 44 + offset: 0, 0 + index: -1 +arrow + rotate: false + xy: 130, 0 + size: 65, 44 + orig: 65, 44 + offset: 0, 0 + index: -1 +arrow + rotate: false + xy: 195, 0 + size: 65, 44 + orig: 65, 44 + offset: 0, 0 + index: -1 +arrow + rotate: false + xy: 260, 0 + size: 65, 44 + orig: 65, 44 + offset: 0, 0 + index: -1 +arrow + rotate: false + xy: 325, 0 + size: 65, 44 + orig: 65, 44 + offset: 0, 0 + index: -1 +arrow + rotate: false + xy: 0, 0 + size: 65, 44 + orig: 65, 44 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 0, 0 + size: 65, 44 + orig: 65, 44 + offset: 0, 0 + index: -1 \ No newline at end of file diff --git a/source/core/assets/images/projectiles/arrow.png b/source/core/assets/images/projectiles/arrow.png new file mode 100644 index 000000000..2db4cccc1 Binary files /dev/null and b/source/core/assets/images/projectiles/arrow.png differ diff --git a/source/core/assets/images/projectiles/attack_projectile.atlas b/source/core/assets/images/projectiles/attack_projectile.atlas index 19ed43f53..95f152253 100644 --- a/source/core/assets/images/projectiles/attack_projectile.atlas +++ b/source/core/assets/images/projectiles/attack_projectile.atlas @@ -1,33 +1,33 @@ -attack_projectile.png -size: 420, 93 -format: RGBA8888 -filter: Linear,Linear -repeat: none -P - rotate: false - xy: 0, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -P - rotate: false - xy: 140, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -p - rotate: false - xy: 280, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 280, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 +attack_projectile.png +size: 420, 93 +format: RGBA8888 +filter: Linear,Linear +repeat: none +P + rotate: false + xy: 0, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +P + rotate: false + xy: 140, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +p + rotate: false + xy: 280, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 280, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/projectiles/basic_projectile.atlas b/source/core/assets/images/projectiles/basic_projectile.atlas index 9d295b888..80a571deb 100644 --- a/source/core/assets/images/projectiles/basic_projectile.atlas +++ b/source/core/assets/images/projectiles/basic_projectile.atlas @@ -1,41 +1,55 @@ basic_projectile.png -size: 256, 32 +size: 260, 32 format: RGBA8888 filter: Nearest, Nearest repeat: none +projectile + rotate: false + xy: 78, 2 + size: 36, 19 + orig: 36, 19 + offset: 0, 0 + index: -1 projectileFinal rotate: false xy: 2, 2 size: 36, 19 orig: 36, 19 offset: 0, 0 - index: 2 + index: -1 projectile rotate: false - xy: 40, 2 + xy: 116, 2 size: 36, 19 orig: 36, 19 offset: 0, 0 - index: 4 + index: -1 projectile rotate: false - xy: 78, 2 + xy: 40, 2 size: 36, 19 orig: 36, 19 offset: 0, 0 - index: 1 -projectile + index: -1 +projectileCollide rotate: false - xy: 116, 2 + xy: 152, 2 size: 36, 19 orig: 36, 19 offset: 0, 0 - index: 3 -default + index: -1 +projectileCollide rotate: false - xy: 116, 2 + xy: 188, 2 + size: 36, 19 + orig: 36, 19 + offset: 0, 0 + index: -1 +projectileCollide + rotate: false + xy: 224, 2 size: 36, 19 orig: 36, 19 offset: 0, 0 - index: 3 + index: -1 diff --git a/source/core/assets/images/projectiles/basic_projectile.png b/source/core/assets/images/projectiles/basic_projectile.png index 5fa3bb42c..e551f311b 100644 Binary files a/source/core/assets/images/projectiles/basic_projectile.png and b/source/core/assets/images/projectiles/basic_projectile.png differ diff --git a/source/core/assets/images/projectiles/bossProjectile.atlas b/source/core/assets/images/projectiles/bossProjectile.atlas index 35cdc850e..06d22f3b7 100644 --- a/source/core/assets/images/projectiles/bossProjectile.atlas +++ b/source/core/assets/images/projectiles/bossProjectile.atlas @@ -1,103 +1,103 @@ -bossProjectile.png -size: 980, 186 -format: RGBA8888 -filter: Linear,Linear -repeat: none -rotate - rotate: false - xy: 0, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 140, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 280, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 420, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 560, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 700, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 840, 0 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 0, 93 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 140, 93 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 280, 93 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 420, 93 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 560, 93 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 700, 93 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 700, 93 - size: 140, 93 - orig: 140, 93 - offset: 0, 0 - index: -1 +bossProjectile.png +size: 980, 186 +format: RGBA8888 +filter: Linear,Linear +repeat: none +rotate + rotate: false + xy: 0, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 140, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 280, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 420, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 560, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 700, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 840, 0 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 0, 93 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 140, 93 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 280, 93 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 420, 93 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 560, 93 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 700, 93 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 700, 93 + size: 140, 93 + orig: 140, 93 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/projectiles/burn_effect.atlas b/source/core/assets/images/projectiles/burn_effect.atlas index 140875f0f..28e780b93 100644 --- a/source/core/assets/images/projectiles/burn_effect.atlas +++ b/source/core/assets/images/projectiles/burn_effect.atlas @@ -1,55 +1,55 @@ - -burn_effect.png -size: 256, 64 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -projectile - rotate: false - xy: 78, 2 - size: 36, 31 - orig: 36, 31 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 2, 2 - size: 36, 31 - orig: 36, 31 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 154, 2 - size: 35, 31 - orig: 35, 31 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 40, 2 - size: 36, 31 - orig: 36, 31 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 116, 2 - size: 36, 31 - orig: 36, 31 - offset: 0, 0 - index: -1 -projectileFinal - rotate: false - xy: 191, 2 - size: 31, 31 - orig: 31, 31 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 78, 2 - size: 36, 31 - orig: 36, 31 - offset: 0, 0 + +burn_effect.png +size: 256, 64 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +projectile + rotate: false + xy: 78, 2 + size: 36, 31 + orig: 36, 31 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 2, 2 + size: 36, 31 + orig: 36, 31 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 154, 2 + size: 35, 31 + orig: 35, 31 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 40, 2 + size: 36, 31 + orig: 36, 31 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 116, 2 + size: 36, 31 + orig: 36, 31 + offset: 0, 0 + index: -1 +projectileFinal + rotate: false + xy: 191, 2 + size: 31, 31 + orig: 31, 31 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 78, 2 + size: 36, 31 + orig: 36, 31 + offset: 0, 0 index: -1 \ No newline at end of file diff --git a/source/core/assets/images/projectiles/engineer_projectile.atlas b/source/core/assets/images/projectiles/engineer_projectile.atlas index 9790d718e..e1510d801 100644 --- a/source/core/assets/images/projectiles/engineer_projectile.atlas +++ b/source/core/assets/images/projectiles/engineer_projectile.atlas @@ -1,6 +1,6 @@ engineer_projectile.png -size: 128, 32 +size: 148, 32 format: RGBA8888 filter: Nearest, Nearest repeat: none @@ -32,4 +32,24 @@ bullet orig: 20, 19 offset: 0, 0 index: -1 - +bulletCollide + rotate: false + xy: 87, 2 + size: 20, 19 + orig: 20, 19 + offset: 0, 0 + index: -1 +bulletCollide + rotate: false + xy: 107, 2 + size: 20, 19 + orig: 20, 19 + offset: 0, 0 + index: -1 +bulletCollide + rotate: false + xy: 127, 2 + size: 20, 19 + orig: 20, 19 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/projectiles/engineer_projectile.png b/source/core/assets/images/projectiles/engineer_projectile.png index a98ae11e2..991bba172 100644 Binary files a/source/core/assets/images/projectiles/engineer_projectile.png and b/source/core/assets/images/projectiles/engineer_projectile.png differ diff --git a/source/core/assets/images/projectiles/firework_anim.atlas b/source/core/assets/images/projectiles/firework_anim.atlas index 45f2d54c9..912c8027a 100644 --- a/source/core/assets/images/projectiles/firework_anim.atlas +++ b/source/core/assets/images/projectiles/firework_anim.atlas @@ -1,41 +1,41 @@ - -firework_anim.png -size: 128, 32 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -projectile - rotate: false - xy: 23, 2 - size: 19, 16 - orig: 19, 16 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 65, 2 - size: 19, 16 - orig: 19, 16 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 44, 2 - size: 19, 16 - orig: 19, 16 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 2, 2 - size: 19, 16 - orig: 19, 16 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 23, 2 - size: 19, 16 - orig: 19, 16 - offset: 0, 0 - index: -1 + +firework_anim.png +size: 128, 32 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +projectile + rotate: false + xy: 23, 2 + size: 19, 16 + orig: 19, 16 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 65, 2 + size: 19, 16 + orig: 19, 16 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 44, 2 + size: 19, 16 + orig: 19, 16 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 2, 2 + size: 19, 16 + orig: 19, 16 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 23, 2 + size: 19, 16 + orig: 19, 16 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/projectiles/mobBoss_projectile.atlas b/source/core/assets/images/projectiles/mobBoss_projectile.atlas index e0ddcbdd0..94ebaf787 100644 --- a/source/core/assets/images/projectiles/mobBoss_projectile.atlas +++ b/source/core/assets/images/projectiles/mobBoss_projectile.atlas @@ -1,62 +1,62 @@ - -mobBoss_projectile.png -size: 256, 32 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -mob_boss - rotate: false - xy: 142, 2 - size: 26, 19 - orig: 26, 19 - offset: 0, 0 - index: -1 -mob_boss - rotate: false - xy: 198, 3 - size: 24, 18 - orig: 24, 18 - offset: 0, 0 - index: -1 -mob_boss - rotate: false - xy: 170, 2 - size: 26, 19 - orig: 26, 19 - offset: 0, 0 - index: -1 -mob_boss - rotate: false - xy: 37, 2 - size: 33, 19 - orig: 33, 19 - offset: 0, 0 - index: -1 -mob_boss - rotate: false - xy: 107, 2 - size: 33, 19 - orig: 33, 19 - offset: 0, 0 - index: -1 -mob_boss - rotate: false - xy: 72, 2 - size: 33, 19 - orig: 33, 19 - offset: 0, 0 - index: -1 -mob_bossFinal - rotate: false - xy: 2, 2 - size: 33, 19 - orig: 33, 19 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 142, 2 - size: 26, 19 - orig: 26, 19 - offset: 0, 0 - index: -1 + +mobBoss_projectile.png +size: 256, 32 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +mob_boss + rotate: false + xy: 142, 2 + size: 26, 19 + orig: 26, 19 + offset: 0, 0 + index: -1 +mob_boss + rotate: false + xy: 198, 3 + size: 24, 18 + orig: 24, 18 + offset: 0, 0 + index: -1 +mob_boss + rotate: false + xy: 170, 2 + size: 26, 19 + orig: 26, 19 + offset: 0, 0 + index: -1 +mob_boss + rotate: false + xy: 37, 2 + size: 33, 19 + orig: 33, 19 + offset: 0, 0 + index: -1 +mob_boss + rotate: false + xy: 107, 2 + size: 33, 19 + orig: 33, 19 + offset: 0, 0 + index: -1 +mob_boss + rotate: false + xy: 72, 2 + size: 33, 19 + orig: 33, 19 + offset: 0, 0 + index: -1 +mob_bossFinal + rotate: false + xy: 2, 2 + size: 33, 19 + orig: 33, 19 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 142, 2 + size: 26, 19 + orig: 26, 19 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/projectiles/mobProjectile.atlas b/source/core/assets/images/projectiles/mobProjectile.atlas index 5dabfa025..7975b1d41 100644 --- a/source/core/assets/images/projectiles/mobProjectile.atlas +++ b/source/core/assets/images/projectiles/mobProjectile.atlas @@ -1,41 +1,41 @@ - -mobProjectile.png -size: 128, 32 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -rotate - rotate: false - xy: 80, 2 - size: 24, 23 - orig: 24, 23 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 28, 2 - size: 24, 23 - orig: 24, 23 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 28, 2 - size: 24, 23 - orig: 24, 23 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 2, 2 - size: 24, 23 - orig: 24, 23 - offset: 0, 0 - index: -1 -rotate - rotate: false - xy: 54, 2 - size: 24, 23 - orig: 24, 23 - offset: 0, 0 - index: -1 + +mobProjectile.png +size: 128, 32 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +rotate + rotate: false + xy: 80, 2 + size: 24, 23 + orig: 24, 23 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 28, 2 + size: 24, 23 + orig: 24, 23 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 28, 2 + size: 24, 23 + orig: 24, 23 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 2, 2 + size: 24, 23 + orig: 24, 23 + offset: 0, 0 + index: -1 +rotate + rotate: false + xy: 54, 2 + size: 24, 23 + orig: 24, 23 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/projectiles/oldstun_effect.atlas b/source/core/assets/images/projectiles/oldstun_effect.atlas index a50132d0b..d14093ee3 100644 --- a/source/core/assets/images/projectiles/oldstun_effect.atlas +++ b/source/core/assets/images/projectiles/oldstun_effect.atlas @@ -1,41 +1,41 @@ - -stun_effect.png -size: 256, 32 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -projectile - rotate: false - xy: 86, 3 - size: 41, 27 - orig: 41, 27 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 2, 2 - size: 40, 28 - orig: 40, 28 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 129, 2 - size: 40, 28 - orig: 40, 28 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 44, 2 - size: 40, 28 - orig: 40, 28 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 86, 3 - size: 41, 27 - orig: 41, 27 - offset: 0, 0 + +stun_effect.png +size: 256, 32 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +projectile + rotate: false + xy: 86, 3 + size: 41, 27 + orig: 41, 27 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 2, 2 + size: 40, 28 + orig: 40, 28 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 129, 2 + size: 40, 28 + orig: 40, 28 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 44, 2 + size: 40, 28 + orig: 40, 28 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 86, 3 + size: 41, 27 + orig: 41, 27 + offset: 0, 0 index: -1 \ No newline at end of file diff --git a/source/core/assets/images/projectiles/pierce_anim.atlas b/source/core/assets/images/projectiles/pierce_anim.atlas index 0dea23b97..d6e37446a 100644 --- a/source/core/assets/images/projectiles/pierce_anim.atlas +++ b/source/core/assets/images/projectiles/pierce_anim.atlas @@ -1,42 +1,42 @@ - -pierce_anim.png -size: 256, 32 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -projectile - rotate: false - xy: 2, 2 - size: 35, 26 - orig: 35, 26 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 76, 2 - size: 35, 26 - orig: 35, 26 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 39, 2 - size: 35, 26 - orig: 35, 26 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 113, 2 - size: 35, 26 - orig: 35, 26 - offset: 0, 0 - index: -1 -default -projectile - rotate: false - xy: 2, 2 - size: 35, 26 - orig: 35, 26 - offset: 0, 0 + +pierce_anim.png +size: 256, 32 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +projectile + rotate: false + xy: 2, 2 + size: 35, 26 + orig: 35, 26 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 76, 2 + size: 35, 26 + orig: 35, 26 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 39, 2 + size: 35, 26 + orig: 35, 26 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 113, 2 + size: 35, 26 + orig: 35, 26 + offset: 0, 0 + index: -1 +default +projectile + rotate: false + xy: 2, 2 + size: 35, 26 + orig: 35, 26 + offset: 0, 0 index: -1 \ No newline at end of file diff --git a/source/core/assets/images/projectiles/projectile_explosion.atlas b/source/core/assets/images/projectiles/projectile_explosion.atlas index d285fa835..3b16a2fc6 100644 --- a/source/core/assets/images/projectiles/projectile_explosion.atlas +++ b/source/core/assets/images/projectiles/projectile_explosion.atlas @@ -1,97 +1,97 @@ - -projectile_explosion.png -size: 2048, 256 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -explosion - rotate: false - xy: 1042, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 782, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 262, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosionFinal - rotate: false - xy: 1302, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 392, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 1432, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 652, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 132, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 1172, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 522, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 2, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -explosion - rotate: false - xy: 912, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 1042, 2 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 + +projectile_explosion.png +size: 2048, 256 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +explosion + rotate: false + xy: 1042, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 782, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 262, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosionFinal + rotate: false + xy: 1302, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 392, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 1432, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 652, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 132, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 1172, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 522, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 2, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +explosion + rotate: false + xy: 912, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 1042, 2 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/projectiles/snow_ball.atlas b/source/core/assets/images/projectiles/snow_ball.atlas index 20e4eb554..21712ba2b 100644 --- a/source/core/assets/images/projectiles/snow_ball.atlas +++ b/source/core/assets/images/projectiles/snow_ball.atlas @@ -1,48 +1,48 @@ - -snow_ball.png -size: 128, 32 -format: RGBA8888 -filter: Nearest, Nearest -repeat: none -projectile - rotate: false - xy: 20, 2 - size: 16, 19 - orig: 16, 19 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 56, 2 - size: 16, 19 - orig: 16, 19 - offset: 0, 0 - index: -1 -projectile - rotate: false - xy: 38, 2 - size: 16, 19 - orig: 16, 19 - offset: 0, 0 - index: -1 -projectileFinal - rotate: false - xy: 2, 2 - size: 16, 19 - orig: 16, 19 - offset: 0, 0 - index: -1 -collision - rotate: false - xy: 92, 3 - size: 16, 18 - orig: 16, 18 - offset: 0, 0 - index: -1 -collision - rotate: false - xy: 74, 3 - size: 16, 18 - orig: 16, 18 - offset: 0, 0 - index: -1 + +snow_ball.png +size: 128, 32 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +projectile + rotate: false + xy: 20, 2 + size: 16, 19 + orig: 16, 19 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 56, 2 + size: 16, 19 + orig: 16, 19 + offset: 0, 0 + index: -1 +projectile + rotate: false + xy: 38, 2 + size: 16, 19 + orig: 16, 19 + offset: 0, 0 + index: -1 +projectileFinal + rotate: false + xy: 2, 2 + size: 16, 19 + orig: 16, 19 + offset: 0, 0 + index: -1 +collision + rotate: false + xy: 92, 3 + size: 16, 18 + orig: 16, 18 + offset: 0, 0 + index: -1 +collision + rotate: false + xy: 74, 3 + size: 16, 18 + orig: 16, 18 + offset: 0, 0 + index: -1 diff --git a/source/core/assets/images/projectiles/stun_effect.atlas b/source/core/assets/images/projectiles/stun_effect.atlas index 6aa98a315..8406d5748 100644 --- a/source/core/assets/images/projectiles/stun_effect.atlas +++ b/source/core/assets/images/projectiles/stun_effect.atlas @@ -1,6 +1,6 @@ stun_effect.png -size: 128, 32 +size: 152, 32 format: RGBA8888 filter: Nearest, Nearest repeat: none @@ -32,6 +32,27 @@ projectile orig: 17, 19 offset: 0, 0 index: -1 +stun + rotate: false + xy: 87, 2 + size: 21, 19 + orig: 21, 19 + offset: 0, 0 + index: -1 +stun + rotate: false + xy: 109, 2 + size: 21, 19 + orig: 21, 19 + offset: 0, 0 + index: -1 +stun + rotate: false + xy: 131, 2 + size: 21, 19 + orig: 21, 19 + offset: 0, 0 + index: -1 default rotate: false xy: 2, 2 diff --git a/source/core/assets/images/projectiles/stun_effect.png b/source/core/assets/images/projectiles/stun_effect.png index cd862a426..f2b3deddb 100644 Binary files a/source/core/assets/images/projectiles/stun_effect.png and b/source/core/assets/images/projectiles/stun_effect.png differ diff --git a/source/core/assets/images/ui/Screen/Losing.png b/source/core/assets/images/ui/Screen/Losing.png deleted file mode 100644 index 133a500f8..000000000 Binary files a/source/core/assets/images/ui/Screen/Losing.png and /dev/null differ diff --git a/source/core/assets/images/ui/Screen/Nextlevel.png b/source/core/assets/images/ui/Screen/Nextlevel.png deleted file mode 100644 index 424016fa4..000000000 Binary files a/source/core/assets/images/ui/Screen/Nextlevel.png and /dev/null differ diff --git a/source/core/assets/images/ui/Screen/WinningScreen.png b/source/core/assets/images/ui/Screen/WinningScreen.png deleted file mode 100644 index bd977c7a8..000000000 Binary files a/source/core/assets/images/ui/Screen/WinningScreen.png and /dev/null 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 deleted file mode 100644 index 6f8775172..000000000 Binary files a/source/core/assets/images/ui/Sprites/UI_Glass_Arrow_Large_01a - Copy.png and /dev/null differ diff --git a/source/core/assets/images/ui/buttons/glass.atlas b/source/core/assets/images/ui/buttons/glass.atlas index 3e095821f..4a7987fe5 100644 --- a/source/core/assets/images/ui/buttons/glass.atlas +++ b/source/core/assets/images/ui/buttons/glass.atlas @@ -6,714 +6,693 @@ filter: Linear, Linear repeat: none dot_gothic_16 rotate: false - xy: 1, 979 + xy: 1, 989 size: 505, 107 orig: 505, 107 offset: 0, 0 index: -1 dot_gothic_32 rotate: false - xy: 509, 1517 + xy: 509, 1527 size: 505, 240 orig: 505, 240 offset: 0, 0 index: -1 Emulogic-zrEw rotate: false - xy: 1, 753 + xy: 1, 763 size: 505, 224 orig: 505, 224 offset: 0, 0 index: -1 determination_mono_18 rotate: false - xy: 1525, 1964 + xy: 1525, 1974 size: 505, 64 orig: 505, 64 offset: 0, 0 index: -1 determination_mono_18_bold rotate: false - xy: 509, 1759 + xy: 509, 1769 size: 506, 106 orig: 506, 106 offset: 0, 0 index: -1 determination_mono_22 rotate: false - xy: 1017, 1939 + xy: 1017, 1949 size: 506, 89 orig: 506, 89 offset: 0, 0 index: -1 determination_mono_32 rotate: false - xy: 509, 1370 + xy: 509, 1380 size: 503, 145 orig: 503, 145 offset: 0, 0 index: -1 determination_mono_48_title rotate: false - xy: 1, 1632 + xy: 1, 1642 size: 506, 396 orig: 506, 396 offset: 0, 0 index: -1 emulogic_18 rotate: false - xy: 1017, 1840 + xy: 1017, 1850 size: 505, 97 orig: 505, 97 offset: 0, 0 index: -1 game_paused_24 rotate: false - xy: 1, 1577 + xy: 1, 1587 size: 506, 53 orig: 506, 53 offset: 0, 0 index: -1 game_paused_title rotate: false - xy: 1, 647 + xy: 1, 657 size: 502, 104 orig: 502, 104 offset: 0, 0 index: -1 glitch_24 rotate: false - xy: 509, 1867 + xy: 509, 1877 size: 506, 161 orig: 506, 161 offset: 0, 0 index: -1 glitch_title rotate: false - xy: 1, 1088 + xy: 1, 1098 size: 506, 487 orig: 506, 487 offset: 0, 0 index: -1 UI_Glass_Arrow_Large_01a rotate: false - xy: 965, 1336 + xy: 965, 1346 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Arrow_Medium_01a rotate: false - xy: 457, 613 + xy: 99, 167 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Arrow_Small_01a rotate: false - xy: 403, 461 + xy: 251, 319 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Banner_01a rotate: false - xy: 1017, 1806 + xy: 1017, 1816 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Banner_01b rotate: false - xy: 99, 5 + xy: 403, 589 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Textfield_01a rotate: false - xy: 99, 5 + xy: 403, 589 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a1 rotate: false - xy: 509, 1184 + xy: 509, 1194 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a3 rotate: false - xy: 509, 1184 + xy: 509, 1194 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a2 rotate: false - xy: 305, 461 + xy: 305, 623 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a2 rotate: false - xy: 305, 461 + xy: 305, 623 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a3 rotate: false - xy: 1, 5 + xy: 1, 167 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a1 rotate: false - xy: 1, 5 + xy: 1, 167 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a4 rotate: false - xy: 153, 157 + xy: 153, 319 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a1 rotate: false - xy: 1017, 1772 + xy: 1017, 1782 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a2 rotate: false - xy: 1115, 1806 + xy: 1115, 1816 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a3 rotate: false - xy: 509, 1150 + xy: 509, 1160 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a4 rotate: false - xy: 607, 1184 + xy: 607, 1194 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a4 rotate: false - xy: 607, 1184 + xy: 607, 1194 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a1 rotate: false - xy: 1115, 1772 + xy: 403, 623 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a3 rotate: false - xy: 1115, 1772 + xy: 403, 623 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a2 rotate: false - xy: 1213, 1806 + xy: 1115, 1782 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a2 rotate: false - xy: 1213, 1806 + xy: 1115, 1782 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a3 rotate: false - xy: 509, 1116 + xy: 1213, 1816 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a1 rotate: false - xy: 509, 1116 + xy: 1213, 1816 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a4 rotate: false - xy: 607, 1150 + xy: 509, 1126 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a1 rotate: false - xy: 705, 1184 + xy: 607, 1160 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a2 rotate: false - xy: 305, 295 + xy: 705, 1194 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a3 rotate: false - xy: 1181, 1772 + xy: 305, 555 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a4 rotate: false - xy: 1279, 1806 + xy: 1, 35 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a4 rotate: false - xy: 1279, 1806 + xy: 1, 35 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a1 _1 rotate: false - xy: 251, 157 + xy: 469, 623 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a3 rotate: false - xy: 251, 157 + xy: 469, 623 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a2_2 rotate: false - xy: 575, 1116 + xy: 1181, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a2 rotate: false - xy: 575, 1116 + xy: 1181, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a3_3 rotate: false - xy: 673, 1150 + xy: 1279, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a1 rotate: false - xy: 673, 1150 + xy: 1279, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a4_4 rotate: false - xy: 771, 1184 + xy: 575, 1126 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a1_ rotate: false - xy: 305, 261 + xy: 673, 1160 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a2 rotate: false - xy: 1247, 1772 + xy: 771, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a3 rotate: false - xy: 1345, 1806 + xy: 305, 521 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a4 rotate: false - xy: 965, 1302 + xy: 371, 555 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a4 rotate: false - xy: 965, 1302 + xy: 371, 555 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Large_01a rotate: false - xy: 457, 579 + xy: 1, 1 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Medium_01a rotate: false - xy: 403, 427 + xy: 965, 1312 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Small_01a rotate: false - xy: 251, 123 + xy: 99, 133 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Large_01a rotate: false - xy: 609, 1116 + xy: 251, 285 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Medium_01a rotate: false - xy: 707, 1150 + xy: 437, 589 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Small_01a rotate: false - xy: 805, 1184 + xy: 1215, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Dropdown_01a rotate: false - xy: 305, 227 + xy: 1313, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Dropdown_Handle_01a rotate: false - xy: 1281, 1772 + xy: 609, 1126 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Fillbar_01a rotate: false - xy: 1379, 1806 + xy: 707, 1160 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Fillbar_Filler_01a rotate: false - xy: 965, 1268 + xy: 805, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Horizontal_01a rotate: false - xy: 305, 427 + xy: 305, 589 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Inward_01a rotate: false - xy: 153, 59 + xy: 1, 69 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 UI_Glass_Frame_Lite_01a rotate: false - xy: 457, 545 + xy: 305, 487 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Standard_01a rotate: false - xy: 305, 329 + xy: 153, 221 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 UI_Glass_Frame_Vertical_01a rotate: false - xy: 403, 329 + xy: 305, 389 size: 32, 96 orig: 32, 96 offset: 0, 0 index: -1 UI_Glass_Minus_Large_01a rotate: false - xy: 371, 295 + xy: 339, 521 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Minus_Medium_01a rotate: false - xy: 339, 261 + xy: 405, 555 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Minus_Small_01a rotate: false - xy: 251, 89 + xy: 965, 1278 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Large_01a rotate: false - xy: 643, 1116 + xy: 99, 99 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Medium_01a rotate: false - xy: 741, 1150 + xy: 251, 251 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Small_01a rotate: false - xy: 839, 1184 + xy: 1249, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Scrollbar_01a rotate: false - xy: 305, 193 + xy: 1347, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Scrollbar_Handle_01a rotate: false - xy: 1315, 1772 + xy: 643, 1126 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a1 rotate: false - xy: 1413, 1806 + xy: 741, 1160 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a2 rotate: false - xy: 965, 1234 + xy: 839, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a4 rotate: false - xy: 965, 1234 + xy: 839, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a3 rotate: false - xy: 457, 511 + xy: 305, 355 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_01a rotate: false - xy: 339, 227 + xy: 339, 487 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_Filler_01a rotate: false - xy: 677, 1116 + xy: 373, 521 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_Handle_01a rotate: false - xy: 775, 1150 + xy: 965, 1244 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Available_01a rotate: false - xy: 873, 1184 + xy: 1283, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Selected_01a rotate: false - xy: 1349, 1772 + xy: 1381, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Unavailable_01a rotate: false - xy: 1447, 1806 + xy: 677, 1126 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Bar_01a rotate: false - xy: 339, 193 + xy: 775, 1160 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Cover_01a rotate: false - xy: 711, 1116 + xy: 873, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Handle_01a rotate: false - xy: 809, 1150 + xy: 339, 453 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 Weapon-Tower-Default rotate: false - xy: 153, 343 + xy: 153, 353 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 droid-tower-default rotate: false - xy: 509, 1218 + xy: 509, 1228 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 fire-tower-default rotate: false - xy: 1, 495 - size: 150, 150 - orig: 150, 150 - offset: 0, 0 - index: -1 -firework-tower-default - rotate: false - xy: 153, 191 + xy: 1, 505 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 imageedit_2_8132799771 rotate: false - xy: 661, 1218 + xy: 661, 1228 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 mine-tower-default rotate: false - 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 + xy: 1, 353 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 stun-tower-default rotate: false - xy: 153, 495 + xy: 153, 505 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 tnt-tower-default rotate: false - xy: 813, 1218 + xy: 813, 1228 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 wall-tower-default rotate: false - xy: 1, 191 + xy: 1, 201 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 7e4dc5eb1..8637af19f 100644 --- a/source/core/assets/images/ui/buttons/glass.json +++ b/source/core/assets/images/ui/buttons/glass.json @@ -301,87 +301,6 @@ 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: { @@ -477,33 +396,6 @@ 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 d0a06883c..57c85ace2 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 1312aeb97..c4233d125 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 0e58a9b27..5bed55ad9 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 86127efd1..162af4008 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 e6f0f8328..c2e54ef5c 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 a7b89cdbc..e91965704 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 94793be5d..6669cedb4 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 ec496ffdb..0baad28ac 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 190ad6288..10761bfb8 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 15cd7697c..31369d500 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 ec393bc53..f718a06f8 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 bf328c7f6..ecce5abc5 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 56924bc69..22606d09e 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 deleted file mode 100644 index 83b146773..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/1.png and /dev/null 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 deleted file mode 100644 index 38c48d3f9..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/10.png and /dev/null 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 deleted file mode 100644 index 95cf8ab42..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/11.png and /dev/null 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 deleted file mode 100644 index af7abbc1c..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/12.png and /dev/null 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 deleted file mode 100644 index 69d8b3c97..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/13.png and /dev/null 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 deleted file mode 100644 index cde8aac41..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/14.png and /dev/null 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 deleted file mode 100644 index 72688aec7..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/15.png and /dev/null 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 deleted file mode 100644 index 8d2c0c3f8..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/16.png and /dev/null 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 deleted file mode 100644 index 103f9db5d..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/17.png and /dev/null 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 deleted file mode 100644 index 8042f62d4..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/18.png and /dev/null 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 deleted file mode 100644 index e1f79e56d..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/19.png and /dev/null 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 deleted file mode 100644 index dfe9ffa08..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/2.png and /dev/null 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 deleted file mode 100644 index ea08f6dbd..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/20.png and /dev/null 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 deleted file mode 100644 index 6c0e49f7e..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/21.png and /dev/null 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 deleted file mode 100644 index 8f46a8754..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/22.png and /dev/null 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 deleted file mode 100644 index d26c3f2cb..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/23.png and /dev/null 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 deleted file mode 100644 index 31a0089cf..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/24.png and /dev/null 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 deleted file mode 100644 index 0f6b42833..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/25.png and /dev/null 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 deleted file mode 100644 index ceea305fb..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/26.png and /dev/null 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 deleted file mode 100644 index 409574f4b..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/27.png and /dev/null 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 deleted file mode 100644 index da0ea0619..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/28.png and /dev/null 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 deleted file mode 100644 index 5883a9c6a..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/29.png and /dev/null 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 deleted file mode 100644 index 3eb5240ad..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/3.png and /dev/null 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 deleted file mode 100644 index 6b9a39fda..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/30.png and /dev/null 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 deleted file mode 100644 index 0ab825429..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/31.png and /dev/null 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 deleted file mode 100644 index 3f819e061..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/32.png and /dev/null 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 deleted file mode 100644 index 3b342a7ed..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/33.png and /dev/null 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 deleted file mode 100644 index 7e72e313b..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/34.png and /dev/null 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 deleted file mode 100644 index 8f7a6ac98..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/35.png and /dev/null 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 deleted file mode 100644 index c97607f9d..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/36.png and /dev/null 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 deleted file mode 100644 index 111369017..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/37.png and /dev/null 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 deleted file mode 100644 index d1bcb6c63..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/38.png and /dev/null 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 deleted file mode 100644 index a95c42274..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/39.png and /dev/null 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 deleted file mode 100644 index 99c9a00e7..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/4.png and /dev/null 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 deleted file mode 100644 index a2d84a577..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/40.png and /dev/null 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 deleted file mode 100644 index 5a5e72514..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/41.png and /dev/null 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 deleted file mode 100644 index 184df838b..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/42.png and /dev/null 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 deleted file mode 100644 index 28e4bd7b2..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/43.png and /dev/null 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 deleted file mode 100644 index 08e086483..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/44.png and /dev/null 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 deleted file mode 100644 index 8f0966920..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/45.png and /dev/null 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 deleted file mode 100644 index 2746951f5..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/46.png and /dev/null 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 deleted file mode 100644 index f4c6864b6..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/47.png and /dev/null 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 deleted file mode 100644 index 9cc5ffc9a..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/48.png and /dev/null 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 deleted file mode 100644 index 5d6713c95..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/49.png and /dev/null 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 deleted file mode 100644 index 89bc4b608..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/5.png and /dev/null 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 deleted file mode 100644 index 6f917443d..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/50.png and /dev/null 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 deleted file mode 100644 index d4dbdbec9..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/51.png and /dev/null 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 deleted file mode 100644 index 98e7cc3dc..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/52.png and /dev/null 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 deleted file mode 100644 index e63b80a40..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/53.png and /dev/null 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 deleted file mode 100644 index 440ab7aca..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/54.png and /dev/null 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 deleted file mode 100644 index fee03428e..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/55.png and /dev/null 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 deleted file mode 100644 index d7efc51e5..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/56.png and /dev/null 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 deleted file mode 100644 index 4636aa76b..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/57.png and /dev/null 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 deleted file mode 100644 index f0d2ce55b..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/58.png and /dev/null 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 deleted file mode 100644 index 1dcca3581..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/59.png and /dev/null 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 deleted file mode 100644 index 2b2446eec..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/6.png and /dev/null 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 deleted file mode 100644 index ee5a8d3d6..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/60.png and /dev/null 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 deleted file mode 100644 index aa572f74c..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/7.png and /dev/null 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 deleted file mode 100644 index cc337325f..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/8.png and /dev/null 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 deleted file mode 100644 index 343949c3e..000000000 Binary files a/source/core/assets/planets/Barren_or_Moon_bw/2/9.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/1.png b/source/core/assets/planets/Desert_bw/1/1.png deleted file mode 100644 index f46cb689c..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/1.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/10.png b/source/core/assets/planets/Desert_bw/1/10.png deleted file mode 100644 index c58ab448a..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/10.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/11.png b/source/core/assets/planets/Desert_bw/1/11.png deleted file mode 100644 index 9bbd5b15e..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/11.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/12.png b/source/core/assets/planets/Desert_bw/1/12.png deleted file mode 100644 index 10ab860ba..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/12.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/13.png b/source/core/assets/planets/Desert_bw/1/13.png deleted file mode 100644 index 06bef9c92..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/13.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/14.png b/source/core/assets/planets/Desert_bw/1/14.png deleted file mode 100644 index 8190ee841..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/14.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/15.png b/source/core/assets/planets/Desert_bw/1/15.png deleted file mode 100644 index 4e8d7bc08..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/15.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/16.png b/source/core/assets/planets/Desert_bw/1/16.png deleted file mode 100644 index 698ee30e1..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/16.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/17.png b/source/core/assets/planets/Desert_bw/1/17.png deleted file mode 100644 index 58a1598b7..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/17.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/18.png b/source/core/assets/planets/Desert_bw/1/18.png deleted file mode 100644 index 986726910..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/18.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/19.png b/source/core/assets/planets/Desert_bw/1/19.png deleted file mode 100644 index b8eaff229..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/19.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/2.png b/source/core/assets/planets/Desert_bw/1/2.png deleted file mode 100644 index 2781b82e5..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/2.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/20.png b/source/core/assets/planets/Desert_bw/1/20.png deleted file mode 100644 index b3958de59..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/20.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/21.png b/source/core/assets/planets/Desert_bw/1/21.png deleted file mode 100644 index a60474811..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/21.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/22.png b/source/core/assets/planets/Desert_bw/1/22.png deleted file mode 100644 index c601e384f..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/22.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/23.png b/source/core/assets/planets/Desert_bw/1/23.png deleted file mode 100644 index 6d85bd568..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/23.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/24.png b/source/core/assets/planets/Desert_bw/1/24.png deleted file mode 100644 index 9a87cb24a..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/24.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/25.png b/source/core/assets/planets/Desert_bw/1/25.png deleted file mode 100644 index ba3244ab0..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/25.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/26.png b/source/core/assets/planets/Desert_bw/1/26.png deleted file mode 100644 index bbf9658cd..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/26.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/27.png b/source/core/assets/planets/Desert_bw/1/27.png deleted file mode 100644 index 085b26c0c..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/27.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/28.png b/source/core/assets/planets/Desert_bw/1/28.png deleted file mode 100644 index 90e2e3973..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/28.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/29.png b/source/core/assets/planets/Desert_bw/1/29.png deleted file mode 100644 index 0b45d77e2..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/29.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/3.png b/source/core/assets/planets/Desert_bw/1/3.png deleted file mode 100644 index 7e4940092..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/3.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/30.png b/source/core/assets/planets/Desert_bw/1/30.png deleted file mode 100644 index 699ef070a..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/30.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/31.png b/source/core/assets/planets/Desert_bw/1/31.png deleted file mode 100644 index a9ae13fe9..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/31.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/32.png b/source/core/assets/planets/Desert_bw/1/32.png deleted file mode 100644 index 8f67ae032..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/32.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/33.png b/source/core/assets/planets/Desert_bw/1/33.png deleted file mode 100644 index 18a14ff2d..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/33.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/34.png b/source/core/assets/planets/Desert_bw/1/34.png deleted file mode 100644 index 79f2d7d4a..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/34.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/35.png b/source/core/assets/planets/Desert_bw/1/35.png deleted file mode 100644 index e6b295841..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/35.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/36.png b/source/core/assets/planets/Desert_bw/1/36.png deleted file mode 100644 index a93e0e1b2..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/36.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/37.png b/source/core/assets/planets/Desert_bw/1/37.png deleted file mode 100644 index 8fce78ac2..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/37.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/38.png b/source/core/assets/planets/Desert_bw/1/38.png deleted file mode 100644 index 48421334b..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/38.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/39.png b/source/core/assets/planets/Desert_bw/1/39.png deleted file mode 100644 index deb2f6036..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/39.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/4.png b/source/core/assets/planets/Desert_bw/1/4.png deleted file mode 100644 index ba06391a6..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/4.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/40.png b/source/core/assets/planets/Desert_bw/1/40.png deleted file mode 100644 index 369e0c071..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/40.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/41.png b/source/core/assets/planets/Desert_bw/1/41.png deleted file mode 100644 index fb5c606ac..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/41.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/42.png b/source/core/assets/planets/Desert_bw/1/42.png deleted file mode 100644 index 8f19f22af..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/42.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/43.png b/source/core/assets/planets/Desert_bw/1/43.png deleted file mode 100644 index 7733662a7..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/43.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/44.png b/source/core/assets/planets/Desert_bw/1/44.png deleted file mode 100644 index b838b2be2..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/44.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/45.png b/source/core/assets/planets/Desert_bw/1/45.png deleted file mode 100644 index 292b15023..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/45.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/46.png b/source/core/assets/planets/Desert_bw/1/46.png deleted file mode 100644 index 794767e0b..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/46.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/47.png b/source/core/assets/planets/Desert_bw/1/47.png deleted file mode 100644 index 09fb1ba56..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/47.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/48.png b/source/core/assets/planets/Desert_bw/1/48.png deleted file mode 100644 index 0841b4217..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/48.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/49.png b/source/core/assets/planets/Desert_bw/1/49.png deleted file mode 100644 index 456f88164..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/49.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/5.png b/source/core/assets/planets/Desert_bw/1/5.png deleted file mode 100644 index f1f657c6b..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/5.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/50.png b/source/core/assets/planets/Desert_bw/1/50.png deleted file mode 100644 index 2dbba0084..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/50.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/51.png b/source/core/assets/planets/Desert_bw/1/51.png deleted file mode 100644 index 525975029..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/51.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/52.png b/source/core/assets/planets/Desert_bw/1/52.png deleted file mode 100644 index 53636a69d..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/52.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/53.png b/source/core/assets/planets/Desert_bw/1/53.png deleted file mode 100644 index d33b7b261..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/53.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/54.png b/source/core/assets/planets/Desert_bw/1/54.png deleted file mode 100644 index 69b2e663a..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/54.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/55.png b/source/core/assets/planets/Desert_bw/1/55.png deleted file mode 100644 index 0361ed344..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/55.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/56.png b/source/core/assets/planets/Desert_bw/1/56.png deleted file mode 100644 index 8fa954a7c..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/56.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/57.png b/source/core/assets/planets/Desert_bw/1/57.png deleted file mode 100644 index 0046fa102..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/57.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/58.png b/source/core/assets/planets/Desert_bw/1/58.png deleted file mode 100644 index c5d0730ce..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/58.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/59.png b/source/core/assets/planets/Desert_bw/1/59.png deleted file mode 100644 index d439755c9..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/59.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/6.png b/source/core/assets/planets/Desert_bw/1/6.png deleted file mode 100644 index 4f47a7d3a..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/6.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/60.png b/source/core/assets/planets/Desert_bw/1/60.png deleted file mode 100644 index 901ec426c..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/60.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/7.png b/source/core/assets/planets/Desert_bw/1/7.png deleted file mode 100644 index 4afcc2b93..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/7.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/8.png b/source/core/assets/planets/Desert_bw/1/8.png deleted file mode 100644 index 2467b0973..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/8.png and /dev/null differ diff --git a/source/core/assets/planets/Desert_bw/1/9.png b/source/core/assets/planets/Desert_bw/1/9.png deleted file mode 100644 index 64c1407ae..000000000 Binary files a/source/core/assets/planets/Desert_bw/1/9.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/1.png b/source/core/assets/planets/Lava_bw/1/1.png deleted file mode 100644 index 4870542ee..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/1.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/10.png b/source/core/assets/planets/Lava_bw/1/10.png deleted file mode 100644 index 27892603b..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/10.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/11.png b/source/core/assets/planets/Lava_bw/1/11.png deleted file mode 100644 index 8fac24b5e..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/11.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/12.png b/source/core/assets/planets/Lava_bw/1/12.png deleted file mode 100644 index 9d1506a86..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/12.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/13.png b/source/core/assets/planets/Lava_bw/1/13.png deleted file mode 100644 index 6772fcc59..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/13.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/14.png b/source/core/assets/planets/Lava_bw/1/14.png deleted file mode 100644 index a840e1709..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/14.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/15.png b/source/core/assets/planets/Lava_bw/1/15.png deleted file mode 100644 index 1ecb607ba..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/15.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/16.png b/source/core/assets/planets/Lava_bw/1/16.png deleted file mode 100644 index cea173d97..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/16.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/17.png b/source/core/assets/planets/Lava_bw/1/17.png deleted file mode 100644 index 96aa223a8..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/17.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/18.png b/source/core/assets/planets/Lava_bw/1/18.png deleted file mode 100644 index 9f747091a..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/18.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/19.png b/source/core/assets/planets/Lava_bw/1/19.png deleted file mode 100644 index 26f7dd583..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/19.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/2.png b/source/core/assets/planets/Lava_bw/1/2.png deleted file mode 100644 index 2f3256c15..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/2.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/20.png b/source/core/assets/planets/Lava_bw/1/20.png deleted file mode 100644 index 6635e686b..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/20.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/21.png b/source/core/assets/planets/Lava_bw/1/21.png deleted file mode 100644 index 4a652d49d..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/21.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/22.png b/source/core/assets/planets/Lava_bw/1/22.png deleted file mode 100644 index 7d2e6a780..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/22.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/23.png b/source/core/assets/planets/Lava_bw/1/23.png deleted file mode 100644 index 87d84cae8..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/23.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/24.png b/source/core/assets/planets/Lava_bw/1/24.png deleted file mode 100644 index 0afc0c14f..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/24.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/25.png b/source/core/assets/planets/Lava_bw/1/25.png deleted file mode 100644 index 8c1f67ad8..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/25.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/26.png b/source/core/assets/planets/Lava_bw/1/26.png deleted file mode 100644 index 3821d8c8f..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/26.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/27.png b/source/core/assets/planets/Lava_bw/1/27.png deleted file mode 100644 index 4f1278653..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/27.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/28.png b/source/core/assets/planets/Lava_bw/1/28.png deleted file mode 100644 index e63366a61..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/28.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/29.png b/source/core/assets/planets/Lava_bw/1/29.png deleted file mode 100644 index 9d2f957c6..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/29.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/3.png b/source/core/assets/planets/Lava_bw/1/3.png deleted file mode 100644 index c1832e3f8..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/3.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/30.png b/source/core/assets/planets/Lava_bw/1/30.png deleted file mode 100644 index a829dcafa..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/30.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/31.png b/source/core/assets/planets/Lava_bw/1/31.png deleted file mode 100644 index bca15d38a..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/31.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/32.png b/source/core/assets/planets/Lava_bw/1/32.png deleted file mode 100644 index f518b17ea..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/32.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/33.png b/source/core/assets/planets/Lava_bw/1/33.png deleted file mode 100644 index c198e15dc..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/33.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/34.png b/source/core/assets/planets/Lava_bw/1/34.png deleted file mode 100644 index 5858eed2b..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/34.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/35.png b/source/core/assets/planets/Lava_bw/1/35.png deleted file mode 100644 index 4ff7388ba..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/35.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/36.png b/source/core/assets/planets/Lava_bw/1/36.png deleted file mode 100644 index bdbe0cbbc..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/36.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/37.png b/source/core/assets/planets/Lava_bw/1/37.png deleted file mode 100644 index 124696f87..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/37.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/38.png b/source/core/assets/planets/Lava_bw/1/38.png deleted file mode 100644 index b63846619..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/38.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/39.png b/source/core/assets/planets/Lava_bw/1/39.png deleted file mode 100644 index 69067340a..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/39.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/4.png b/source/core/assets/planets/Lava_bw/1/4.png deleted file mode 100644 index 1bba4861a..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/4.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/40.png b/source/core/assets/planets/Lava_bw/1/40.png deleted file mode 100644 index b73701d1c..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/40.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/41.png b/source/core/assets/planets/Lava_bw/1/41.png deleted file mode 100644 index be99af527..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/41.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/42.png b/source/core/assets/planets/Lava_bw/1/42.png deleted file mode 100644 index 0f33b33ef..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/42.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/43.png b/source/core/assets/planets/Lava_bw/1/43.png deleted file mode 100644 index 12da1adfd..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/43.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/44.png b/source/core/assets/planets/Lava_bw/1/44.png deleted file mode 100644 index bb3861f75..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/44.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/45.png b/source/core/assets/planets/Lava_bw/1/45.png deleted file mode 100644 index 4889df522..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/45.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/46.png b/source/core/assets/planets/Lava_bw/1/46.png deleted file mode 100644 index f42703873..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/46.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/47.png b/source/core/assets/planets/Lava_bw/1/47.png deleted file mode 100644 index fd942d677..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/47.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/48.png b/source/core/assets/planets/Lava_bw/1/48.png deleted file mode 100644 index a52660c5f..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/48.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/49.png b/source/core/assets/planets/Lava_bw/1/49.png deleted file mode 100644 index 66f7a08b1..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/49.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/5.png b/source/core/assets/planets/Lava_bw/1/5.png deleted file mode 100644 index dcab56667..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/5.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/50.png b/source/core/assets/planets/Lava_bw/1/50.png deleted file mode 100644 index f93a71b11..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/50.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/51.png b/source/core/assets/planets/Lava_bw/1/51.png deleted file mode 100644 index 34c30435c..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/51.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/52.png b/source/core/assets/planets/Lava_bw/1/52.png deleted file mode 100644 index a9d61627e..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/52.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/53.png b/source/core/assets/planets/Lava_bw/1/53.png deleted file mode 100644 index d8f6e7acc..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/53.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/54.png b/source/core/assets/planets/Lava_bw/1/54.png deleted file mode 100644 index 1977fe824..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/54.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/55.png b/source/core/assets/planets/Lava_bw/1/55.png deleted file mode 100644 index 41d663d35..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/55.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/56.png b/source/core/assets/planets/Lava_bw/1/56.png deleted file mode 100644 index 58e5ce938..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/56.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/57.png b/source/core/assets/planets/Lava_bw/1/57.png deleted file mode 100644 index 92f979cb6..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/57.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/58.png b/source/core/assets/planets/Lava_bw/1/58.png deleted file mode 100644 index 2453d425a..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/58.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/59.png b/source/core/assets/planets/Lava_bw/1/59.png deleted file mode 100644 index 34b374eb6..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/59.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/6.png b/source/core/assets/planets/Lava_bw/1/6.png deleted file mode 100644 index b0ede3cc5..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/6.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/60.png b/source/core/assets/planets/Lava_bw/1/60.png deleted file mode 100644 index 27c94b8f7..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/60.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/7.png b/source/core/assets/planets/Lava_bw/1/7.png deleted file mode 100644 index 2d651f42c..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/7.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/8.png b/source/core/assets/planets/Lava_bw/1/8.png deleted file mode 100644 index 1d823981d..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/8.png and /dev/null differ diff --git a/source/core/assets/planets/Lava_bw/1/9.png b/source/core/assets/planets/Lava_bw/1/9.png deleted file mode 100644 index db5fca99d..000000000 Binary files a/source/core/assets/planets/Lava_bw/1/9.png and /dev/null 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 deleted file mode 100644 index 61bc03e66..000000000 Binary files a/source/core/assets/sounds/towers/12-Gauge-Pump-Action-Shotgun-Close-Gunshot.mp3 and /dev/null 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 deleted file mode 100644 index 0611f722a..000000000 Binary files a/source/core/assets/sounds/towers/5.56_single_shot.mp3 and /dev/null 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 deleted file mode 100644 index 5e39881ce..000000000 Binary files a/source/core/assets/sounds/towers/Desert-Eagle-Far-Single-Gunshot.mp3 and /dev/null 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 deleted file mode 100644 index 34ef353ee..000000000 Binary files a/source/core/assets/sounds/towers/ar15_single_shot_far.mp3 and /dev/null differ diff --git a/source/core/assets/sounds/towers/eco_tower_ping.mp3 b/source/core/assets/sounds/towers/eco_tower_ping.mp3 deleted file mode 100644 index 1553f6001..000000000 Binary files a/source/core/assets/sounds/towers/eco_tower_ping.mp3 and /dev/null differ diff --git a/source/core/assets/sounds/towers/explosion.mp3 b/source/core/assets/sounds/towers/explosion.mp3 deleted file mode 100644 index ab19a2947..000000000 Binary files a/source/core/assets/sounds/towers/explosion.mp3 and /dev/null differ diff --git a/source/core/src.zip b/source/core/src.zip new file mode 100644 index 000000000..a2f8a6ce3 Binary files /dev/null and b/source/core/src.zip differ diff --git a/source/core/src/main.zip b/source/core/src/main.zip new file mode 100644 index 000000000..94a6266e3 Binary files /dev/null and b/source/core/src/main.zip differ diff --git a/source/core/src/main/com/csse3200/game/GdxGame.java b/source/core/src/main/com/csse3200/game/GdxGame.java index 5e3581d2a..903f443d3 100644 --- a/source/core/src/main/com/csse3200/game/GdxGame.java +++ b/source/core/src/main/com/csse3200/game/GdxGame.java @@ -5,7 +5,6 @@ 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; @@ -18,7 +17,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"); @@ -64,31 +63,30 @@ public void dispose() { * @return new screen */ private Screen newScreen(ScreenType screenType) { - 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; - }; + 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; + } } public enum ScreenType { - 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 + MAIN_MENU, MAIN_GAME, SETTINGS, STORY_SCREEN, LEVEL_SELECT, TURRET_SELECTION, LOSING_SCREEN, HELP_SCREEN } /** @@ -97,4 +95,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 b54745014..175345a38 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 @@ -21,6 +21,8 @@ public class AITaskComponent extends Component implements TaskRunner { private final List priorityTasks = new ArrayList<>(2); private final List priorityTasksToBeRestored = new ArrayList<>(2); private PriorityTask currentTask; + + public boolean freezed = false; /** * Add a priority task to the list of tasks. This task will be run only when it has the highest * priority, and can be stopped to run a higher priority task. @@ -46,8 +48,8 @@ public AITaskComponent addTask(PriorityTask task) { */ public T getTask(Class task) { for (PriorityTask priorityTask : priorityTasks) { - if (task.isInstance(priorityTask)) { - return task.cast(priorityTask); + if (priorityTask.getClass() == task) { + return (T) priorityTask; } } logger.info("Task {} not found", task); @@ -65,10 +67,11 @@ public void update() { return; } - if (desiredtask != currentTask) { + if (desiredtask != currentTask && !freezed) { changeTask(desiredtask); } - currentTask.update(); + if(currentTask!=null) + currentTask.update(); } @Override @@ -83,8 +86,12 @@ public void dispose() { */ public void disposeAll() { currentTask = null; - priorityTasksToBeRestored.addAll(priorityTasks); - priorityTasks.clear(); + for (int i = 0; i < priorityTasks.size(); i++) { + priorityTasksToBeRestored.add(priorityTasks.get(i)); + } + for (int i = 0; i < priorityTasks.size(); i++) { + priorityTasks.remove(i); + } } /** @@ -92,8 +99,12 @@ public void disposeAll() { * back into priorityTasks. */ public void restore() { - priorityTasks.addAll(priorityTasksToBeRestored); - priorityTasksToBeRestored.clear(); + for (int i = 0; i < priorityTasksToBeRestored.size(); i++) { + priorityTasks.add(priorityTasksToBeRestored.get(i)); + } + for (int i = 0; i < priorityTasksToBeRestored.size(); i++) { + priorityTasksToBeRestored.remove(i); + } 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 30ada73cc..8fccaf74b 100644 --- a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java +++ b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java @@ -22,6 +22,8 @@ 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; @@ -159,7 +161,6 @@ 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", @@ -200,14 +201,10 @@ 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"; @@ -246,37 +243,6 @@ 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) */ @@ -291,20 +257,40 @@ 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); @@ -345,18 +331,102 @@ 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; - // } + 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); + } /** * Spawn an entity on the map. Is called during a wave. Add cases here for each mob type @@ -367,9 +437,6 @@ private void spawnTerrain() { 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; @@ -382,7 +449,7 @@ public void spawnMob(String entity, GridPoint2 randomPos, int health) { case "Skeleton": mob = NPCFactory.createSkeleton(health); break; - case "Wizard": + case "DeflectWizard": mob = NPCFactory.createWizard(health); break; case "WaterQueen": @@ -394,7 +461,6 @@ public void spawnMob(String entity, GridPoint2 randomPos, int health) { case "IceBoss": mob = MobBossFactory.createIceBoss(health); break; - case "Coat": mob = NPCFactory.createCoat(health); break; @@ -407,7 +473,15 @@ 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; @@ -425,6 +499,400 @@ 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"); @@ -473,6 +941,17 @@ 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/Component.java b/source/core/src/main/com/csse3200/game/components/Component.java index babc6f291..e589d2ece 100644 --- a/source/core/src/main/com/csse3200/game/components/Component.java +++ b/source/core/src/main/com/csse3200/game/components/Component.java @@ -1,102 +1,102 @@ -package com.csse3200.game.components; - -import com.csse3200.game.entities.Entity; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Core component class from which all components inherit. Contains logic for creating, updating, - * and disposing. Components can be attached to an entity to give it specific behaviour. It is - * unlikely that changes will need to be made here. - */ -public class Component { - private static final Logger logger = LoggerFactory.getLogger(Component.class); - protected Entity entity; - protected boolean enabled = true; - - /** - * Called when the entity is created and registered. Initial logic such as calls to GetComponent - * should be made here, not in the constructor which is called before an entity is finished. - */ - public void create() { - // No action by default. - } - - /** - * Early update called once per frame of the game, before update(). Use this only for logic that - * must run before other updates, such as physics. Not called if component is disabled. - */ - public void earlyUpdate() { - // No action by default. - } - - /** - * Called once per frame of the game, and should be used for most component logic. Not called if - * component is disabled. - */ - public void update() { - // No action by default. - } - - /** Called when the component is disposed. Dispose of any internal resources here. */ - public void dispose() { - // No action by default. - } - - /** - * Set the entity to which this component belongs. This is called by the Entity, and should not be - * set manually. - * - * @param entity The entity to which the component is attached. - */ - public void setEntity(Entity entity) { - logger.debug("Attaching {} to {}", this, entity); - this.entity = entity; - } - - /** - * Get the entity to which this component belongs. - * @return entity - */ - public Entity getEntity() { - return entity; - } - - /** - * Enable or disable the component. While disabled, a component does not run update() or - * earlyUpdate(). Other events inside the component may still fire. The component can still be - * disposed while disabled. - * - * @param enabled Should component be enabled - */ - public void setEnabled(boolean enabled) { - logger.debug("Setting enabled={} on {}", enabled, this); - this.enabled = enabled; - } - - /** Used to trigger the component to update itself. This should not need to be called manually. */ - public final void triggerUpdate() { - if (enabled) { - update(); - } - } - - /** - * Used to trigger the component to early-update itself. This should not need to be called - * manually. - */ - public final void triggerEarlyUpdate() { - if (enabled) { - earlyUpdate(); - } - } - - @Override - public String toString() { - String className = this.getClass().getSimpleName(); - if (entity == null) { - return className; - } - return entity + "." + className; - } -} +package com.csse3200.game.components; + +import com.csse3200.game.entities.Entity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Core component class from which all components inherit. Contains logic for creating, updating, + * and disposing. Components can be attached to an entity to give it specific behaviour. It is + * unlikely that changes will need to be made here. + */ +public class Component { + private static final Logger logger = LoggerFactory.getLogger(Component.class); + protected Entity entity; + public boolean enabled = true; + + /** + * Called when the entity is created and registered. Initial logic such as calls to GetComponent + * should be made here, not in the constructor which is called before an entity is finished. + */ + public void create() { + // No action by default. + } + + /** + * Early update called once per frame of the game, before update(). Use this only for logic that + * must run before other updates, such as physics. Not called if component is disabled. + */ + public void earlyUpdate() { + // No action by default. + } + + /** + * Called once per frame of the game, and should be used for most component logic. Not called if + * component is disabled. + */ + public void update() { + // No action by default. + } + + /** Called when the component is disposed. Dispose of any internal resources here. */ + public void dispose() { + // No action by default. + } + + /** + * Set the entity to which this component belongs. This is called by the Entity, and should not be + * set manually. + * + * @param entity The entity to which the component is attached. + */ + public void setEntity(Entity entity) { + logger.debug("Attaching {} to {}", this, entity); + this.entity = entity; + } + + /** + * Get the entity to which this component belongs. + * @return entity + */ + public Entity getEntity() { + return entity; + } + + /** + * Enable or disable the component. While disabled, a component does not run update() or + * earlyUpdate(). Other events inside the component may still fire. The component can still be + * disposed while disabled. + * + * @param enabled Should component be enabled + */ + public void setEnabled(boolean enabled) { + logger.debug("Setting enabled={} on {}", enabled, this); + this.enabled = enabled; + } + + /** Used to trigger the component to update itself. This should not need to be called manually. */ + public final void triggerUpdate() { + if (enabled) { + update(); + } + } + + /** + * Used to trigger the component to early-update itself. This should not need to be called + * manually. + */ + public final void triggerEarlyUpdate() { + if (enabled) { + earlyUpdate(); + } + } + + @Override + public String toString() { + String className = this.getClass().getSimpleName(); + if (entity == null) { + return className; + } + return entity + "." + className; + } +} 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 db110417e..32b32e3d3 100644 --- a/source/core/src/main/com/csse3200/game/components/EffectComponent.java +++ b/source/core/src/main/com/csse3200/game/components/EffectComponent.java @@ -54,6 +54,9 @@ 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); @@ -82,6 +85,9 @@ 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 4fb249d6d..596bb71f2 100644 --- a/source/core/src/main/com/csse3200/game/components/EffectsComponent.java +++ b/source/core/src/main/com/csse3200/game/components/EffectsComponent.java @@ -2,13 +2,20 @@ 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; /** @@ -95,7 +102,6 @@ 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 @@ -130,4 +136,132 @@ 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/TouchAttackComponent.java b/source/core/src/main/com/csse3200/game/components/TouchAttackComponent.java index 2ff88df7e..b55a6e80a 100644 --- a/source/core/src/main/com/csse3200/game/components/TouchAttackComponent.java +++ b/source/core/src/main/com/csse3200/game/components/TouchAttackComponent.java @@ -1,183 +1,299 @@ -package com.csse3200.game.components; - -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.physics.box2d.Body; -import com.badlogic.gdx.physics.box2d.Fixture; -import com.csse3200.game.components.npc.DeflectingComponent; -import com.csse3200.game.entities.Entity; -import com.csse3200.game.entities.Weapon; -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.PhysicsComponent; - -/** - * When this entity touches a valid enemy's hitbox, deal damage to them and - * apply a knockback. - * Has an optional disposeOnHit property that disposes projectile upon - * collision. - * - *

- * Requires CombatStatsComponent, HitboxComponent on this entity. - * - *

- * Damage is only applied if target entity has a CombatStatsComponent. Knockback - * is only applied - * if target entity has a PhysicsComponent. - */ -public class TouchAttackComponent extends Component { - private short targetLayer; - private float knockbackForce = 0f; - private boolean disposeOnHit = false; - private CombatStatsComponent combatStats; - private HitboxComponent hitboxComponent; - - /** - * Create a component which attacks entities on collision, without knockback. - * - * @param targetLayer The physics layer of the target's collider. - */ - public TouchAttackComponent(short targetLayer) { - this.targetLayer = targetLayer; - } - - /** - * Create a component which attacks entities on collision, with knockback. - * - * @param targetLayer The physics layer of the target's collider. - * @param knockback The magnitude of the knockback applied to the entity. - */ - public TouchAttackComponent(short targetLayer, float knockback) { - this.targetLayer = targetLayer; - this.knockbackForce = knockback; - } - - /** - * Create a component which attacks entities on collision, with knockback and - * self-dispose. - * - * @param targetLayer The physics layer of the target's collider. - * @param knockback The magnitude of the knockback applied to the entity. - * @param disposeOnHit Whether this entity should be disposed on hit. - */ - public TouchAttackComponent(short targetLayer, float knockback, boolean disposeOnHit) { - this.targetLayer = targetLayer; - this.knockbackForce = knockback; - this.disposeOnHit = disposeOnHit; - } - - @Override - public void create() { - entity.getEvents().addListener("collisionStart", this::onCollisionStart); - entity.getEvents().addListener("collisionEnd", this::onCollisionEnd); - combatStats = entity.getComponent(CombatStatsComponent.class); - hitboxComponent = entity.getComponent(HitboxComponent.class); - } - - public void onCollisionStart(Fixture me, Fixture other) { - if (hitboxComponent.getFixture() != me) { - // Not triggered by hitbox, ignore - return; - } - - if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { - // Doesn't match our target layer, ignore - return; - } - - // Try to attack target. - Entity target = ((BodyUserData) other.getBody().getUserData()).entity; - - // If enemy has deflecting component, don't delete it. - Component deflectComponent = target.getComponent(DeflectingComponent.class); - if (deflectComponent != null && deflectComponent.enabled) - return; - - CombatStatsComponent targetStats = target.getComponent(CombatStatsComponent.class); - if (targetStats != null) { - // If entity has abilities, pick one at random and apply it else use baseAttack - // damage - if (combatStats.getWeapon(target) != null) { - targetStats.hit(combatStats.getWeapon(target).getDamage()); - } else { - targetStats.hit(combatStats.getBaseAttack()); - } - } - // Apply knockback - PhysicsComponent physicsComponent = target.getComponent(PhysicsComponent.class); - if (physicsComponent != null && knockbackForce > 0f) { - Body targetBody = physicsComponent.getBody(); - Vector2 direction = target.getCenterPosition().sub(entity.getCenterPosition()); - Vector2 impulse = direction.setLength(knockbackForce); - targetBody.applyLinearImpulse(impulse, targetBody.getWorldCenter(), true); - } - - if (disposeOnHit) { - Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; - projectile.setFlagForDelete(true); - } - } - - public void setDisposeOnHit(boolean disposeOnHit) { - this.disposeOnHit = disposeOnHit; - } - - public void setKnockBack(float knockback) { - this.knockbackForce = knockback; - } - - private void onCollisionEnd(Fixture me, Fixture other) { - // Nothing to do on collision end - if (hitboxComponent.getFixture() != me) { - // Not triggered by hitbox, ignore - return; - } - - if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { - // Doesn't match our target layer, ignore - return; - } - - Entity otherEntity = ((BodyUserData) other.getBody().getUserData()).entity; - - // If enemy has enabled deflection component, don't dispose it. - if (otherEntity.getComponent(DeflectingComponent.class) != null) - return; - - if (disposeOnHit) { - Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; - projectile.setFlagForDelete(true); - } - } - - /** - * Choose the weapon to use against the given fixture. - * - * If the fixture has been removed (died) return null, else return the weapon to use. - * */ - public Weapon chooseWeapon(Fixture other) { - if (other == null) { - return null; - } - BodyUserData data = ((BodyUserData) other.getBody().getUserData()); - if (data == null) { - return null; - } - Entity target = data.entity; - Weapon weapon = null; - if (target.getComponent(CombatStatsComponent.class) != null) { - weapon = combatStats.getWeapon(target); - } - return weapon; - } - - /** - * Sets the target layer of this component, changing which entity to "attack" - * and/or apply knockback to. - * - * @param targetLayer - */ - public void setTargetLayer(short targetLayer) { - this.targetLayer = targetLayer; - } -} +package com.csse3200.game.components; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.Fixture; +import com.csse3200.game.components.npc.DeflectingComponent; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.Weapon; +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.PhysicsComponent; +import com.csse3200.game.components.projectile.EngineerBulletsAnimationController; +import com.csse3200.game.components.projectile.ProjectileAnimationController; +import com.csse3200.game.components.projectile.SnowBallProjectileAnimationController; +import com.csse3200.game.components.projectile.StunEffectProjectileAnimationController; +import com.csse3200.game.components.projectile.BurnEffectProjectileAnimationController; +import com.csse3200.game.physics.components.PhysicsMovementComponent; +import java.util.Timer; +import java.util.TimerTask; +import com.csse3200.game.components.npc.XenoAnimationController; +import com.csse3200.game.components.npc.DragonKnightAnimationController; +import com.csse3200.game.components.npc.FireWormAnimationController; +import com.csse3200.game.components.npc.SkeletonAnimationController; +import com.csse3200.game.components.npc.WizardAnimationController; +import com.csse3200.game.components.npc.WaterQueenAnimationController; +import com.csse3200.game.components.npc.WaterSlimeAnimationController; +import com.csse3200.game.ai.tasks.AITaskComponent; + +/** + * When this entity touches a valid enemy's hitbox, deal damage to them and + * apply a knockback. + * Has an optional disposeOnHit property that disposes projectile upon + * collision. + * + *

+ * Requires CombatStatsComponent, HitboxComponent on this entity. + * + *

+ * Damage is only applied if target entity has a CombatStatsComponent. Knockback + * is only applied + * if target entity has a PhysicsComponent. + */ +public class TouchAttackComponent extends Component { + private short targetLayer; + private float knockbackForce = 0f; + private boolean disposeOnHit = false; + private int aoeSize = 0; + private CombatStatsComponent combatStats; + private HitboxComponent hitboxComponent; + + /** + * Create a component which attacks entities on collision, without knockback. + * + * @param targetLayer The physics layer of the target's collider. + */ + public TouchAttackComponent(short targetLayer) { + this.targetLayer = targetLayer; + } + + /** + * Create a component which attacks entities on collision, with knockback. + * + * @param targetLayer The physics layer of the target's collider. + * @param knockback The magnitude of the knockback applied to the entity. + */ + public TouchAttackComponent(short targetLayer, float knockback) { + this.targetLayer = targetLayer; + this.knockbackForce = knockback; + } + + /** + * Create a component which attacks entities on collision, with knockback and + * self-dispose. + * + * @param targetLayer The physics layer of the target's collider. + * @param knockback The magnitude of the knockback applied to the entity. + * @param disposeOnHit Whether this entity should be disposed on hit. + */ + public TouchAttackComponent(short targetLayer, float knockback, boolean disposeOnHit) { + this.targetLayer = targetLayer; + this.knockbackForce = knockback; + this.disposeOnHit = disposeOnHit; + } + + @Override + public void create() { + entity.getEvents().addListener("collisionStart", this::onCollisionStart); + entity.getEvents().addListener("collisionEnd", this::onCollisionEnd); + combatStats = entity.getComponent(CombatStatsComponent.class); + hitboxComponent = entity.getComponent(HitboxComponent.class); + } + + public void onCollisionStart(Fixture me, Fixture other) { + if (me==null || hitboxComponent==null || hitboxComponent.getFixture() != me) { + // Not triggered by hitbox, ignore + return; + } + if(other!=null) + { + if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { + // Doesn't match our target layer, ignore + return; + } + Component deflectComponent = ((BodyUserData) other.getBody().getUserData()).entity.getComponent(DeflectingComponent.class); + if (deflectComponent != null && deflectComponent.enabled) + return; + }else + return; + // Try to attack target. + Entity target = ((BodyUserData) other.getBody().getUserData()).entity; + + EngineerBulletsAnimationController engineerBulletsAnimationController; + ProjectileAnimationController projectileAnimationController; + SnowBallProjectileAnimationController snowBallProjectileAnimationController; + StunEffectProjectileAnimationController stunEffectProjectileAnimationController; + BurnEffectProjectileAnimationController burnEffectProjectileAnimationController; + if((engineerBulletsAnimationController=entity.getComponent(EngineerBulletsAnimationController.class)) != null) + { + setDisposeOnHit(false); + entity.getComponent(PhysicsMovementComponent.class).setSpeed(new Vector2(0, 0)); + new Timer().schedule(new TimerTask() { + public void run() { + Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; + projectile.setFlagForDelete(true); + } + }, 300/*START_SPEED*frames*1000ms*/); + }else + if((projectileAnimationController=entity.getComponent(ProjectileAnimationController.class)) != null) + { + setDisposeOnHit(false); + entity.getComponent(PhysicsMovementComponent.class).setSpeed(new Vector2(0, 0)); + new Timer().schedule(new TimerTask() { + public void run() { + Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; + projectile.setFlagForDelete(true); + } + }, 300/*START_SPEED*frames*1000ms*/); + }else + if((burnEffectProjectileAnimationController=entity.getComponent(BurnEffectProjectileAnimationController.class)) != null) + { + setDisposeOnHit(false); + entity.getComponent(PhysicsMovementComponent.class).setSpeed(new Vector2(0, 0)); + new Timer().schedule(new TimerTask() { + public void run() { + Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; + projectile.setFlagForDelete(true); + } + }, 800/*START_SPEED*frames*1000ms*/); + }else + if((snowBallProjectileAnimationController=entity.getComponent(SnowBallProjectileAnimationController.class)) != null) + { + setDisposeOnHit(false); + entity.getComponent(PhysicsMovementComponent.class).setSpeed(new Vector2(0, 0)); + new Timer().schedule(new TimerTask() { + public void run() { + Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; + projectile.setFlagForDelete(true); + } + }, 200/*START_SPEED*frames*1000ms*/); + + AITaskComponent aiTaskComponent; + if((aiTaskComponent=target.getComponent(AITaskComponent.class))!=null) + { + aiTaskComponent.freezed = true; + PhysicsMovementComponent physicsMovementComponent; + if((physicsMovementComponent=target.getComponent(PhysicsMovementComponent.class))!=null) + physicsMovementComponent.setMoving(false); + new Timer().schedule(new TimerTask() { + public void run() { + aiTaskComponent.freezed = false; + PhysicsMovementComponent physicsMovementComponent; + if((physicsMovementComponent=target.getComponent(PhysicsMovementComponent.class))!=null) + physicsMovementComponent.setMoving(true); + target.getEvents().trigger("wanderStart"); + } + }, 5000); + } + target.getEvents().trigger("freeze"); + /*else + if(aiTaskComponent!=null) + aiTaskComponent.freezed = false;*/ + }else + if((stunEffectProjectileAnimationController=entity.getComponent(StunEffectProjectileAnimationController.class)) != null) + { + setDisposeOnHit(false); + entity.getComponent(PhysicsMovementComponent.class).setSpeed(new Vector2(0, 0)); + new Timer().schedule(new TimerTask() { + public void run() { + Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; + projectile.setFlagForDelete(true); + } + }, 900/*START_SPEED*frames*1000ms*/); + + AITaskComponent aiTaskComponent; + if((aiTaskComponent=target.getComponent(AITaskComponent.class))!=null) + { + aiTaskComponent.freezed = true; + PhysicsMovementComponent physicsMovementComponent; + if((physicsMovementComponent=target.getComponent(PhysicsMovementComponent.class))!=null) + physicsMovementComponent.setMoving(false); + new Timer().schedule(new TimerTask() { + public void run() { + aiTaskComponent.freezed = false; + PhysicsMovementComponent physicsMovementComponent; + if((physicsMovementComponent=target.getComponent(PhysicsMovementComponent.class))!=null) + physicsMovementComponent.setMoving(true); + } + }, 1000); + } + } + CombatStatsComponent targetStats = target.getComponent(CombatStatsComponent.class); + if (targetStats != null) { + // If entity has abilities, pick one at random and apply it else use baseAttack + // damage + if (combatStats.getWeapon(target) != null) { + targetStats.hit(combatStats.getWeapon(target).getDamage()); + } else { + targetStats.hit(combatStats.getBaseAttack()); + } + } + // Apply knockback + PhysicsComponent physicsComponent = target.getComponent(PhysicsComponent.class); + if (physicsComponent != null && knockbackForce > 0f) { + Body targetBody = physicsComponent.getBody(); + Vector2 direction = target.getCenterPosition().sub(entity.getCenterPosition()); + Vector2 impulse = direction.setLength(knockbackForce); + targetBody.applyLinearImpulse(impulse, targetBody.getWorldCenter(), true); + } + + if (disposeOnHit) { + Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; + projectile.setFlagForDelete(true); + } + } + + public void setDisposeOnHit(boolean disposeOnHit) { + this.disposeOnHit = disposeOnHit; + } + + public void setKnockBack(float knockback) { + this.knockbackForce = knockback; + } + + private void onCollisionEnd(Fixture me, Fixture other) { + // Nothing to do on collision end + if (hitboxComponent.getFixture() != me) { + // Not triggered by hitbox, ignore + return; + } + + if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { + // Doesn't match our target layer, ignore + return; + } + + Entity otherEntity = ((BodyUserData) other.getBody().getUserData()).entity; + + // If enemy has enabled deflection component, don't dispose it. + if (otherEntity.getComponent(DeflectingComponent.class) != null) + return; + + if (disposeOnHit) { + Entity projectile = ((BodyUserData) me.getBody().getUserData()).entity; + projectile.setFlagForDelete(true); + } + } + + /** + * Choose the weapon to use against the given fixture. + * + * If the fixture has been removed (died) return null, else return the weapon to use. + * */ + public Weapon chooseWeapon(Fixture other) { + if (other == null) { + return null; + } + BodyUserData data = ((BodyUserData) other.getBody().getUserData()); + if (data == null) { + return null; + } + Entity target = data.entity; + Weapon weapon = null; + if (target.getComponent(CombatStatsComponent.class) != null) { + weapon = combatStats.getWeapon(target); + } + return weapon; + } + + /** + * Sets the target layer of this component, changing which entity to "attack" + * and/or apply knockback to. + * + * @param targetLayer + */ + public void setTargetLayer(short targetLayer) { + this.targetLayer = targetLayer; + } +} 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 b110de999..858563858 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,6 +1,5 @@ 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; @@ -57,17 +56,11 @@ 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.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))); + scrapsTb.addAction(new SequenceAction(Actions.fadeIn(4f))); + crystalsTb.addAction(new SequenceAction(Actions.fadeIn(8f))); } 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 09d2d3d73..6334e1b4a 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,10 +1,8 @@ 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; @@ -59,25 +57,20 @@ private void addActors() { table.add(engineerTb).width(engineerTb.getWidth() * 0.5f).height(engineerTb.getHeight() * 0.5f); stage.addActor(table); - // 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))); + engineerTb.addAction(new SequenceAction(Actions.fadeIn(4f))); } /** * Updates the engineer count on the UI component */ public void updateCount() { - 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()) { + 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/maingame/MainGameActions.java b/source/core/src/main/com/csse3200/game/components/maingame/MainGameActions.java index bbdd88acc..7253f6d3b 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,19 +21,7 @@ public MainGameActions(GdxGame game) { public void create() { entity.getEvents().addListener("exit", this::onExit); entity.getEvents().addListener("lose", this::onLose); - 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); + //entity.getEvents().addListener("win", this::onWin); } /** @@ -47,4 +35,6 @@ 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 bb0e32a50..f9d6c4de1 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,6 +15,7 @@ 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; @@ -31,7 +32,6 @@ 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,83 +86,19 @@ private void addActors() { // Create and position the tables that will hold the buttons. // Contains the tower build menu buttons - towerTable.top().padTop(80f); + towerTable.top().padTop(50f); towerTable.setFillParent(true); // Contains other buttons (just pause at this stage) - buttonTable.top().right().padTop(80f).padRight(80f); + buttonTable.top().right().padTop(50f).padRight(80f); buttonTable.setFillParent(true); progressTable.top().center().setWidth(500f); progressTable.setFillParent(true); - levelNameTable.center().top().padLeft(20f).padTop(20f).pad(20f); + levelNameTable.top().left().padLeft(20f).padTop(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, @@ -181,19 +117,20 @@ private void setTowers() { // 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, true)) { - towers.add(tower); + if (towers.isEmpty()) { + towers.addAll(defaultTowers); + } else { + for (TowerType tower : defaultTowers) { + if (towers.size < 5 && !towers.contains(tower, false)) { + 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()); @@ -205,43 +142,12 @@ private void createTowerButtons() { 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((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))); + 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))); // Spawns a pause menu when the button is pressed. pauseBtn.addListener( @@ -273,7 +179,181 @@ public boolean keyUp(InputEvent event, int keycode) { return false; } }); - return pauseBtn; + + // 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(); } /** @@ -289,10 +369,6 @@ 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 cd005fe8b..6b0d93bf1 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,16 +12,22 @@ 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() { @@ -37,15 +43,16 @@ private void addActors() { remainingMobsButton = ButtonFactory.createButton("Mobs:" + ServiceLocator.getWaveService().getEnemyCount()); - 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))); + 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))); - buttonTable.top().right().padTop(160f).padRight(80f); + buttonTable.top().right().padTop(130f).padRight(80f); buttonTable.setFillParent(true); buttonTable.add(remainingMobsButton).right(); - + buttonTable.row(); + buttonTable.add(timerButton); stage.addActor(buttonTable); @@ -74,12 +81,11 @@ public void createTimerButton() { timerButton = ButtonFactory.createButton("Next wave in:" + (ServiceLocator.getWaveService().getNextWaveTime() / 1000)); - 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); + 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))); buttonTable.row(); - buttonTable.add(timerButton); + buttonTable.add(timerButton).padRight(10f); } /** @@ -90,22 +96,20 @@ 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 7562fd92c..2f57c0ecc 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,6 +2,7 @@ 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 2fdc6ddf1..f0a67c1ff 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,13 +53,14 @@ private void addActors() { cursorPixmap.dispose(); // Dispose of the Pixmap to release resources table = new Table(); + table1 = new Table(); table.setFillParent(true); - stage.addActor(table); + table1.setFillParent(true); - 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); + Image title = + new Image( + ServiceLocator.getResourceService() + .getAsset("images/background/main_menu/main_menu_bg.png", Texture.class)); title.setWidth(Gdx.graphics.getWidth()); title.setHeight(Gdx.graphics.getHeight()); title.setPosition(0, 0); @@ -125,13 +126,18 @@ public void changed(ChangeEvent changeEvent, Actor actor) { float padTopOtherBtns = 15f / originalScreenHeight * Gdx.graphics.getHeight(); - 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(); + 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); 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 82c587f18..71fa5359d 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,14 +5,19 @@ 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 c023e0aa5..e9bf8170e 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,13 +5,19 @@ 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 15fe60fcd..ab5aa645e 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() { - super.update(); + resetHealth(); } /** @@ -77,6 +77,8 @@ 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 f07028878..d4279f756 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,8 +7,6 @@ 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 @@ -29,10 +27,9 @@ 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 @@ -95,15 +92,11 @@ 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); - // Random direction - setVerticalAngleDirection(mobPos.y + (15 * randDirection)); - setVerticalSpeed(dodgeSpeed); + setVerticalAngleDirection(mobPos.y > 3.5 ? mobPos.y - 15 : mobPos.y + 15); + setVerticalSpeed(dodgeSpeed); } else { setVerticalAngleDirection(mobPos.y); setVerticalSpeed(originalSpeed); 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 7302a1cdc..dab866862 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 @@ -1,14 +1,22 @@ package com.csse3200.game.components.npc; +import com.badlogic.gdx.audio.Sound; 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 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() { @@ -17,6 +25,11 @@ public void create() { entity.getEvents().addListener("mob_walk", this::animateWalk); entity.getEvents().addListener("mob_attack", this::animateAttack); entity.getEvents().addListener("mob_death", this::animateDeath); + + entity.getEvents().addListener("wanderStart", this::animateWalk); + entity.getEvents().addListener("shootStart", this::animateAttack); + entity.getEvents().addListener("dieStart", this::animateDeath); + entity.getEvents().addListener("freeze", this::animateFreeze); } void animateWalk() { @@ -31,6 +44,9 @@ void animateDeath() { animator.startAnimation("dragon_knight_death"); } - + void animateFreeze() + { + animator.startAnimation("dragon_knight_freeze"); + } } 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 28d118210..02998db7f 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,13 +4,19 @@ 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( @@ -23,7 +29,11 @@ public void create() { entity.getEvents().addListener("mob_walk", this::animateWalk); entity.getEvents().addListener("mob_attack", this::animateAttack); entity.getEvents().addListener("mob_death", this::animateDeath); - entity.getEvents().addListener("default", this::stopAnimation); + + entity.getEvents().addListener("wanderStart", this::animateWalk); + entity.getEvents().addListener("shootStart", this::animateAttack); + entity.getEvents().addListener("dieStart", this::animateDeath); + entity.getEvents().addListener("freeze", this::animateFreeze); } void animateWalk() { @@ -44,6 +54,9 @@ void stopAnimation() { animator.startAnimation("default"); } - + void animateFreeze() + { + animator.startAnimation("fire_worm_freeze"); + } } 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 b10236761..267c23404 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,9 +3,12 @@ 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 dfbd4bc9a..3bdad9407 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,9 +3,13 @@ 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 fccdfe580..d821f6cca 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,6 +2,7 @@ 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 @@ -12,7 +13,9 @@ 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; + AnimationRenderComponent animator; + private SecureRandom rand = new SecureRandom(); + @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 63f850085..f6743dd9d 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,8 +3,11 @@ 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 7a821ef75..bafa8d36a 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,30 +4,33 @@ 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"; Sound deathSound = ServiceLocator.getResourceService().getAsset( ATTACK_SOUND, Sound.class); - private static final String DEATH_SOUND = "sounds/mobs/skeletonHit.mp3"; - Sound attackSound = ServiceLocator.getResourceService().getAsset( - DEATH_SOUND, Sound.class); - @Override public void create() { super.create(); animator = this.entity.getComponent(AnimationRenderComponent.class); - entity.getEvents().addListener("mob_walk", this::animateWalk); - entity.getEvents().addListener("mob_attack", this::animateAttack); - entity.getEvents().addListener("mob_death", this::animateDeath); + entity.getEvents().addListener("wanderStart", this::animateWalk); + entity.getEvents().addListener("shootStart", this::animateAttack); + entity.getEvents().addListener("dieStart", this::animateDeath); + entity.getEvents().addListener("freeze", this::animateFreeze); } void animateWalk() { @@ -36,8 +39,6 @@ void animateWalk() { void animateAttack() { animator.startAnimation("skeleton_attack"); - attackSound.setVolume(1000, 0); - attackSound.play(); } void animateDeath() { @@ -45,5 +46,10 @@ void animateDeath() { deathSound.setVolume(1000, 5.5f); deathSound.play(); } + + void animateFreeze() + { + animator.startAnimation("skeleton_freeze"); + } } 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 6b92dd1cf..3fd20bb9d 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 = (entity.getPosition().y); + float newYPosition = (float) (entity.getPosition().y); if (withinBounds(newXPosition, newYPosition)) { spawnAdditionalMob(newXPosition, newYPosition, initialScaleX, initialScaleY); @@ -133,32 +133,38 @@ 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); @@ -174,9 +180,12 @@ public void spawnAdditionalMob(float positionX, float positionY, * False otherwise. */ private boolean withinBounds(float currX, float currY) { - return currX >= MIN_X_BOUNDS + if (currX >= MIN_X_BOUNDS && currX <= MAX_X_BOUNDS && currY >= MIN_Y_BOUNDS - && currY <= MAX_Y_BOUNDS; + && currY <= MAX_Y_BOUNDS) { + return true; + } + return false; } } 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 294f312b1..82209c68b 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,13 +4,19 @@ 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( @@ -20,9 +26,10 @@ public class WaterQueenAnimationController extends Component { public void create() { super.create(); animator = this.entity.getComponent(AnimationRenderComponent.class); - entity.getEvents().addListener("mob_walk", this::animateWalk); - entity.getEvents().addListener("mob_attack", this::animateAttack); - entity.getEvents().addListener("mob_death", this::animateDeath); + entity.getEvents().addListener("wanderStart", this::animateWalk); + entity.getEvents().addListener("shootStart", this::animateAttack); + entity.getEvents().addListener("dieStart", this::animateDeath); + entity.getEvents().addListener("freeze", this::animateFreeze); } void animateWalk() { @@ -38,5 +45,9 @@ void animateAttack() { void animateDeath() { animator.startAnimation("water_queen_death"); } + + void animateFreeze() { + animator.startAnimation("water_queen_freeze"); + } } 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 52163ddcb..b0e14ba49 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 @@ -1,22 +1,31 @@ package com.csse3200.game.components.npc; +import com.badlogic.gdx.audio.Sound; 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 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() { super.create(); animator = this.entity.getComponent(AnimationRenderComponent.class); - entity.getEvents().addListener("mob_walk", this::animateWalk); - entity.getEvents().addListener("mob_attack", this::animateAttack); - entity.getEvents().addListener("mob_death", this::animateDeath); + entity.getEvents().addListener("wanderStart", this::animateWalk); + entity.getEvents().addListener("shootStart", this::animateAttack); + entity.getEvents().addListener("dieStart", this::animateDeath); + entity.getEvents().addListener("freeze", this::animateFreeze); } void animateWalk() { @@ -30,6 +39,10 @@ void animateAttack() { void animateDeath() { animator.startAnimation("water_slime_death"); } + + void animateFreeze() { + animator.startAnimation("water_slime_freeze"); + } } 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 9b4660afb..68ac160fe 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,13 +4,19 @@ 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"; @@ -25,6 +31,12 @@ public void create() { entity.getEvents().addListener("mob_walk", this::animateWalk); entity.getEvents().addListener("mob_attack", this::animateAttack); entity.getEvents().addListener("mob_death", this::animateDeath); + + entity.getEvents().addListener("wanderStart", this::animateWalk); + entity.getEvents().addListener("shootStart", this::animateAttack); + entity.getEvents().addListener("dieStart", this::animateDeath); + entity.getEvents().addListener("freeze", this::animateFreeze); + } void animateWalk() { @@ -40,5 +52,10 @@ void animateAttack() { void animateDeath() { animator.startAnimation("wizard_death"); } + + void animateFreeze() + { + animator.startAnimation("wizard_freeze"); + } } diff --git a/source/core/src/main/com/csse3200/game/components/npc/XenoAnimationController.java b/source/core/src/main/com/csse3200/game/components/npc/XenoAnimationController.java index d07dc4683..f8a4abf3c 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/XenoAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/npc/XenoAnimationController.java @@ -1,7 +1,9 @@ package com.csse3200.game.components.npc; +import com.badlogic.gdx.audio.Sound; import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; import java.security.SecureRandom; /** @@ -26,6 +28,7 @@ public void create() { entity.getEvents().addListener("shootStart", this::animateShoot); entity.getEvents().addListener("dieStart", this::animateDie); entity.getEvents().addListener("stop", this::stopAnimation); + entity.getEvents().addListener("freeze", this::animateFreeze); } void animateRun() { @@ -56,4 +59,9 @@ void animateDie() { void stopAnimation() { animator.startAnimation("default"); } + + void animateFreeze() + { + animator.startAnimation("xeno_freeze"); + } } 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 23fb243c9..ce305311e 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,10 +1,13 @@ 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; @@ -13,15 +16,14 @@ 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; @@ -40,9 +42,6 @@ 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(); @@ -106,6 +105,7 @@ public void changed(ChangeEvent changeEvent, Actor actor) { } }); + window.setResizable(true); window.setModal(true); window.setTouchable(Touchable.enabled); @@ -119,30 +119,14 @@ 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 @@ -158,18 +142,11 @@ 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 80ebb6db0..b1be835cb 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,6 +10,7 @@ * 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 43907be2f..a12dd12ad 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,12 +7,14 @@ * This input handler only uses keyboard input. */ public class PopupMenuInputComponent extends InputComponent{ - /** - * !!! - * NOTE: THIS CLASS IS OBSOLETE - * !!! + /** 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. */ - 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/projectile/BurnEffectProjectileAnimationController.java b/source/core/src/main/com/csse3200/game/components/projectile/BurnEffectProjectileAnimationController.java index 847f77027..01e052cc6 100644 --- a/source/core/src/main/com/csse3200/game/components/projectile/BurnEffectProjectileAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/projectile/BurnEffectProjectileAnimationController.java @@ -2,6 +2,9 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.badlogic.gdx.physics.box2d.Fixture; +import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.components.HitboxComponent; public class BurnEffectProjectileAnimationController extends Component { /** Event name constants */ @@ -12,7 +15,14 @@ public class BurnEffectProjectileAnimationController extends Component { private static final String START_ANIM = "projectile"; private static final String FINAL_ANIM = "projectileFinal"; AnimationRenderComponent animator; - + + private HitboxComponent hitboxComponent; + short targetLayer; + + public BurnEffectProjectileAnimationController(short targetLayer) + { + this.targetLayer = targetLayer; + } @Override public void create() { @@ -21,6 +31,7 @@ public void create() { entity.getEvents().addListener(START, this::animateStart); entity.getEvents().addListener(FINAL, this::animateFinal); + hitboxComponent = entity.getComponent(HitboxComponent.class); } void animateStart() { @@ -28,6 +39,18 @@ void animateStart() { } void animateFinal() { - animator.startAnimation(FINAL_ANIM); + } + + public void animateCollide(Fixture me, Fixture other) { + if (hitboxComponent.getFixture() != me) { + // Not triggered by hitbox, ignore + return; + } + if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { + // Doesn't match our target layer, ignore + return; + } + + animator.startAnimation("explosion"); } } diff --git a/source/core/src/main/com/csse3200/game/components/projectile/EngineerBulletsAnimationController.java b/source/core/src/main/com/csse3200/game/components/projectile/EngineerBulletsAnimationController.java index a9dc1a63f..d68d4d79f 100644 --- a/source/core/src/main/com/csse3200/game/components/projectile/EngineerBulletsAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/projectile/EngineerBulletsAnimationController.java @@ -3,11 +3,24 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.ServiceLocator; //used for sound +import com.badlogic.gdx.physics.box2d.Fixture; +import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.components.HitboxComponent; +import com.csse3200.game.physics.BodyUserData; +import com.csse3200.game.components.npc.DeflectingComponent; public class EngineerBulletsAnimationController extends Component{ /** Event name constants */ AnimationRenderComponent animator; + + private HitboxComponent hitboxComponent; + short targetLayer; + + public EngineerBulletsAnimationController(short targetLayer) + { + this.targetLayer = targetLayer; + } @Override public void create() { @@ -15,7 +28,8 @@ public void create() { animator = this.entity.getComponent(AnimationRenderComponent.class); entity.getEvents().addListener("startProjectile", this::animateStart); entity.getEvents().addListener("startProjectileFinal", this::animateFinal); - + entity.getEvents().addListener("collisionStart", this::animateCollide); + hitboxComponent = entity.getComponent(HitboxComponent.class); } void animateStart() { @@ -25,5 +39,27 @@ void animateStart() { void animateFinal() { animator.startAnimation("bulletFinal"); } + + void animateCollide(Fixture me, Fixture other){ + if(me!=null) + { + if (hitboxComponent==null || hitboxComponent.getFixture() != me) { + // Not triggered by hitbox, ignore + return; + } + }else + { + animator.startAnimation("bulletCollide"); + return; + } + if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { + // Doesn't match our target layer, ignore + return; + } + Component deflectComponent = ((BodyUserData) other.getBody().getUserData()).entity.getComponent(DeflectingComponent.class); + if (deflectComponent != null && deflectComponent.enabled) + return; + animator.startAnimation("bulletCollide"); + } } diff --git a/source/core/src/main/com/csse3200/game/components/projectile/PierceArrowAnimationController.java b/source/core/src/main/com/csse3200/game/components/projectile/PierceArrowAnimationController.java new file mode 100644 index 000000000..89bd71d32 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/components/projectile/PierceArrowAnimationController.java @@ -0,0 +1,25 @@ +package com.csse3200.game.components.projectile; + +import com.csse3200.game.components.Component; +import com.csse3200.game.rendering.AnimationRenderComponent; + +public class PierceArrowAnimationController extends Component { + /** Event name constants */ + private static final String START = "startProjectile"; + /** Animation name constants */ + private static final String START_ANIM = "arrow"; + AnimationRenderComponent animator; + + + @Override + public void create() { + super.create(); + animator = this.entity.getComponent(AnimationRenderComponent.class); + entity.getEvents().addListener(START, this::animateStart); + + } + + void animateStart() { + animator.startAnimation(START_ANIM); + } +} diff --git a/source/core/src/main/com/csse3200/game/components/projectile/ProjectileAnimationController.java b/source/core/src/main/com/csse3200/game/components/projectile/ProjectileAnimationController.java index 9610554c9..2b0a18608 100644 --- a/source/core/src/main/com/csse3200/game/components/projectile/ProjectileAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/projectile/ProjectileAnimationController.java @@ -2,6 +2,9 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.badlogic.gdx.physics.box2d.Fixture; +import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.components.HitboxComponent; public class ProjectileAnimationController extends Component{ /** Event name constants */ @@ -12,7 +15,14 @@ public class ProjectileAnimationController extends Component{ private static final String START_ANIM = "projectile"; private static final String FINAL_ANIM = "projectileFinal"; AnimationRenderComponent animator; - + + private HitboxComponent hitboxComponent; + short targetLayer; + + public ProjectileAnimationController(short targetLayer) + { + this.targetLayer = targetLayer; + } @Override public void create() { @@ -20,7 +30,8 @@ public void create() { animator = this.entity.getComponent(AnimationRenderComponent.class); entity.getEvents().addListener(START, this::animateStart); entity.getEvents().addListener(FINAL, this::animateFinal); - + entity.getEvents().addListener("collisionStart", this::animateCollide); + hitboxComponent = entity.getComponent(HitboxComponent.class); } void animateStart() { @@ -30,4 +41,17 @@ void animateStart() { void animateFinal() { animator.startAnimation(FINAL_ANIM); } + + void animateCollide(Fixture me, Fixture other) { + if (hitboxComponent.getFixture() != me) { + // Not triggered by hitbox, ignore + return; + } + if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { + // Doesn't match our target layer, ignore + return; + } + + animator.startAnimation("projectileCollide"); + } } diff --git a/source/core/src/main/com/csse3200/game/components/projectile/SnowBallProjectileAnimationController.java b/source/core/src/main/com/csse3200/game/components/projectile/SnowBallProjectileAnimationController.java index adb1f2869..d80b5b209 100644 --- a/source/core/src/main/com/csse3200/game/components/projectile/SnowBallProjectileAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/projectile/SnowBallProjectileAnimationController.java @@ -2,6 +2,9 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.badlogic.gdx.physics.box2d.Fixture; +import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.components.HitboxComponent; public class SnowBallProjectileAnimationController extends Component{ private static final String START = "startProjectile"; @@ -11,6 +14,14 @@ public class SnowBallProjectileAnimationController extends Component{ private static final String START_ANIM = "projectile"; private static final String FINAL_ANIM = "projectileFinal"; AnimationRenderComponent animator; + + private HitboxComponent hitboxComponent; + short targetLayer; + + public SnowBallProjectileAnimationController(short targetLayer) + { + this.targetLayer = targetLayer; + } @Override public void create() { @@ -18,7 +29,9 @@ public void create() { animator = this.entity.getComponent(AnimationRenderComponent.class); entity.getEvents().addListener(START, this::animateStart); entity.getEvents().addListener(FINAL, this::animateFinal); + entity.getEvents().addListener("collisionStart", this::animateCollide); + hitboxComponent = entity.getComponent(HitboxComponent.class); } void animateStart() { @@ -28,4 +41,17 @@ void animateStart() { void animateFinal() { animator.startAnimation(FINAL_ANIM); } + + void animateCollide(Fixture me, Fixture other) { + if (hitboxComponent.getFixture() != me) { + // Not triggered by hitbox, ignore + return; + } + if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { + // Doesn't match our target layer, ignore + return; + } + + animator.startAnimation("collision"); + } } diff --git a/source/core/src/main/com/csse3200/game/components/projectile/StunEffectProjectileAnimationController.java b/source/core/src/main/com/csse3200/game/components/projectile/StunEffectProjectileAnimationController.java index 94899ff17..507a689d4 100644 --- a/source/core/src/main/com/csse3200/game/components/projectile/StunEffectProjectileAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/projectile/StunEffectProjectileAnimationController.java @@ -2,6 +2,9 @@ import com.csse3200.game.components.Component; import com.csse3200.game.rendering.AnimationRenderComponent; +import com.badlogic.gdx.physics.box2d.Fixture; +import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.components.HitboxComponent; public class StunEffectProjectileAnimationController extends Component { /** Event name constants */ @@ -11,17 +14,39 @@ public class StunEffectProjectileAnimationController extends Component { private static final String START_ANIM = "projectile"; AnimationRenderComponent animator; + private HitboxComponent hitboxComponent; + short targetLayer; + + public StunEffectProjectileAnimationController(short targetLayer) + { + this.targetLayer = targetLayer; + } @Override public void create() { super.create(); animator = this.entity.getComponent(AnimationRenderComponent.class); entity.getEvents().addListener(START, this::animateStart); + entity.getEvents().addListener("collisionStart", this::animateCollide); + hitboxComponent = entity.getComponent(HitboxComponent.class); } void animateStart() { animator.startAnimation(START_ANIM); } - + + void animateCollide(Fixture me, Fixture other) + { + if (hitboxComponent.getFixture() != me) { + // Not triggered by hitbox, ignore + return; + } + if (!PhysicsLayer.contains(targetLayer, other.getFilterData().categoryBits)) { + // Doesn't match our target layer, ignore + return; + } + + animator.startAnimation("stun"); + } } 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 3d33e15a2..3c79de39a 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 @@ -105,13 +105,27 @@ public void updateTowerState() { } switch (towerState) { - case WALK -> handleWalkState(); - case IDLE -> handleIdleState(); - case SHOOT_DOWN -> handleShootDownState(); - case SHOOT_UP -> handleShootUpState(); - case DOWN -> handleDownState(); - case UP -> handleUpState(); - default -> handleDieState(); // DIE + case WALK -> { + handleWalkState(); + } + case IDLE -> { + handleIdleState(); + } + case SHOOT_DOWN -> { + handleShootDownState(); + } + case SHOOT_UP -> { + handleShootUpState(); + } + case DOWN -> { + handleDownState(); + } + case UP -> { + handleUpState(); + } + default -> { // DIE + handleDieState(); + } } } @@ -124,10 +138,6 @@ 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; } 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 5654f3b15..0c434b674 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 @@ -101,10 +101,18 @@ public void updateTowerState() { } switch (towerState) { - case IDLE -> handleIdleState(); - case PREP_ATTACK -> handlePrepAttackState(); - case ATTACK -> handleAttackState(); - default -> handleDeathState(); // DEATH + case IDLE -> { + handleIdleState(); + } + case PREP_ATTACK -> { + handlePrepAttackState(); + } + case ATTACK -> { + handleAttackState(); + } + default -> { // DEATH + handleDeathState(); + } } } @@ -132,6 +140,22 @@ public int getPriority() { return !isTargetVisible() ? 0 : priority; } + /** + * not currently used. + * @return the priority for this task + */ + public int getActivePriority() { + return !isTargetVisible() ? 0 : priority; + } + + /** + * not currently used. + * @return + */ + public int getInactivePriority() { + return isTargetVisible() ? priority : 0; + } + /** * detects targets from the centre of the tower to maxRange in a straight line. * @return true if mobs are present and false otherwise. @@ -146,6 +170,15 @@ 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; + } + /** * Function for getting the tower's state. * 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 e8bcbe5de..9d29a1738 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,8 +13,6 @@ 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 @@ -40,7 +38,6 @@ 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; @@ -57,7 +54,6 @@ 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(); } @@ -85,12 +81,7 @@ public void start() { public void update() { if (timeSource.getTime() >= endTime) { updateTowerState(); - if (towerState == STATE.ATTACK) { - endTime = timeSource.getTime() + round(fireRateInterval * 1000); - } else { - endTime = timeSource.getTime() + (INTERVAL * 1000); - } - + endTime = timeSource.getTime() + (INTERVAL * 1000); } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobAttackTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobAttackTask.java index 39215cb9e..152d27693 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobAttackTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobAttackTask.java @@ -16,13 +16,15 @@ import com.csse3200.game.physics.raycast.RaycastHit; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.ai.tasks.AITaskComponent; +import com.csse3200.game.components.npc.XenoAnimationController; /** * Task that allows mobs to shoot projectiles or melee attack towers */ public class MobAttackTask extends DefaultTask implements PriorityTask { private static final int INTERVAL = 1; // time interval to scan for towers in - private static final short TARGET_LAYER = PhysicsLayer.HUMANS; // mobs detecting for towers + private static final short TARGET = PhysicsLayer.HUMANS; // mobs detecting for towers // ^ fix this private static final String STOW = "wanderStart"; @@ -33,13 +35,15 @@ public class MobAttackTask extends DefaultTask implements PriorityTask { private Fixture target; private final int priority; + private final float maxRange; + private Vector2 mobPosition = new Vector2(10f,10f); private final Vector2 maxRangePosition = new Vector2(); private final PhysicsEngine physics; private GameTime timeSource; - + private long endTime; private final RaycastHit hit = new RaycastHit(); - private static final long DELAY = 1000; // delay between shots + private final long delay = 1000; // delay between shots private long startTime; private enum STATE { @@ -50,9 +54,11 @@ private enum STATE { /** * @param priority Task priority when targets are detected (0 when nothing detected). Must be a positive integer. + * @param maxRange Maximum effective range of the weapon mob. This determines the detection distance of targets */ - public MobAttackTask(int priority) { + public MobAttackTask(int priority, float maxRange) { this.priority = priority; + this.maxRange = maxRange; startTime = 0; physics = ServiceLocator.getPhysicsService().getPhysics(); @@ -66,9 +72,11 @@ public MobAttackTask(int priority) { public void start() { super.start(); startTime = timeSource.getTime(); - Vector2 mobPosition = owner.getEntity().getCenterPosition(); + this.mobPosition = owner.getEntity().getCenterPosition(); this.maxRangePosition.set(0, mobPosition.y); - long endTime = timeSource.getTime() + (INTERVAL * 500); + //owner.getEntity().getEvents().trigger(IDLE); + endTime = timeSource.getTime() + (INTERVAL * 500); +// owner.getEntity().getEvents().trigger("shootStart"); } /** @@ -77,11 +85,14 @@ public void start() { */ @Override public void update() { - updateMobState(); - - if (mobState == STATE.STOW) { - status = Status.FINISHED; - } + if(!owner.getEntity().getComponent(AITaskComponent.class).freezed) + { + updateMobState(); + + if (mobState == STATE.STOW) { + status = Status.FINISHED; + } + } } /** @@ -116,21 +127,25 @@ public void updateMobState() { if (!isTargetVisible() || this.meleeOrProjectile() == null) { this.owner.getEntity().getEvents().trigger(STOW); mobState = STATE.STOW; - } else if (this.meleeOrProjectile() instanceof Melee) { + } else { + if (this.meleeOrProjectile() instanceof Melee) { TouchAttackComponent attackComp = owner.getEntity().getComponent(TouchAttackComponent.class); HitboxComponent hitboxComp = owner.getEntity().getComponent(HitboxComponent.class); attackComp.onCollisionStart(hitboxComp.getFixture(), target); this.owner.getEntity().getEvents().trigger("meleeStart"); - } else { + } else { Entity newProjectile = ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)); - newProjectile.setPosition(owner.getEntity().getPosition().x, owner.getEntity().getPosition().y); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x), (float) (owner.getEntity().getPosition().y)); newProjectile.setScale(-1f, 1f); ServiceLocator.getEntityService().register(newProjectile); +// System.out.printf("ANIMATION: " + owner.getEntity().getComponent(AnimationRenderComponent.class).getCurrentAnimation() + "\n"); this.owner.getEntity().getEvents().trigger(FIRING); mobState = STATE.STOW; + } } owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(true); + } case STOW -> { @@ -165,20 +180,41 @@ public void stop() { */ @Override public int getPriority() { - if ((startTime + DELAY) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { + if (status == Status.ACTIVE) { + return getActivePriority(); + } + return getInactivePriority(); + } + + /** + * Fetches the active priority of the Task if a target is visible. + * @return (int) active priority if a target is visible, -1 otherwise + */ + private int getActivePriority() { + if ((startTime + delay) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { + return priority; + } + return -1; + } + + /** + * Fetches the inactive priority of the Task if a target is not visible. + * @return (int) -1 if a target is not visible, active priority otherwise + */ + private int getInactivePriority() { + if ((startTime + delay) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { return priority; } return -1; } /** - * Uses a raycast to determine whether there are any targets in detection range. - * + * Uses a raycast to determine whether there are any targets in detection range * @return true if a target is visible, false otherwise */ private boolean isTargetVisible() { Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); - return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET_LAYER, hit); + return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET, hit); } /** @@ -189,10 +225,11 @@ private boolean isTargetVisible() { * the function will return null. If it returns null when the mob is in state FIRING or DEPLOY, it will not fire * and will STOW. * - * @return the Weapon (Melee or Projectile) the mob will use to attack the target. null if immune target or no target + * returns the Weapon (Melee or Projectile) the mob will use to attack the target. null if immune target or no target * */ private Weapon meleeOrProjectile() { - +// Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); +// Fixture hitraycast = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET); setTarget(); TouchAttackComponent comp = owner.getEntity().getComponent(TouchAttackComponent.class); Weapon chosenWeapon = null; @@ -205,6 +242,6 @@ private Weapon meleeOrProjectile() { private void setTarget() { Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); - target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET_LAYER); + target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET); } } 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 85d29c15b..5782ca8f9 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,6 +1,5 @@ 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; @@ -12,8 +11,6 @@ import com.csse3200.game.services.GameTime; -/// THIS CODE IS REDUNDANT /// - /** * Task that prints a message to the terminal whenever it is called. */ @@ -100,18 +97,10 @@ 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(); - } - currency.setPosition(mobPosition.x,mobPosition.y); - ServiceLocator.getEntityService().register(currency); + Entity scrap = DropFactory.createScrapDrop(); + scrap.setPosition(mobPosition.x,mobPosition.y); + ServiceLocator.getEntityService().register(scrap); } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobDodgeTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobDodgeTask.java index a437fbdbf..5cc8a44d1 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobDodgeTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobDodgeTask.java @@ -1,9 +1,11 @@ package com.csse3200.game.components.tasks; -import com.csse3200.game.components.tasks.MobTask.MobTask; -import com.csse3200.game.components.tasks.MobTask.MobType; +import com.badlogic.gdx.math.Vector2; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.ai.tasks.AITaskComponent; +import com.csse3200.game.components.npc.XenoAnimationController; +import com.csse3200.game.components.tasks.MobTask.*; /** * This task runs the AI that adds a dodge mechanic/functionality for the mobs @@ -23,15 +25,17 @@ public class MobDodgeTask extends MobTask { private long endTime; // Helps task wait between each interval. - private static final int DELAY_INTERVAL = 500; + private final int DELAY_INTERVAL = 500; /** * Initialises a mob dodge task with a specified wander range, wait time, and * priority level. * - * @param mobType Distance in X and Y the entity can move from its position - * when start() is called. - * @param priority Priority level compared to other added tasks. + * @param wanderRange Distance in X and Y the entity can move from its position + * when start() is + * called. + * @param waitTime How long in seconds to wait between wandering. + * @param priority Priority level compared to other added tasks. */ public MobDodgeTask(MobType mobType, int priority) { super(mobType); @@ -59,13 +63,15 @@ public void start() { @Override public void update() { super.update(); - if (timeSource.getTime() >= endTime) { - owner.getEntity().getEvents().trigger("dodgeIncomingEntity", - owner.getEntity().getCenterPosition()); - + if(!owner.getEntity().getComponent(AITaskComponent.class).freezed) + { + if (timeSource.getTime() >= endTime) { + owner.getEntity().getEvents().trigger("dodgeIncomingEntity", + owner.getEntity().getCenterPosition()); - endTime = timeSource.getTime() + DELAY_INTERVAL; // update time - } + endTime = timeSource.getTime() + DELAY_INTERVAL; // update time + } + } } /** diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobMeleeAttackTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobMeleeAttackTask.java index b76de16a4..336b75f4b 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobMeleeAttackTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobMeleeAttackTask.java @@ -16,13 +16,15 @@ import com.csse3200.game.physics.raycast.RaycastHit; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.ai.tasks.AITaskComponent; +import com.csse3200.game.components.npc.XenoAnimationController; /** * Task that allows mobs to shoot projectiles or melee attack towers */ public class MobMeleeAttackTask extends DefaultTask implements PriorityTask { private static final int INTERVAL = 1; // time interval to scan for towers in - private static final short TARGET_LAYER = PhysicsLayer.HUMANS; // mobs detecting for towers + private static final short TARGET = PhysicsLayer.HUMANS; // mobs detecting for towers // ^ fix this private static final String STOW = "wanderStart"; @@ -33,13 +35,15 @@ public class MobMeleeAttackTask extends DefaultTask implements PriorityTask { private Fixture target; private final int priority; + private final float maxRange; + private Vector2 mobPosition = new Vector2(10f,10f); private final Vector2 maxRangePosition = new Vector2(); private final PhysicsEngine physics; private GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); - private static final long DELAY = 1000; // delay between shots + private final long delay = 1000; // delay between shots private long startTime; private enum STATE { @@ -52,8 +56,9 @@ private enum STATE { * @param priority Task priority when targets are detected (0 when nothing detected). Must be a positive integer. * @param maxRange Maximum effective range of the weapon mob. This determines the detection distance of targets */ - public MobMeleeAttackTask(int priority) { + public MobMeleeAttackTask(int priority, float maxRange) { this.priority = priority; + this.maxRange = maxRange; startTime = 0; physics = ServiceLocator.getPhysicsService().getPhysics(); @@ -67,11 +72,11 @@ public MobMeleeAttackTask(int priority) { public void start() { super.start(); startTime = timeSource.getTime(); - Vector2 mobPosition = owner.getEntity().getCenterPosition(); + this.mobPosition = owner.getEntity().getCenterPosition(); this.maxRangePosition.set(0, mobPosition.y); //owner.getEntity().getEvents().trigger(IDLE); endTime = timeSource.getTime() + (INTERVAL * 500); -// owner.getEntity().getEvents().trigger(FIRING); +// owner.getEntity().getEvents().trigger("shootStart"); } /** @@ -80,11 +85,14 @@ public void start() { */ @Override public void update() { - updateMobState(); - - if (mobState == STATE.STOW) { - status = Status.FINISHED; - } + + if(!owner.getEntity().getComponent(AITaskComponent.class).freezed) + { + updateMobState(); + if (mobState == STATE.STOW) { + status = Status.FINISHED; + } + } } /** @@ -92,62 +100,64 @@ public void update() { * triggers the appropriate events corresponding to the STATE enum. */ public void updateMobState() { - switch (mobState) { - - case IDLE -> { - if (isTargetVisible()) { - // targets detected in idle mode - start deployment - owner.getEntity().getEvents().trigger(DEPLOY); - mobState = STATE.DEPLOY; - } - } - - case DEPLOY -> { - // currently deploying, - if (isTargetVisible() || this.meleeOrProjectile() != null) { - owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(false); - this.owner.getEntity().getEvents().trigger(FIRING); - mobState = STATE.FIRING; - } else { - this.owner.getEntity().getEvents().trigger(STOW); - mobState = STATE.STOW; - } - } - - case FIRING -> { - // targets gone or cannot be attacked - stop firing - if (!isTargetVisible() || this.meleeOrProjectile() == null) { - this.owner.getEntity().getEvents().trigger(STOW); - mobState = STATE.STOW; - } else if (this.meleeOrProjectile() instanceof Melee) { - TouchAttackComponent attackComp = owner.getEntity().getComponent(TouchAttackComponent.class); - HitboxComponent hitboxComp = owner.getEntity().getComponent(HitboxComponent.class); - attackComp.onCollisionStart(hitboxComp.getFixture(), target); - this.owner.getEntity().getEvents().trigger(FIRING); - } else { - Entity newProjectile = ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)); - newProjectile.setPosition(owner.getEntity().getPosition().x, owner.getEntity().getPosition().y); - newProjectile.setScale(-0.0f, 0.0f); - ServiceLocator.getEntityService().register(newProjectile); - -// System.out.printf("ANIMATION: " + owner.getEntity().getComponent(AnimationRenderComponent.class).getCurrentAnimation() + "\n"); - this.owner.getEntity().getEvents().trigger(FIRING); - mobState = STATE.STOW; - } - owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(true); - } - - case STOW -> { - // currently stowing - if (isTargetVisible()) { - owner.getEntity().getEvents().trigger(DEPLOY); - mobState = STATE.DEPLOY; - } else { - owner.getEntity().getEvents().trigger(IDLE); - mobState = STATE.IDLE; - } - } - } + switch (mobState) { + case IDLE -> { + if (isTargetVisible()) { + // targets detected in idle mode - start deployment + owner.getEntity().getEvents().trigger(DEPLOY); + mobState = STATE.DEPLOY; + } + } + + case DEPLOY -> { + // currently deploying, + if (isTargetVisible() || this.meleeOrProjectile() != null) { + owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(false); + this.owner.getEntity().getEvents().trigger(FIRING); + mobState = STATE.FIRING; + } else { + this.owner.getEntity().getEvents().trigger(STOW); + mobState = STATE.STOW; + } + } + + case FIRING -> { + // targets gone or cannot be attacked - stop firing + if (!isTargetVisible() || this.meleeOrProjectile() == null) { + this.owner.getEntity().getEvents().trigger(STOW); + mobState = STATE.STOW; + } else { + if (this.meleeOrProjectile() instanceof Melee) { + TouchAttackComponent attackComp = owner.getEntity().getComponent(TouchAttackComponent.class); + HitboxComponent hitboxComp = owner.getEntity().getComponent(HitboxComponent.class); + attackComp.onCollisionStart(hitboxComp.getFixture(), target); + this.owner.getEntity().getEvents().trigger("shootStart"); + } else { + Entity newProjectile = ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x), (float) (owner.getEntity().getPosition().y)); + newProjectile.setScale(-0.0f, 0.0f); + ServiceLocator.getEntityService().register(newProjectile); + + // System.out.printf("ANIMATION: " + owner.getEntity().getComponent(AnimationRenderComponent.class).getCurrentAnimation() + "\n"); + this.owner.getEntity().getEvents().trigger(FIRING); + mobState = STATE.STOW; + } + } + owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(true); + + } + + case STOW -> { + // currently stowing + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(DEPLOY); + mobState = STATE.DEPLOY; + } else { + owner.getEntity().getEvents().trigger(IDLE); + mobState = STATE.IDLE; + } + } + } } /** @@ -169,7 +179,29 @@ public void stop() { */ @Override public int getPriority() { - if ((startTime + DELAY) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { + if (status == Status.ACTIVE) { + return getActivePriority(); + } + return getInactivePriority(); + } + + /** + * Fetches the active priority of the Task if a target is visible. + * @return (int) active priority if a target is visible, -1 otherwise + */ + private int getActivePriority() { + if ((startTime + delay) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { + return priority; + } + return -1; + } + + /** + * Fetches the inactive priority of the Task if a target is not visible. + * @return (int) -1 if a target is not visible, active priority otherwise + */ + private int getInactivePriority() { + if ((startTime + delay) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { return priority; } return -1; @@ -181,7 +213,7 @@ public int getPriority() { */ private boolean isTargetVisible() { Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 100f, owner.getEntity().getPosition().y - 2f); - return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET_LAYER, hit); + return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET, hit); } /** @@ -209,6 +241,6 @@ private Weapon meleeOrProjectile() { private void setTarget() { Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 100f, owner.getEntity().getPosition().y - 2f); - target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET_LAYER); + target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET); } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobRangedAttackTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobRangedAttackTask.java index 021419a05..35eb230fc 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobRangedAttackTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobRangedAttackTask.java @@ -16,13 +16,17 @@ import com.csse3200.game.physics.raycast.RaycastHit; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; - +import com.csse3200.game.ai.tasks.AITaskComponent; +import com.csse3200.game.components.npc.FireWormAnimationController; +import com.csse3200.game.components.npc.WizardAnimationController; +import com.csse3200.game.components.npc.WaterQueenAnimationController; +import com.csse3200.game.components.ProjectileEffects; /** * Task that allows mobs to shoot projectiles or melee attack towers */ public class MobRangedAttackTask extends DefaultTask implements PriorityTask { private static final int INTERVAL = 1; // time interval to scan for towers in - private static final short TARGET_LAYER = PhysicsLayer.HUMANS; // mobs detecting for towers + private static final short TARGET = PhysicsLayer.HUMANS; // mobs detecting for towers // ^ fix this private static final String STOW = "wanderStart"; @@ -33,13 +37,15 @@ public class MobRangedAttackTask extends DefaultTask implements PriorityTask { private Fixture target; private final int priority; + private final float maxRange; + private Vector2 mobPosition = new Vector2(10f,10f); private final Vector2 maxRangePosition = new Vector2(); private final PhysicsEngine physics; private GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); - private static final long DELAY = 1000; // delay between shots + private final long delay = 1000; // delay between shots private long startTime; private enum STATE { @@ -50,9 +56,11 @@ private enum STATE { /** * @param priority Task priority when targets are detected (0 when nothing detected). Must be a positive integer. + * @param maxRange Maximum effective range of the weapon mob. This determines the detection distance of targets */ - public MobRangedAttackTask(int priority) { + public MobRangedAttackTask(int priority, float maxRange) { this.priority = priority; + this.maxRange = maxRange; startTime = 0; physics = ServiceLocator.getPhysicsService().getPhysics(); @@ -66,7 +74,7 @@ public MobRangedAttackTask(int priority) { public void start() { super.start(); startTime = timeSource.getTime(); - Vector2 mobPosition = owner.getEntity().getCenterPosition(); + this.mobPosition = owner.getEntity().getCenterPosition(); this.maxRangePosition.set(0, mobPosition.y); //owner.getEntity().getEvents().trigger(IDLE); endTime = timeSource.getTime() + (INTERVAL * 500); @@ -79,11 +87,14 @@ public void start() { */ @Override public void update() { - updateMobState(); + if(!owner.getEntity().getComponent(AITaskComponent.class).freezed) + { + updateMobState(); - if (mobState == STATE.STOW) { - status = Status.FINISHED; - } + if (mobState == STATE.STOW) { + status = Status.FINISHED; + } + } } /** @@ -118,28 +129,43 @@ public void updateMobState() { if (!isTargetVisible() || this.meleeOrProjectile() == null) { this.owner.getEntity().getEvents().trigger(STOW); mobState = STATE.STOW; - } else if (this.meleeOrProjectile() instanceof Melee) { - TouchAttackComponent attackComp = owner.getEntity().getComponent(TouchAttackComponent.class); - HitboxComponent hitboxComp = owner.getEntity().getComponent(HitboxComponent.class); - attackComp.onCollisionStart(hitboxComp.getFixture(), target); - Entity newProjectile = ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)); - newProjectile.setPosition(owner.getEntity().getPosition().x, owner.getEntity().getPosition().y); - newProjectile.setScale(-1f, 1f); - ServiceLocator.getEntityService().register(newProjectile); - - // System.out.printf("ANIMATION: " + owner.getEntity().getComponent(AnimationRenderComponent.class).getCurrentAnimation() + "\n"); - this.owner.getEntity().getEvents().trigger(FIRING); } else { - Entity newProjectile = ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)); - newProjectile.setPosition(owner.getEntity().getPosition().x, owner.getEntity().getPosition().y); - newProjectile.setScale(-1f, 1f); - ServiceLocator.getEntityService().register(newProjectile); + Entity newProjectile = (owner.getEntity().getComponent(FireWormAnimationController.class)!=null)? + ProjectileFactory.createEffectProjectile(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f), ProjectileEffects.BURN, false) + : ((owner.getEntity().getComponent(WaterQueenAnimationController.class)!=null)? + ProjectileFactory.createComboSnowBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f), false) + : ((owner.getEntity().getComponent(WizardAnimationController.class)!=null)? + ProjectileFactory.createEffectProjectile(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f), ProjectileEffects.STUN, false) + : ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)))); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x), (float) (owner.getEntity().getPosition().y)); + newProjectile.setScale(-1f, 1f); + Entity newProjectile1 = (owner.getEntity().getComponent(FireWormAnimationController.class)!=null)? + ProjectileFactory.createPierceFireBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)) + : ((owner.getEntity().getComponent(WaterQueenAnimationController.class)!=null)? + ProjectileFactory.createFireworks(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)) + : ((owner.getEntity().getComponent(WizardAnimationController.class)!=null)? + ProjectileFactory.createRicochetFireball(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f), 3) + : ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)))); + newProjectile1.setPosition((float) (owner.getEntity().getPosition().x), (float) (owner.getEntity().getPosition().y)); + newProjectile1.setScale(-1f, 1f); + ServiceLocator.getEntityService().register(newProjectile1); + ServiceLocator.getEntityService().register(newProjectile); + + if (this.meleeOrProjectile() instanceof Melee) { + TouchAttackComponent attackComp = owner.getEntity().getComponent(TouchAttackComponent.class); + HitboxComponent hitboxComp = owner.getEntity().getComponent(HitboxComponent.class); + attackComp.onCollisionStart(hitboxComp.getFixture(), target); // System.out.printf("ANIMATION: " + owner.getEntity().getComponent(AnimationRenderComponent.class).getCurrentAnimation() + "\n"); - this.owner.getEntity().getEvents().trigger(FIRING); - mobState = STATE.STOW; + this.owner.getEntity().getEvents().trigger(FIRING); + } else { + // System.out.printf("ANIMATION: " + owner.getEntity().getComponent(AnimationRenderComponent.class).getCurrentAnimation() + "\n"); + this.owner.getEntity().getEvents().trigger(FIRING); + mobState = STATE.STOW; + } } owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(true); + } case STOW -> { @@ -174,7 +200,29 @@ public void stop() { */ @Override public int getPriority() { - if ((startTime + DELAY) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { + if (status == Status.ACTIVE) { + return getActivePriority(); + } + return getInactivePriority(); + } + + /** + * Fetches the active priority of the Task if a target is visible. + * @return (int) active priority if a target is visible, -1 otherwise + */ + private int getActivePriority() { + if ((startTime + delay) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { + return priority; + } + return -1; + } + + /** + * Fetches the inactive priority of the Task if a target is not visible. + * @return (int) -1 if a target is not visible, active priority otherwise + */ + private int getInactivePriority() { + if ((startTime + delay) < timeSource.getTime() && isTargetVisible() && this.meleeOrProjectile() != null) { return priority; } return -1; @@ -186,7 +234,7 @@ public int getPriority() { */ private boolean isTargetVisible() { Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 100f, owner.getEntity().getPosition().y - 2f); - return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET_LAYER, hit); + return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET, hit); } /** @@ -214,6 +262,6 @@ private Weapon meleeOrProjectile() { private void setTarget() { Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 100f, owner.getEntity().getPosition().y - 2f); - target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET_LAYER); + target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET); } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobShootTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobShootTask.java index 2453c4941..e44abeea2 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobShootTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobShootTask.java @@ -12,13 +12,15 @@ import com.csse3200.game.physics.raycast.RaycastHit; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.ai.tasks.AITaskComponent; +import com.csse3200.game.components.npc.XenoAnimationController; /** * Task that allows mobs to shoot projectiles or melee attack towers */ public class MobShootTask extends DefaultTask implements PriorityTask { private static final int INTERVAL = 1; // time interval to scan for towers in - private static final short TARGET_LAYER = PhysicsLayer.HUMANS; // mobs detecting for towers + private static final short TARGET = PhysicsLayer.HUMANS; // mobs detecting for towers // ^ fix this private static final String WALKING = "wanderStart"; @@ -29,13 +31,15 @@ public class MobShootTask extends DefaultTask implements PriorityTask { private Fixture target; private final int priority; + private final float maxRange; + private Vector2 mobPosition = new Vector2(10f,10f); private final Vector2 maxRangePosition = new Vector2(); private final PhysicsEngine physics; private GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); - private static final long DELAY = 1000; // delay between shots + private final long delay = 1000; // delay between shots private long startTime; private enum STATE { @@ -46,9 +50,11 @@ private enum STATE { /** * @param priority Task priority when targets are detected (0 when nothing detected). Must be a positive integer. + * @param maxRange Maximum effective range of the weapon mob. This determines the detection distance of targets */ - public MobShootTask(int priority) { + public MobShootTask(int priority, float maxRange) { this.priority = priority; + this.maxRange = maxRange; startTime = 0; physics = ServiceLocator.getPhysicsService().getPhysics(); @@ -62,7 +68,7 @@ public MobShootTask(int priority) { public void start() { super.start(); startTime = timeSource.getTime(); - Vector2 mobPosition = owner.getEntity().getCenterPosition(); + this.mobPosition = owner.getEntity().getCenterPosition(); this.maxRangePosition.set(0, mobPosition.y); //owner.getEntity().getEvents().trigger(IDLE); endTime = timeSource.getTime() + (INTERVAL * 500); @@ -75,11 +81,14 @@ public void start() { */ @Override public void update() { - updateMobState(); - - if (mobState == STATE.WALKING) { - status = Status.FINISHED; - } + if(!owner.getEntity().getComponent(AITaskComponent.class).freezed) + { + updateMobState(); + + if (mobState == STATE.WALKING) { + status = Status.FINISHED; + } + } } /** @@ -99,7 +108,7 @@ public void updateMobState() { case DEPLOY -> { // currently deploying, - if (isTargetVisible()) { + if (isTargetVisible() != false) { owner.getEntity().getComponent(PhysicsMovementComponent.class).setEnabled(false); this.owner.getEntity().getEvents().trigger(FIRING); mobState = STATE.FIRING; @@ -111,13 +120,13 @@ public void updateMobState() { case FIRING -> { // targets gone or cannot be attacked - stop firing - if (isTargetVisible()) { + if (!isTargetVisible() == false) { this.owner.getEntity().getEvents().trigger(WALKING); mobState = STATE.WALKING; } else { Entity newProjectile = ProjectileFactory.createMobBall(PhysicsLayer.HUMANS, new Vector2(0, owner.getEntity().getPosition().y), new Vector2(2f,2f)); - newProjectile.setPosition(owner.getEntity().getPosition().x, owner.getEntity().getPosition().y); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x), (float) (owner.getEntity().getPosition().y)); newProjectile.setScale(-1f, 1f); ServiceLocator.getEntityService().register(newProjectile); @@ -163,7 +172,29 @@ public void stop() { */ @Override public int getPriority() { - if ((startTime + DELAY) < timeSource.getTime() && isTargetVisible()) { + if (status == Status.ACTIVE) { + return getActivePriority(); + } + return getInactivePriority(); + } + + /** + * Fetches the active priority of the Task if a target is visible. + * @return (int) active priority if a target is visible, -1 otherwise + */ + private int getActivePriority() { + if ((startTime + delay) < timeSource.getTime() && isTargetVisible() != false) { + return priority; + } + return -1; + } + + /** + * Fetches the inactive priority of the Task if a target is not visible. + * @return (int) -1 if a target is not visible, active priority otherwise + */ + private int getInactivePriority() { + if ((startTime + delay) < timeSource.getTime() && isTargetVisible() != false) { return priority; } return -1; @@ -175,7 +206,7 @@ public int getPriority() { */ private boolean isTargetVisible() { Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); - return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET_LAYER, hit); + return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET, hit); } /** @@ -203,6 +234,6 @@ private boolean isTargetVisible() { private void setTarget() { Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); - target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET_LAYER); + target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET); } } 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 bd150803f..43610dd61 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,331 +1,703 @@ -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; -import com.csse3200.game.physics.components.PhysicsMovementComponent; -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; - -/** - * The AI Task for all general mobs. This task handles the sequencing for melee - * and ranged mobs as well as animations for all mobs. Its sequence is based on - * whether the mob is a melee or ranged mob which dictates its attack method. - */ -public class MobTask extends DefaultTask implements PriorityTask { - - // Constants - private static final int PRIORITY = 3; - private static final Vector2 MELEE_MOB_SPEED = new Vector2(0.7f,0.7f); - private static final Vector2 MELEE_RANGE_SPEED = new Vector2(0.5f,0.5f); - 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 = 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; - private MovementTask movementTask; - private Entity target; - private GameTime gameTime; - private long lastTimeAttacked; - private long dodgeEndTime; - - // Flags - boolean melee; - boolean runFlag = false; - boolean meleeFlag = false; - boolean targetInRange = false; - boolean rangeAttackFlag = false; - boolean meleeAttackFlag = false; - boolean deathFlag = false; - boolean canDodge = false; - - // Enums - private enum State { - RUN, ATTACK, DEATH, DEFAULT, DODGE - } - - /** - * constructor for the mob - * @param mobType type of mob it is - */ - public MobTask(MobType mobType) { - this.mobType = mobType; - gameTime = ServiceLocator.getTimeSource(); - } - - /** - * constructor for the mob - * @param mobType type of mob it is - * @param canDodge ability to dodge projectiles - */ - public MobTask(MobType mobType, boolean canDodge) { - this.mobType = mobType; - gameTime = ServiceLocator.getTimeSource(); - this.canDodge = true; - } - - /** - * starts general mob sequence, starts its movement task and initialises - * some of its variables - */ - @Override - public void start() { - super.start(); - mob = owner.getEntity(); - animation = mob.getComponent(AnimationRenderComponent.class); - melee = mobType.isMelee(); - - movementTask = new MovementTask(new Vector2(0f, mob.getPosition().y)); - movementTask.create(owner); - movementTask.start(); - runFlag = true; - changeState(State.RUN); - lastTimeAttacked = gameTime.getTime(); - dodgeEndTime = gameTime.getTime(); - - 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); - } - } - - /** - * handles the sequencing of melee and range mobs and detects death state - */ - @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)) { - // 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 - } - - switch (state) { - case RUN -> { - if (runFlag) { - movementTask.start(); - animate(); - runFlag = false; - } - if (melee && enemyDetected() && gameTime.getTime() - lastTimeAttacked >= MELEE_ATTACK_SPEED) { - changeState(State.ATTACK); - meleeAttackFlag = true; - } else if (gameTime.getTime() - lastTimeAttacked >= RANGE_ATTACK_SPEED) { - changeState(State.ATTACK); - rangeAttackFlag = true; - } - } - case ATTACK -> { - if (melee && meleeAttackFlag) { - movementTask.stop(); - animate(); - meleeAttack(); - meleeAttackFlag = false; - } else if (!melee && rangeAttackFlag) { - movementTask.stop(); - animate(); - rangeAttack(); - rangeAttackFlag = false; - } - if (animation.isFinished()) { - changeState(State.RUN); - runFlag = true; - } - } - case DODGE -> { - if (animation.isFinished()) { - movementTask.start(); - changeState(State.RUN); - animate(); - runFlag = true; - } - } - } - } - - /** - * handles animation for all states and all possible mobs - */ - private void animate() { - switch (state) { - case RUN -> owner.getEntity().getEvents().trigger("mob_walk"); - case ATTACK -> owner.getEntity().getEvents().trigger("mob_attack"); - case DEATH -> { - 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"); - } - } - - /** - * Changes the state of the mob. - * - * @param state state to change current state to - */ - private void changeState(State state) { - this.state = state; - } - - /** - * detects if there's an enemy within range of 1 to the left of it - * @return if there's an enemy in front of the mob or not - */ - private boolean enemyDetected() { - // if there's an entity within x of - 1 of mob - Entity targetInFront = ServiceLocator.getEntityService().getEntityAtPosition( - mob.getPosition().x - MELEE_ATTACK_RANGE, mob.getPosition().y); - if (targetInFront == null) { - return false; - } - - // layer checking - HitboxComponent targetHitbox = targetInFront.getComponent(HitboxComponent.class); - if (targetHitbox == null) { - return false; - } - if (PhysicsLayer.contains(PhysicsLayer.HUMANS, targetHitbox.getLayer())) { - this.target = targetInFront; - return true; - } - return false; - } - - /** - * hits the target directly in front of it - */ - private void meleeAttack() { - // toggle melee flag off - meleeFlag = false; - - // check if target is null or not in range - if (target == null) { - return; - } - CombatStatsComponent targetCombatStats = target.getComponent(CombatStatsComponent.class); - targetCombatStats.hit(MELEE_DAMAGE); - Timer.schedule(new Timer.Task() { - @Override - public void run() { - if (!targetInRange) { - return; // stop if target in range - } - meleeFlag = true; // toggle melee flag off - } - }, MELEE_ATTACK_SPEED); - } - - /** - * Shoots a fireball projectile and updates lastTimeAttacked - */ - private void rangeAttack() { - Vector2 destination = new Vector2(0, mob.getPosition().y); - Entity projectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.HUMANS, destination, - new Vector2(2, 2), ProjectileEffects.FIREBALL, false); - projectile.setPosition(mob.getPosition()); - projectile.setScale(-1f, 1f); - ServiceLocator.getEntityService().register(projectile); - lastTimeAttacked = gameTime.getTime(); - } - - /** - * @return priority of task - */ - @Override - public int getPriority() { - return PRIORITY; - } - - /** - * Sets dodge flag of the mob - * - * @param dodgeFlag If true, mob dodges projectile. - */ - 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); - - } - - - - } -} + +package com.csse3200.game.components.tasks.MobTask; + +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.ProjectileFactory; +import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.components.HitboxComponent; +import com.csse3200.game.physics.components.PhysicsMovementComponent; +import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.GameTime; +import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.components.npc.ArcaneArcherAnimationController; + +/** + * The AI Task for all general mobs. This task handles the sequencing for melee + * and ranged mobs as well as animations for all mobs. Its sequence is based on + * whether the mob is a melee or ranged mob which dictates its attack method. + */ +public class MobTask extends DefaultTask implements PriorityTask { + + // Constants + private static final int PRIORITY = 3; + private static final Vector2 MELEE_MOB_SPEED = new Vector2(0.7f,0.7f); + private static final Vector2 MELEE_RANGE_SPEED = new Vector2(0.5f,0.5f); + 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 variables + private final MobType mobType; + private State state = State.DEFAULT; + private State prevState; + private Entity mob; + private AnimationRenderComponent animation; + private MovementTask movementTask; + private Entity target; + private GameTime gameTime; + private long lastTimeAttacked; + private long dodgeEndTime; + + // Flags + boolean melee; + boolean runFlag = false; + boolean meleeFlag = false; + boolean targetInRange = false; + boolean rangeAttackFlag = false; + boolean meleeAttackFlag = false; + boolean deathFlag = false; + boolean canDodge = false; + + // Enums + private enum State { + RUN, ATTACK, DEATH, DEFAULT, DODGE + } + + /** + * constructor for the mob + * @param mobType type of mob it is + */ + public MobTask(MobType mobType) { + this.mobType = mobType; + gameTime = ServiceLocator.getTimeSource(); + } + + /** + * constructor for the mob + * @param mobType type of mob it is + */ + public MobTask(MobType mobType, boolean canDodge) { + this.mobType = mobType; + gameTime = ServiceLocator.getTimeSource(); + this.canDodge = true; + } + + /** + * starts general mob sequence, starts its movement task and initialises + * some of its variables + */ + @Override + 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)); + movementTask.create(owner); + movementTask.start(); + runFlag = true; + changeState(State.RUN); + lastTimeAttacked = gameTime.getTime(); + dodgeEndTime = gameTime.getTime(); + + if (melee) { + mob.getComponent(PhysicsMovementComponent.class).setSpeed(MELEE_MOB_SPEED); + } else { + mob.getComponent(PhysicsMovementComponent.class).setSpeed(MELEE_RANGE_SPEED); + } + } + + /** + * handles the sequencing of melee and range mobs and detects death state + */ + @Override + public void update() { + + // death check + if (mob.getComponent(CombatStatsComponent.class).getHealth() <= 0 && !deathFlag) { + changeState(State.DEATH); + animate(); + movementTask.stop(); + deathFlag = true; + } else if (deathFlag && animation.isFinished()) { + mob.setFlagForDelete(true); + } + + // 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 + } + + switch (state) { + case RUN -> { + if (runFlag) { + movementTask.start(); + animate(); + runFlag = false; + } + if (melee) { + if (enemyDetected()) { + if (gameTime.getTime() - lastTimeAttacked >= MELEE_ATTACK_SPEED) { + changeState(State.ATTACK); + meleeAttackFlag = true; + } + } + } else { + if (gameTime.getTime() - lastTimeAttacked >= RANGE_ATTACK_SPEED) { + changeState(State.ATTACK); + rangeAttackFlag = true; + } + } + } + case ATTACK -> { + if (melee) { + if (meleeAttackFlag) { + movementTask.stop(); + animate(); + meleeAttack(); + meleeAttackFlag = false; + } + if (animation.isFinished()) { + movementTask.start(); + changeState(State.RUN); + runFlag = true; + } + } + if (!melee) { + if (rangeAttackFlag) { + movementTask.stop(); + animate(); + rangeAttack(); + rangeAttackFlag = false; + } + if (animation.isFinished()) { + movementTask.start(); + changeState(State.RUN); + runFlag = true; + } + } + } + case DODGE -> { + if (animation.isFinished()) { + movementTask.start(); + changeState(State.RUN); + animate(); + runFlag = true; + } + } + } + } + + /** + * handles animation for all states and all possible mobs + */ + private void animate() { + switch (state) { + case RUN -> owner.getEntity().getEvents().trigger("mob_walk"); + case ATTACK -> owner.getEntity().getEvents().trigger("mob_attack"); + case DEATH -> { + 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"); + } + // switch (mobType) { + // case SKELETON -> { + // switch (state) { + // case RUN -> owner.getEntity().getEvents().trigger("skeleton_walk"); + // case ATTACK -> owner.getEntity().getEvents().trigger("skeleton_attack"); + // case DEATH -> owner.getEntity().getEvents().trigger("skeleton_death"); + // case DEFAULT -> owner.getEntity().getEvents().trigger("skeleton_default"); + // } + // } + // case WIZARD -> { + // switch (state) { + // case RUN -> owner.getEntity().getEvents().trigger("wizard_run"); + // case ATTACK -> owner.getEntity().getEvents().trigger("wizard_attack"); + // case DEATH -> owner.getEntity().getEvents().trigger("wizard_death"); + // case DEFAULT -> owner.getEntity().getEvents().trigger("default"); + // } + // } + // case WATER_QUEEN -> { + // switch (state) { + // case RUN -> owner.getEntity().getEvents().trigger("water_queen_walk"); + // case ATTACK -> owner.getEntity().getEvents().trigger("water_queen_attack"); + // case DEATH -> owner.getEntity().getEvents().trigger("water_queen_death"); + // case DEFAULT -> owner.getEntity().getEvents().trigger("default"); + // } + // } + // case WATER_SLIME -> { + // switch (state) { + // case RUN -> owner.getEntity().getEvents().trigger("water_slime_walk"); + // case ATTACK -> owner.getEntity().getEvents().trigger("water_slime_attack"); + // case DEATH -> { + // owner.getEntity().getEvents().trigger("water_slime_death"); + // owner.getEntity().getEvents().trigger("splitDeath"); + // } + // case DEFAULT -> owner.getEntity().getEvents().trigger("default"); + // } + // } + // case FIRE_WORM -> { + // switch (state) { + // case RUN -> owner.getEntity().getEvents().trigger("fire_worm_walk"); + // case ATTACK -> owner.getEntity().getEvents().trigger("fire_worm_attack"); + // case DEATH -> owner.getEntity().getEvents().trigger("fire_worm_death"); + // case DEFAULT -> owner.getEntity().getEvents().trigger("default"); + // } + // } + // case DRAGON_KNIGHT -> { + // switch (state) { + // case RUN -> owner.getEntity().getEvents().trigger("dragon_knight_run"); + // case ATTACK -> owner.getEntity().getEvents().trigger("dragon_knight_attack"); + // case DEATH -> owner.getEntity().getEvents().trigger("dragon_knight_death"); + // case DEFAULT -> owner.getEntity().getEvents().trigger("default"); + // } + // } + // case COAT -> { + // switch (state) { + // case RUN -> owner.getEntity().getEvents().trigger("coat_run"); + // case ATTACK -> owner.getEntity().getEvents().trigger("coat_attack"); + // case DEATH -> owner.getEntity().getEvents().trigger("coat_death"); + // case DEFAULT -> owner.getEntity().getEvents().trigger("default"); + // } + // } + // } + } + + /** + * changes state of the mob + * @param state state to change current state to + */ + private void changeState(State state) { + prevState = this.state; + this.state = state; + } + + /** + * detects if there's an enemy within range of 1 to the left of it + * @return if there's an enemy in front of the mob or not + */ + private boolean enemyDetected() { + // if there's an entity within x of - 1 of mob + Entity target = ServiceLocator.getEntityService().getEntityAtPosition( + mob.getPosition().x - MELEE_ATTACK_RANGE, mob.getPosition().y); + if (target == null) { + return false; + } + + // layer checking + HitboxComponent targetHitbox = target.getComponent(HitboxComponent.class); + if (targetHitbox == null) { + return false; + } + if (PhysicsLayer.contains(PhysicsLayer.HUMANS, targetHitbox.getLayer())) { + this.target = target; + return true; + } + return false; + } + + /** + * hits the target directly in front of it + */ + private void meleeAttack() { + // toggle melee flag off + meleeFlag = false; + + // check if target is null or not in range + if (target == null) { + return; + } + CombatStatsComponent targetCombatStats = target.getComponent(CombatStatsComponent.class); + targetCombatStats.hit(MELEE_DAMAGE); + Timer.schedule(new Timer.Task() { + @Override + public void run() { + if (!targetInRange) { + return; // stop if target in range + } + meleeFlag = true; // toggle melee flag off + } + }, MELEE_ATTACK_SPEED); + if(owner.getEntity().getComponent(ArcaneArcherAnimationController.class)!=null) + { + Entity newProjectile = ProjectileFactory.createPierceArrow(PhysicsLayer.HUMANS, new Vector2(-100, owner.getEntity().getPosition().y), new Vector2(2f,2f)); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x), (float) (owner.getEntity().getPosition().y)); + newProjectile.setScale(1.3f, 1.3f); + ServiceLocator.getEntityService().register(newProjectile); + lastTimeAttacked = gameTime.getTime(); + } + } + + /** + * Shoots a fireball projectile and updates lastTimeAttacked + */ + private void rangeAttack() { + Vector2 destination = new Vector2(0, mob.getPosition().y); + Entity projectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.HUMANS, destination, + new Vector2(2, 2), ProjectileEffects.FIREBALL, false); + projectile.setPosition(mob.getPosition()); + projectile.setScale(-1f, 1f); + ServiceLocator.getEntityService().register(projectile); + lastTimeAttacked = gameTime.getTime(); + } + + /** + * @return priority of task + */ + @Override + public int getPriority() { + return PRIORITY; + } + /** + * Sets dodge flag of the mob + * + * @param dodgeFlag If true, mob dodges projectile. + */ + public void setDodge(boolean dodgeFlag) { + this.canDodge = dodgeFlag; + } +} +======= +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; +import com.csse3200.game.physics.components.PhysicsMovementComponent; +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; + +/** + * The AI Task for all general mobs. This task handles the sequencing for melee + * and ranged mobs as well as animations for all mobs. Its sequence is based on + * whether the mob is a melee or ranged mob which dictates its attack method. + */ +public class MobTask extends DefaultTask implements PriorityTask { + + // Constants + private static final int PRIORITY = 3; + private static final Vector2 MELEE_MOB_SPEED = new Vector2(0.7f,0.7f); + private static final Vector2 MELEE_RANGE_SPEED = new Vector2(0.5f,0.5f); + 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 = 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; + private MovementTask movementTask; + private Entity target; + private GameTime gameTime; + private long lastTimeAttacked; + private long dodgeEndTime; + + // Flags + boolean melee; + boolean runFlag = false; + boolean meleeFlag = false; + boolean targetInRange = false; + boolean rangeAttackFlag = false; + boolean meleeAttackFlag = false; + boolean deathFlag = false; + boolean canDodge = false; + + // Enums + private enum State { + RUN, ATTACK, DEATH, DEFAULT, DODGE + } + + /** + * constructor for the mob + * @param mobType type of mob it is + */ + public MobTask(MobType mobType) { + this.mobType = mobType; + gameTime = ServiceLocator.getTimeSource(); + } + + /** + * constructor for the mob + * @param mobType type of mob it is + * @param canDodge ability to dodge projectiles + */ + public MobTask(MobType mobType, boolean canDodge) { + this.mobType = mobType; + gameTime = ServiceLocator.getTimeSource(); + this.canDodge = true; + } + + /** + * starts general mob sequence, starts its movement task and initialises + * some of its variables + */ + @Override + public void start() { + super.start(); + mob = owner.getEntity(); + animation = mob.getComponent(AnimationRenderComponent.class); + melee = mobType.isMelee(); + + movementTask = new MovementTask(new Vector2(0f, mob.getPosition().y)); + movementTask.create(owner); + movementTask.start(); + runFlag = true; + changeState(State.RUN); + lastTimeAttacked = gameTime.getTime(); + dodgeEndTime = gameTime.getTime(); + + 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); + } + } + + /** + * handles the sequencing of melee and range mobs and detects death state + */ + @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)) { + // 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 + } + + switch (state) { + case RUN -> { + if (runFlag) { + movementTask.start(); + animate(); + runFlag = false; + } + if (melee && enemyDetected() && gameTime.getTime() - lastTimeAttacked >= MELEE_ATTACK_SPEED) { + changeState(State.ATTACK); + meleeAttackFlag = true; + } else if (gameTime.getTime() - lastTimeAttacked >= RANGE_ATTACK_SPEED) { + changeState(State.ATTACK); + rangeAttackFlag = true; + } + } + case ATTACK -> { + if (melee && meleeAttackFlag) { + movementTask.stop(); + animate(); + meleeAttack(); + meleeAttackFlag = false; + } else if (!melee && rangeAttackFlag) { + movementTask.stop(); + animate(); + rangeAttack(); + rangeAttackFlag = false; + } + if (animation.isFinished()) { + changeState(State.RUN); + runFlag = true; + } + } + case DODGE -> { + if (animation.isFinished()) { + movementTask.start(); + changeState(State.RUN); + animate(); + runFlag = true; + } + } + } + } + + /** + * handles animation for all states and all possible mobs + */ + private void animate() { + switch (state) { + case RUN -> owner.getEntity().getEvents().trigger("mob_walk"); + case ATTACK -> owner.getEntity().getEvents().trigger("mob_attack"); + case DEATH -> { + 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"); + } + } + + /** + * Changes the state of the mob. + * + * @param state state to change current state to + */ + private void changeState(State state) { + this.state = state; + } + + /** + * detects if there's an enemy within range of 1 to the left of it + * @return if there's an enemy in front of the mob or not + */ + private boolean enemyDetected() { + // if there's an entity within x of - 1 of mob + Entity targetInFront = ServiceLocator.getEntityService().getEntityAtPosition( + mob.getPosition().x - MELEE_ATTACK_RANGE, mob.getPosition().y); + if (targetInFront == null) { + return false; + } + + // layer checking + HitboxComponent targetHitbox = targetInFront.getComponent(HitboxComponent.class); + if (targetHitbox == null) { + return false; + } + if (PhysicsLayer.contains(PhysicsLayer.HUMANS, targetHitbox.getLayer())) { + this.target = targetInFront; + return true; + } + return false; + } + + /** + * hits the target directly in front of it + */ + private void meleeAttack() { + // toggle melee flag off + meleeFlag = false; + + // check if target is null or not in range + if (target == null) { + return; + } + CombatStatsComponent targetCombatStats = target.getComponent(CombatStatsComponent.class); + targetCombatStats.hit(MELEE_DAMAGE); + Timer.schedule(new Timer.Task() { + @Override + public void run() { + if (!targetInRange) { + return; // stop if target in range + } + meleeFlag = true; // toggle melee flag off + } + }, MELEE_ATTACK_SPEED); + } + + /** + * Shoots a fireball projectile and updates lastTimeAttacked + */ + private void rangeAttack() { + Vector2 destination = new Vector2(0, mob.getPosition().y); + Entity projectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.HUMANS, destination, + new Vector2(2, 2), ProjectileEffects.FIREBALL, false); + projectile.setPosition(mob.getPosition()); + projectile.setScale(-1f, 1f); + ServiceLocator.getEntityService().register(projectile); + lastTimeAttacked = gameTime.getTime(); + } + + /** + * @return priority of task + */ + @Override + public int getPriority() { + return PRIORITY; + } + + /** + * Sets dodge flag of the mob + * + * @param dodgeFlag If true, mob dodges projectile. + */ + 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/MobTask/MobType.java b/source/core/src/main/com/csse3200/game/components/tasks/MobTask/MobType.java index 335b2a7e7..92ea1027f 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobTask/MobType.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobTask/MobType.java @@ -1,25 +1,26 @@ -package com.csse3200.game.components.tasks.MobTask; - -public enum MobType { - SKELETON(true), - WIZARD(false), - WATER_QUEEN(false), - WATER_SLIME(true), - FIRE_WORM(false), - DRAGON_KNIGHT(true), - COAT(true), - NIGHT_BORNE(true), - ARCANE_ARCHER(false), - ROCKY(true), - NECROMANCER(true), - FIREWIZARD(true); - private boolean isMelee; - - MobType(boolean melee) { - this.isMelee = melee; - } - - public boolean isMelee() { - return isMelee; - } -} +package com.csse3200.game.components.tasks.MobTask; + +public enum MobType { + SKELETON(true), + WIZARD(false), + WATER_QUEEN(false), + WATER_SLIME(true), + FIRE_WORM(false), + DRAGON_KNIGHT(true), + COAT(true), + NIGHT_BORNE(true), + ARCANE_ARCHER(true), + ROCKY(true), + NECROMANCER(true), + FIREWIZARD(true), + XENO(true); + private boolean isMelee; + + MobType(boolean melee) { + this.isMelee = melee; + } + + public boolean isMelee() { + return isMelee; + } +} diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobWanderTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobWanderTask.java index e652ea84e..cafc083ed 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobWanderTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobWanderTask.java @@ -11,6 +11,8 @@ import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.csse3200.game.ai.tasks.AITaskComponent; +import com.csse3200.game.components.npc.WizardAnimationController; /** * Wander around by moving a random position within a range of the starting position. Wait a little @@ -19,17 +21,22 @@ public class MobWanderTask extends DefaultTask implements PriorityTask { private static final Logger logger = LoggerFactory.getLogger(MobWanderTask.class); + private final Vector2 wanderRange; private final float waitTime; private Vector2 startPos; private MovementTask movementTask; private WaitTask waitTask; private Task currentTask; private boolean isDead = false; + private Vector2 mobPosition; /** + * @param wanderRange Distance in X and Y the entity can move from its position when start() is + * called. * @param waitTime How long in seconds to wait between wandering. */ - public MobWanderTask(float waitTime) { + public MobWanderTask(Vector2 wanderRange, float waitTime) { + this.wanderRange = wanderRange; this.waitTime = waitTime; } @@ -52,50 +59,50 @@ public void start() { movementTask.start(); currentTask = movementTask; - - // this.owner.getEntity().getEvents().trigger("wanderStart"); } @Override public void update() { - - // Update the position of the mob - Vector2 mobPosition = owner.getEntity().getPosition(); - - // If the mob is at zero health, kill the mob, - // play the death animation and stop the task - // This method is the idea of Ahmad who very kindly helped with section, massive props to him for his help! - if (!isDead && Boolean.TRUE.equals(owner.getEntity().getComponent(CombatStatsComponent.class).isDead())) { - this.owner.getEntity().getEvents().trigger("dieStart"); - currentTask.stop(); - isDead = true; - ServiceLocator.getWaveService().updateEnemyCount(); - } - - // Check if the mob has finished death animation - else if (isDead && owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { - // Drop scrap at the mobs location - Entity scrap = DropFactory.createScrapDrop(); - scrap.setPosition(mobPosition.x, mobPosition.y); - ServiceLocator.getEntityService().register(scrap); - - // Delete the mob and update count for number of mobs remaining in the wave - owner.getEntity().setFlagForDelete(true); - - } - // If not dead, do normal things... - else if (!isDead) { - - if (currentTask.getStatus() != Status.ACTIVE) { - if (currentTask == movementTask) { - startWaiting(); - } else { - startMoving(); - } - } - currentTask.update(); - } + if(!owner.getEntity().getComponent(AITaskComponent.class).freezed) + { + // Update the position of the mob + mobPosition = owner.getEntity().getPosition(); + + // If the mob is at zero health, kill the mob, + // play the death animation and stop the task + // This method is the idea of Ahmad who very kindly helped with section, massive props to him for his help! + if (!isDead && owner.getEntity().getComponent(CombatStatsComponent.class).isDead()) { + this.owner.getEntity().getEvents().trigger("dieStart"); + currentTask.stop(); + isDead = true; + ServiceLocator.getWaveService().updateEnemyCount(); + } + + // Check if the mob has finished death animation + else if (isDead && owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) { + // Drop scrap at the mobs location + Entity scrap = DropFactory.createScrapDrop(); + scrap.setPosition(mobPosition.x,mobPosition.y); + ServiceLocator.getEntityService().register(scrap); + + // Delete the mob and update count for number of mobs remaining in the wave + owner.getEntity().setFlagForDelete(true); + + } + // If not dead, do normal things... + else if (!isDead) { + + if (currentTask.getStatus() != Status.ACTIVE) { + if (currentTask == movementTask) { + startWaiting(); + } else { + startMoving(); + } + } + currentTask.update(); + } + } } private void startWaiting() { 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 02d36a77c..96e412d5c 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,8 +13,6 @@ 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 @@ -33,7 +31,6 @@ 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(); @@ -55,7 +52,6 @@ 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(); } @@ -83,9 +79,6 @@ public void start() { public void update() { if (timeSource.getTime() >= endTime) { updateTowerState(); - if (towerState == STATE.ATTACK) { - endTime = timeSource.getTime() + round(fireRateInterval * 1000); - } endTime = timeSource.getTime() + (INTERVAL * 1000); } } 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 004ab84d8..4aa8b94ca 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,8 +13,6 @@ 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 @@ -39,7 +37,6 @@ 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; @@ -57,7 +54,6 @@ 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(); } @@ -85,11 +81,7 @@ public void start() { public void update() { if (timeSource.getTime() >= endTime) { updateTowerState(); - if (towerState == STATE.ATTACK) { - endTime = timeSource.getTime() + round(fireRateInterval * 1000); - } else { - endTime = timeSource.getTime() + (INTERVAL * 1000); - } + endTime = timeSource.getTime() + (INTERVAL * 1000); } } 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 5a1de08a2..b8c0cf5f8 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 @@ -175,6 +175,14 @@ 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 @@ -189,4 +197,12 @@ 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/TowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/TowerCombatTask.java index a882cd1bb..21a8ab5a6 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,6 +3,7 @@ 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; @@ -56,6 +57,7 @@ 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; @@ -182,7 +184,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(String.format("Changing fire rate to: %d", newInterval)); + logger.info("Changing fire rate to: %d", newInterval); fireRateInterval = 1 / ((float) newInterval / 5); } 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 1e2f3ff90..749647851 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,6 +4,8 @@ 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; @@ -41,7 +43,7 @@ public class WallTowerDestructionTask extends DefaultTask implements PriorityTas public enum STATE { IDLE, DEATH } - private STATE towerState = STATE.IDLE; + public STATE towerState = STATE.IDLE; /** * @param priority Task priority when targets are detected (0 when nothing is present) @@ -73,7 +75,6 @@ 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(); @@ -86,19 +87,22 @@ 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; } - // 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); + 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); + } } } } @@ -111,18 +115,9 @@ 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 3dd7a3124..0c044d89f 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,18 +4,28 @@ 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"; @@ -24,11 +34,18 @@ 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 @@ -47,11 +64,8 @@ public BombshipCombatTask(float maxRange) { @Override public void start() { super.start(); - - // Placeholder value for the Bombship's position. - Vector2 bombShipPosition = owner.getEntity().getCenterPosition(); + this.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); @@ -90,7 +104,9 @@ public void updateBombshipState() { owner.getEntity().getEvents().trigger(START); } } - default -> owner.getEntity().getEvents().trigger(DESTROY); // DESTROY + case DESTROY -> { + owner.getEntity().getEvents().trigger(DESTROY); + } } } @@ -101,6 +117,13 @@ 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 @@ -118,7 +141,32 @@ public int getPriority() { * @return true if a target is detected, false otherwise */ public boolean isEngineerDied() { - return true; + //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; } + */ } 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 faf62ba6c..63c611885 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,10 +4,12 @@ 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, @@ -15,6 +17,7 @@ * 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"; @@ -82,18 +85,28 @@ public void start() { */ @Override public void update() { + if (!isDestroyed) { + startDestroying(); + } + // Check if bombship has destroyed since last update if (!isDestroyed) { - doBombshipThings(); - startDestroying();; - currentTask.update(); + startDestroying(); } else if (isDestroyed && animator.isFinished()) { owner.getEntity().setFlagForDelete(true); } + + // otherwise doing engineer things since engineer is alive + else if (!isDestroyed){ + doBombshipThings(); + + currentTask.update(); + } } 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(); @@ -104,7 +117,6 @@ 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) @@ -125,6 +137,22 @@ 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. @@ -133,7 +161,6 @@ 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 a861a3a5c..38896b2b4 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,7 +10,6 @@ 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; @@ -141,8 +140,6 @@ public void update() { slimey.setScale(5f, 5f); ServiceLocator.getEntityService().register(slimey); demon.setFlagForDelete(true); - dropCurrency(); - } // detect half health @@ -498,19 +495,4 @@ 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 6b4410a1d..4b298c059 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,7 +9,6 @@ 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; @@ -72,7 +71,6 @@ 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() { @@ -116,7 +114,6 @@ public void update() { animate(); if (animation.isFinished()) { iceBaby.setFlagForDelete(true); - dropCurrency(); } } @@ -321,20 +318,4 @@ 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 1bc2db0c3..719c2436a 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,6 +1,5 @@ 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; @@ -10,8 +9,6 @@ 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. */ @@ -96,18 +93,10 @@ 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 - float dropX = bossPosition.x + offsetX; + Entity scrap = DropFactory.createScrapDrop(); + scrap.setPosition(bossPosition.x,bossPosition.y); + ServiceLocator.getEntityService().register(scrap.setScale(2,2)); - 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 92da2af17..97f7dacc4 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,12 +1,8 @@ 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 { @@ -31,8 +27,6 @@ public void update() { if (startFlag && owner.getEntity().getComponent(AnimationRenderComponent.class). isFinished()) { owner.getEntity().setFlagForDelete(true); - ServiceLocator.getGameEndService().updateEngineerCount(); - dropCurrency(); } } @@ -43,19 +37,4 @@ 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 cb3f27b8f..bf5e6c30c 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,7 +64,6 @@ 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 bf607a123..fe8cefae4 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,6 +1,5 @@ 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; @@ -9,7 +8,6 @@ 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; @@ -188,6 +186,4 @@ private void applyAoeDamage(Array targets, int damage) { public int getPriority() { return PRIORITY; } - - } 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 8ed009a12..efd00a117 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,6 +1,5 @@ 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; @@ -17,11 +16,6 @@ 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. @@ -72,7 +66,6 @@ void animateGoDown() { */ void animateAttackUp() { animator.startAnimation("attackUp"); - fireSingleSound.play(); } /** @@ -81,7 +74,6 @@ 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 3e9a3a785..3fcd566f5 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,9 +1,7 @@ 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. @@ -17,11 +15,6 @@ 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; /** @@ -43,8 +36,7 @@ void animateIdle() { animator.startAnimation(ECO_IDLE); } - void animateMove() { animator.startAnimation(ECO_MOVE); - ping.play();} + void animateMove() { animator.startAnimation(ECO_MOVE); } } \ 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 a2cd29c89..0bfe1fe11 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,11 +21,7 @@ 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"; - - 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); + //here we can add the sounds for the implemented animations AnimationRenderComponent animator; @@ -61,7 +57,6 @@ 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 e9ec5c653..cd701b0db 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,9 +1,7 @@ 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 @@ -12,11 +10,6 @@ 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. @@ -37,7 +30,6 @@ 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 f9018e0af..9daa39acb 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,9 +1,7 @@ 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. @@ -21,10 +19,7 @@ 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; /** @@ -53,7 +48,6 @@ 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 8210e7d73..1a197868b 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,19 +1,13 @@ 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; /** @@ -36,7 +30,6 @@ 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 1fc59068a..846d344dd 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,10 +18,7 @@ public class StunTowerAnimationController extends Component { private static final String ATTACK_ANIM = "attack"; private static final String DEATH_ANIM = "death"; - 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); + //further sounds can be added for the tower attacks/movement AnimationRenderComponent animator; @@ -50,7 +47,6 @@ 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 4ebfa2bb8..1f092dab5 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,9 +1,7 @@ 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 @@ -11,10 +9,6 @@ */ 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 @@ -49,7 +43,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 a7d07d076..e83210b48 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,21 +3,17 @@ 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(); @@ -33,11 +29,12 @@ 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 69624ad41..4f22bfaf5 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,15 +29,13 @@ 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/PredefinedWeapons.java b/source/core/src/main/com/csse3200/game/entities/PredefinedWeapons.java index 53e7e1af7..2f0c8d7b5 100644 --- a/source/core/src/main/com/csse3200/game/entities/PredefinedWeapons.java +++ b/source/core/src/main/com/csse3200/game/entities/PredefinedWeapons.java @@ -13,9 +13,15 @@ private PredefinedWeapons() { public static final Melee PUNCH = new Melee(3, 1, "air", 1, 1); public static final Melee AXE = new Melee(9, 3, "fire", 1, 1); public static final Melee KICK = new Melee(2, 1, "earth", 1, 1); + public static final Melee sword = new Melee(10, 4, "fire", 1, 1); + public static final Melee punch = new Melee(3, 1, "air", 1, 1); + public static final Melee axe = new Melee(9, 3, "fire", 1, 1); + public static final Melee kick = new Melee(2, 1, "earth", 1, 1); //TODO import defined projectiles for mobs public static final ProjectileConfig FIREBALL = new ProjectileConfig(); public static final ProjectileConfig FROSTBALL = new ProjectileConfig(); + public static final ProjectileConfig fireBall = new ProjectileConfig(); + public static final ProjectileConfig frostBall = new ProjectileConfig(); } 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 03530fef3..000000000 --- a/source/core/src/main/com/csse3200/game/entities/configs/BaseTowerConfigs.java +++ /dev/null @@ -1,105 +0,0 @@ -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 804e72d7d..3349a149c 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,40 +4,9 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class DroidTowerConfig { - private int health = 1; - private int baseAttack = 0; - private int cost = 1; - private float attackRate = 1; + public int health = 1; + public int baseAttack = 0; + public 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; - } - - /** - * Function for getting tower's attack rate - * @return The attack rate of this tower - */ - public float getAttackRate() { - return this.attackRate; - } + public float attackRate = 1; } 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 48af9db9d..cc5b75284 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,40 +1,9 @@ package com.csse3200.game.entities.configs; public class FireTowerConfig { - private int health = 1; - private int baseAttack = 0; - private int cost = 1; - private float attackRate = 1; + public int health = 1; + public int baseAttack = 0; + public 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; - } - - /** - * Function for getting tower's attack rate - * @return The attack rate of this tower - */ - public float getAttackRate() { - return this.attackRate; - } + public float attackRate = 1; } 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 dd345afae..c1bde5dd3 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,49 +1,9 @@ package com.csse3200.game.entities.configs; public class FireworksTowerConfig { - 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; - } + public int health = 1; + public int baseAttack = 0; + public int cost = 1; + public int attackRate =0; + public int incomeRate =0; } 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 c3e5c6f22..0eb826bcc 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,31 +1,8 @@ package com.csse3200.game.entities.configs; public class HealTowerConfig { - 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; - } + public int health = 1; + public int baseAttack = 0; + public int cost = 1; + //comment to commit message } 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 ed1500176..94845ae6e 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,49 +4,19 @@ * 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; - /** - * 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; - } + public float attackRate = 0; + public float incomeRate = 10; - /** - * 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 329b226c2..8baf1cb52 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,40 +1,7 @@ package com.csse3200.game.entities.configs; public class PierceTowerConfig { - 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; - } + public int health = 1; + public int baseAttack = 0; + public int cost = 1; } 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 07946bc4f..3a637c7e2 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,40 +1,7 @@ package com.csse3200.game.entities.configs; public class RicochetTowerConfig { - 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; - } + public int health = 1; + public int baseAttack = 0; + public int cost = 1; } 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 a84a1bb9e..adf01c4f4 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,40 +1,9 @@ package com.csse3200.game.entities.configs; public class StunTowerConfig { - private int health = 1; - private int baseAttack = 0; - private int cost = 1; - private float attackRate = 1; + public int health = 1; + public int baseAttack = 0; + public 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; - } - - /** - * Function for getting tower's attack rate - * @return The attack rate of this tower - */ - public float getAttackRate() { - return this.attackRate; - } + public float attackRate = 1; } 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 c6d82c1a1..9385fc512 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,40 +4,9 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class TNTTowerConfigs { - private int health = 1; - private int baseAttack = 0; - private int cost = 1; - private float attackRate = 1; + public int health = 1; + public int baseAttack = 0; + public 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; - } - - /** - * Function for getting tower's attack rate - * @return The attack rate of this tower - */ - public float getAttackRate() { - return this.attackRate; - } + public float attackRate = 1; } 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 82d1f00ee..59c830d4f 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,40 +4,9 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class WallTowerConfig { - private int health = 1; - private int baseAttack = 0; - private int cost = 1; - private float attackRate = 0; + public int health = 1; + public int baseAttack = 0; + public 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; - } - - /** - * Function for getting tower's attack rate - * @return The attack rate of this tower - */ - public float getAttackRate() { - return this.attackRate; - } + public float attackRate = 0; } 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 b1c123f39..7f0547769 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,40 +4,8 @@ * Defines a basic set of properties stored in entities config files to be loaded by Entity Factories. */ public class WeaponTowerConfig { - 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; - } + public int health = 1; + public int baseAttack = 0; + public int cost = 1; + public float attackRate = 1; } 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..c1b3f997a --- /dev/null +++ b/source/core/src/main/com/csse3200/game/entities/configs/baseTowerConfigs.java @@ -0,0 +1,18 @@ +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 f2e9a50a1..b96ad1e59 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,6 +11,7 @@ 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; @@ -19,6 +20,7 @@ /** * 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. @@ -29,16 +31,19 @@ * 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() { @@ -70,12 +75,17 @@ public static Entity createBombship() { * @return entity */ public static Entity createBaseshipNPC() { - 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)); + + + 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; } 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 136dba625..f42babb8a 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,7 +216,6 @@ 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 f4dab8d2b..a31a49fe0 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 @@ -1,668 +1,702 @@ -package com.csse3200.game.entities.factories; - -import com.badlogic.gdx.graphics.g2d.Animation; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.badlogic.gdx.math.Vector2; -import com.csse3200.game.ai.tasks.AITaskComponent; -import com.csse3200.game.components.CombatStatsComponent; -import com.csse3200.game.components.EffectComponent; -import com.csse3200.game.components.TouchAttackComponent; -import com.csse3200.game.components.npc.*; -import com.csse3200.game.components.tasks.MobDodgeTask; -import com.csse3200.game.components.tasks.MobMeleeAttackTask; -import com.csse3200.game.components.tasks.MobRangedAttackTask; -import com.csse3200.game.components.tasks.MobWanderTask; -import com.csse3200.game.components.tasks.MobTask.MobTask; -import com.csse3200.game.components.tasks.MobTask.MobType; -import com.csse3200.game.entities.Entity; -import com.csse3200.game.entities.Melee; -import com.csse3200.game.entities.PredefinedWeapons; -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; -import com.csse3200.game.physics.components.PhysicsMovementComponent; -import com.csse3200.game.rendering.AnimationRenderComponent; -import com.csse3200.game.rendering.TextureRenderComponent; -import com.csse3200.game.services.ServiceLocator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Currency; - -/** - * Factory to create non-playable character (NPC) entities with predefined components. - * - *

Each NPC entity type should have a creation method that returns a corresponding entity. - * Predefined entity properties can be loaded from configs stored as json files which are defined in - * "NPCConfigs". - * - *

If needed, this factory can be separated into more specific factories for entities with - * similar characteristics. - */ -public class NPCFactory { - private static final NPCConfigs configs = - FileLoader.readClass(NPCConfigs.class, "configs/NPCs.json"); - private static final String DEFAULT = "default"; - - /** - * Creates a ghost entity. - * - * @return entity - */ - public static Entity createGhost() { - Entity ghost = createMeleeBaseNPC(); - BaseEntityConfig config = configs.ghost; - /** - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/ghost.atlas", TextureAtlas.class)); - animator.addAnimation("angry_float", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("float", 0.1f, Animation.PlayMode.LOOP); - **/ - ghost - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(new TextureRenderComponent("images/mobs/satyr.png")); - - ghost.getComponent(TextureRenderComponent.class).scaleEntity(); - - return ghost; - } - - /** - * Creates a ghost king entity. - * - * @return entity - */ - public static Entity createGhostKing() { - Entity ghostKing = createMeleeBaseNPC(); - GhostKingConfig config = configs.ghostKing; - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/ghostKing.atlas", TextureAtlas.class)); - animator.addAnimation("float", 0.2f, Animation.PlayMode.LOOP); - animator.addAnimation("angry_float", 0.2f, Animation.PlayMode.LOOP); - - ghostKing - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - .addComponent(animator) - .addComponent(new GhostAnimationController()); - - ghostKing.getComponent(AnimationRenderComponent.class).scaleEntity(); - return ghostKing; - } - - /** - * Creates a fire worm entity. - * - * @return entity - */ - public static Entity createSkeleton(int health) { - Entity skeleton = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/skeleton.atlas", TextureAtlas.class)); - animator.addAnimation("skeleton_walk", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("skeleton_attack", 0.1f); - animator.addAnimation("skeleton_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.SKELETON)); - - skeleton - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new SkeletonAnimationController()) - .addComponent(aiTaskComponent); - - skeleton.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); - skeleton.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return skeleton; - } - - /** - * Creates a wizard entity. - * - * @return entity - */ - public static Entity createWizard(int health) { - Entity wizard = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/wizard.atlas", TextureAtlas.class)); - animator.addAnimation("wizard_run", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("wizard_attack", 0.1f); - animator.addAnimation("wizard_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.WIZARD)); - - wizard - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new WizardAnimationController()) - .addComponent(aiTaskComponent); - - wizard.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); - wizard.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return wizard; - } - /** - * Creates a water queen entity. - * - * @return entity - */ - public static Entity createWaterQueen(int health) { - Entity waterQueen = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/water_queen.atlas", TextureAtlas.class)); - animator.addAnimation("water_queen_walk", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("water_queen_attack", 0.1f); - animator.addAnimation("water_queen_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.WATER_QUEEN)); - - waterQueen - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new WaterQueenAnimationController()) - .addComponent(aiTaskComponent); - - waterQueen.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); - waterQueen.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return waterQueen; - } - /** - * Creates a water slime entity. - * - * @return entity - */ - public static Entity createBaseWaterSlime(int health) { - Entity waterSlime = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/water_slime.atlas", TextureAtlas.class)); - animator.addAnimation("water_slime_walk", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("water_slime_attack", 0.1f); - animator.addAnimation("water_slime_death", 0.2f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.WATER_SLIME)); - - waterSlime - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new WaterSlimeAnimationController()) - .addComponent(aiTaskComponent); - - waterSlime.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); - waterSlime.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return waterSlime; - } - /** - * Creates a fire worm entity. - * - * @return entity - */ - public static Entity createFireWorm(int health) { - Entity fireWorm = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/fire_worm.atlas", TextureAtlas.class)); - animator.addAnimation("fire_worm_walk", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("fire_worm_attack", 0.1f); - animator.addAnimation("fire_worm_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.FIRE_WORM)); - - fireWorm - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new FireWormAnimationController()) - .addComponent(aiTaskComponent); - - fireWorm.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); - fireWorm.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return fireWorm; - } - /** - * Creates a dragon Knight entity - * - * @return entity - */ - public static Entity createDragonKnight(int health) { - Entity dragonKnight = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/dragon_knight.atlas", TextureAtlas.class)); - animator.addAnimation("dragon_knight_run", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("dragon_knight_attack", 0.1f); - animator.addAnimation("dragon_knight_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.DRAGON_KNIGHT)); - - dragonKnight - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new DragonKnightAnimationController()) - .addComponent(aiTaskComponent); - - dragonKnight.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); - dragonKnight.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return dragonKnight; - } - - public static Entity createCoat(int health) { - Entity coat = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/coat.atlas", TextureAtlas.class)); - animator.addAnimation("coat_run", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("coat_attack", 0.1f); - animator.addAnimation("coat_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.COAT)); - - coat - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new CoatAnimationController()) - .addComponent(aiTaskComponent); - - coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); - coat.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return coat; - } - - public static Entity createNightBorne(int health) { - Entity coat = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/night_borne.atlas", TextureAtlas.class)); - animator.addAnimation("night_borne_run", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("night_borne_attack", 0.1f); - animator.addAnimation("night_borne_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.NIGHT_BORNE)); - - coat - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new NightBorneAnimationController()) - .addComponent(aiTaskComponent); - - coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); - coat.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return coat; - } - - public static Entity createRocky(int health) { - Entity coat = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/rocky.atlas", TextureAtlas.class)); - animator.addAnimation("rocky_move", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("rocky_attack", 0.1f); - animator.addAnimation("night_borne_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.NIGHT_BORNE)); - - coat - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new RockyAnimationController()) - .addComponent(aiTaskComponent); - - coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); - coat.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return coat; - } - - public static Entity createNecromancer(int health) { - Entity coat = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/necromancer.atlas", TextureAtlas.class)); - animator.addAnimation("necromancer_walk", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("necromancer_attack", 0.1f); - animator.addAnimation("necromancer_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.NECROMANCER)); - - coat - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new NecromancerAnimationController()) - .addComponent(aiTaskComponent); - - coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); - coat.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return coat; - } - - public static Entity createFirewizard(int health) { - Entity fireWizard = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/firewizard.atlas", TextureAtlas.class)); - animator.addAnimation("firewizard_move", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("firewizard_attack", 0.1f); - animator.addAnimation("firewizard_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.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(); - - return fireWizard; - } - - public static Entity createArcaneArcher(int health) { - Entity coat = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/arcane_archer.atlas", TextureAtlas.class)); - animator.addAnimation("arcane_archer_run", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("arcane_archer_attack", 0.1f); - animator.addAnimation("arcane_archer_death", 0.1f); - animator.addAnimation("arcane_archer_dodge", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.ARCANE_ARCHER)); - - coat - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new ArcaneArcherAnimationController()) - .addComponent(aiTaskComponent); - - coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); - coat.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return coat; - } - - public static Entity createGregRangeMob(int health) { - Entity fireWorm = createBaseNPC(); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/fire_worm.atlas", TextureAtlas.class)); - animator.addAnimation("fire_worm_walk", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("fire_worm_attack", 0.1f); - animator.addAnimation("fire_worm_death", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - - AITaskComponent aiTaskComponent = new AITaskComponent() - .addTask(new MobTask(MobType.FIRE_WORM)); - - fireWorm - .addComponent(new CombatStatsComponent(health, 0, drops)) - .addComponent(animator) - .addComponent(new FireWormAnimationController()) - .addComponent(aiTaskComponent); - - fireWorm.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); - fireWorm.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return fireWorm; - } - - - /** - * Creates a xeno grunt entity. - * - * @return entity - */ - public static Entity createXenoGrunt(int health) { - Entity xenoGrunt = createMeleeBaseNPC(); - BaseEnemyConfig config = configs.xenoGrunt; - ArrayList melee = new ArrayList<>(Arrays.asList(PredefinedWeapons.SWORD, PredefinedWeapons.KICK)); - // tester projectiles - ArrayList projectiles = new ArrayList<>(Arrays.asList(PredefinedWeapons.FIREBALL, PredefinedWeapons.FROSTBALL)); - ArrayList drops = new ArrayList<>(); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/mobs/xenoGrunt.atlas", TextureAtlas.class)); - animator.addAnimation("xeno_run", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("xeno_hurt", 0.1f, Animation.PlayMode.LOOP); - animator.addAnimation("xeno_shoot", 0.1f); - animator.addAnimation("xeno_melee_1", 0.1f); - animator.addAnimation("xeno_melee_2", 0.1f); - animator.addAnimation("xeno_die", 0.1f); - animator.addAnimation(DEFAULT, 0.1f); - xenoGrunt - .addComponent(new CombatStatsComponent(health, config.baseAttack, drops, melee, projectiles)) - .addComponent(animator) - .addComponent(new XenoAnimationController()); - - xenoGrunt.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); - xenoGrunt.getComponent(AnimationRenderComponent.class).scaleEntity(); - - return xenoGrunt; - } - - public static Entity createBaseNPC() { - Entity npc = - new Entity() - .addComponent(new PhysicsComponent()) - .addComponent(new PhysicsMovementComponent()) - .addComponent(new ColliderComponent()) - .addComponent(new EffectComponent(true)) - .addComponent(new HitboxComponent().setLayer(PhysicsLayer.NPC)) - .addComponent(new TouchAttackComponent(PhysicsLayer.HUMANS)); - PhysicsUtils.setScaledCollider(npc, 0.3f, 0.5f); - return npc; - } - - /** - * Creates a generic NPC to be used as a base entity by more specific NPC creation methods. - * - * @return entity - */ - public static Entity createMeleeBaseNPC() { - AITaskComponent aiComponent = - new AITaskComponent() - .addTask(new MobWanderTask(2f)) - .addTask(new MobMeleeAttackTask(2)); - - Entity npc = - new Entity() - .addComponent(new PhysicsComponent()) - .addComponent(new PhysicsMovementComponent()) - .addComponent(new ColliderComponent()) - .addComponent(new HitboxComponent().setLayer(PhysicsLayer.XENO)) - .addComponent(new TouchAttackComponent(PhysicsLayer.HUMANS)) - .addComponent(aiComponent); - PhysicsUtils.setScaledCollider(npc, 0.3f, 0.5f); - return npc; - } - /** - * Creates a generic NPC to be used as a base entity by more specific NPC creation methods. - * - * @return entity - */ - public static Entity createRangedBaseNPC() { - AITaskComponent aiComponent = - new AITaskComponent() - .addTask(new MobWanderTask(2f)) - .addTask(new MobRangedAttackTask(2)); - - Entity npc = - new Entity() - .addComponent(new PhysicsComponent()) - .addComponent(new PhysicsMovementComponent()) - .addComponent(new ColliderComponent()) - .addComponent(new HitboxComponent().setLayer(PhysicsLayer.XENO)) - .addComponent(new TouchAttackComponent(PhysicsLayer.HUMANS)) - .addComponent(aiComponent); - PhysicsUtils.setScaledCollider(npc, 0.3f, 0.5f); - return npc; - } - - private NPCFactory() { - throw new IllegalStateException("Instantiating static util class"); - } - - // * COW'S TESTING ARENA DONT TOUCH - public static Entity createSplittingXenoGrunt(int health) { - Entity splitXenoGrunt = createXenoGrunt(health) - // add the scaling yourself. can also scale the X and Y component, - // leading to some very interesting mob designs. - .addComponent(new SplitMoblings(MobType.WATER_SLIME, 7, 0.5f)) - .addComponent(new DodgingComponent(PhysicsLayer.PROJECTILE, 0.25f)); - - // * TEMPORARY TESTING FOR PROJECTILE DODGING - splitXenoGrunt.getComponent(AITaskComponent.class).addTask(new MobDodgeTask(MobType.DRAGON_KNIGHT, 5)); - // splitXenoGrunt.getComponent(AITaskComponent.class).addTask(new MobDodgeTask(new Vector2(2f, 2f), 2f, 5)); - return splitXenoGrunt; - } - - /** - * Create Splitting water slime - * - * @require - Entity to have a "splitDeath" - * @return Splitting water slime - */ - public static Entity createSplittingWaterSlime(int health) { - return createBaseWaterSlime(health).addComponent(new SplitMoblings(MobType.WATER_SLIME, 7, 0.5f)); - } - - /** - * Create Splitting water slime - * - * @require Entity to have a "splitDeath" - * @return Splitting Rocky - */ - public static Entity createSplittingRocky(int health) { - return createRocky(health).addComponent(new SplitMoblings(MobType.ROCKY, 7, 0.5f)); - } - - /** - * Create Splitting night borne - * - * @require Entity to have a "splitDeath" - * @return Splitting Night Borne - */ - public static Entity createSplittingNightBorne(int health) { - return createNightBorne(health).addComponent(new SplitMoblings(MobType.NIGHT_BORNE, 7, 0.5f)); - } - - /** - * Create a dodging Dragon Knight - * - * @return Dodging dragon knight - */ - public static Entity createDodgingDragonKnight(int health) { - Entity dodgeKnight = createDragonKnight(health); - - dodgeKnight.addComponent(new DodgingComponent(PhysicsLayer.PROJECTILE, 0.25f, 5f)); - dodgeKnight.getComponent(AITaskComponent.class).getTask(MobTask.class).setDodge(true); - // PhysicsUtils.setScaledCollider(dodgeKnight, 0.3f, 1f); - dodgeKnight.setScale(0.5f, 1.2f); - - return dodgeKnight; - } - - /** - * Create a dodging Arcane Archer - * - * @return Dodging arcane - */ - public static Entity createDodgingArcaneArcher(int health) { - Entity dodgeKnight = createArcaneArcher(health); - - dodgeKnight.addComponent(new DodgingComponent(PhysicsLayer.PROJECTILE, 0.25f)); - dodgeKnight.getComponent(AITaskComponent.class).getTask(MobTask.class).setDodge(true); - PhysicsUtils.setScaledCollider(dodgeKnight, 0.3f, 0.7f); - dodgeKnight.setScale(0.3f, 0.7f); - - return dodgeKnight; - } - - /** - * Creates a wizard that can deflect bullets - * @return Deflecting wizard - */ - public static Entity createDeflectWizard(int health) { - return createWizard(health).addComponent(new DeflectingComponent( - PhysicsLayer.PROJECTILE, PhysicsLayer.TOWER, 10)); - } - - /** - * Creates a wizard that can deflect bullets - * @return Deflecting firewizard - */ - public static Entity createDeflectFireWizard(int health) { - return createFirewizard(health).addComponent(new DeflectingComponent( - PhysicsLayer.PROJECTILE, PhysicsLayer.TOWER, 10)); - } -} - - +package com.csse3200.game.entities.factories; + +import com.badlogic.gdx.graphics.g2d.Animation; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.math.Vector2; +import com.csse3200.game.ai.tasks.AITaskComponent; +import com.csse3200.game.components.CombatStatsComponent; +import com.csse3200.game.components.TouchAttackComponent; +import com.csse3200.game.components.npc.*; +import com.csse3200.game.components.tasks.MobDodgeTask; +import com.csse3200.game.components.tasks.MobMeleeAttackTask; +import com.csse3200.game.components.tasks.MobRangedAttackTask; +import com.csse3200.game.components.tasks.MobTask.MobTask; +import com.csse3200.game.components.tasks.MobTask.MobType; +import com.csse3200.game.components.tasks.MobWanderTask; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.Melee; +import com.csse3200.game.entities.PredefinedWeapons; +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; +import com.csse3200.game.physics.components.PhysicsMovementComponent; +import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.rendering.TextureRenderComponent; +import com.csse3200.game.services.ServiceLocator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Currency; + +/** + * Factory to create non-playable character (NPC) entities with predefined components. + * + *

Each NPC entity type should have a creation method that returns a corresponding entity. + * Predefined entity properties can be loaded from configs stored as json files which are defined in + * "NPCConfigs". + * + *

If needed, this factory can be separated into more specific factories for entities with + * similar characteristics. + */ +public class NPCFactory { + private static final String DEFAULT = "default"; + private static final NPCConfigs configs = + FileLoader.readClass(NPCConfigs.class, "configs/NPCs.json"); + + /** + * Creates a ghost entity. + * + * @return entity + */ + public static Entity createGhost() { + Entity ghost = createMeleeBaseNPC(); + BaseEntityConfig config = configs.ghost; + /** + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/ghost.atlas", TextureAtlas.class)); + animator.addAnimation("angry_float", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("float", 0.1f, Animation.PlayMode.LOOP); + **/ + 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(); + + return ghost; + } + + /** + * Creates a ghost king entity. + * + * @return entity + */ + public static Entity createGhostKing() { + Entity ghostKing = createMeleeBaseNPC(); + GhostKingConfig config = configs.ghostKing; + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/ghostKing.atlas", TextureAtlas.class)); + animator.addAnimation("float", 0.2f, Animation.PlayMode.LOOP); + animator.addAnimation("angry_float", 0.2f, Animation.PlayMode.LOOP); + + ghostKing + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(animator) + .addComponent(new GhostAnimationController()); + + ghostKing.getComponent(AnimationRenderComponent.class).scaleEntity(); + return ghostKing; + } + + /** + * Creates a fire worm entity. + * + * @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<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/skeleton.atlas", TextureAtlas.class)); + animator.addAnimation("skeleton_walk", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("skeleton_attack", 0.1f); + animator.addAnimation("skeleton_death", 0.1f); + animator.addAnimation("skeleton_freeze", 0.1f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.SKELETON)); + + skeleton + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new SkeletonAnimationController()) + .addComponent(aiTaskComponent); + + skeleton.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); + skeleton.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return skeleton; + } + + /** + * Creates a wizard entity. + * + * @return entity + */ + public static Entity createWizard(int health) { + Entity wizard = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/wizard.atlas", TextureAtlas.class)); + animator.addAnimation("wizard_run", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("wizard_attack", 0.1f); + animator.addAnimation("wizard_death", 0.1f); + animator.addAnimation("wizard_freeze", 0.1f); + animator.addAnimation("default", 0.1f); + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.WIZARD)); + + wizard + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new WizardAnimationController()) + .addComponent(aiTaskComponent); + + wizard.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); + wizard.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return wizard; + } + /** + * Creates a water queen entity. + * + * @return entity + */ + public static Entity createWaterQueen(int health) { + Entity waterQueen = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/water_queen.atlas", TextureAtlas.class)); + animator.addAnimation("water_queen_walk", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("water_queen_attack", 0.1f); + animator.addAnimation("water_queen_death", 0.1f); + animator.addAnimation("water_queen_freeze", 0.1f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.WATER_QUEEN)); + + waterQueen + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new WaterQueenAnimationController()) + .addComponent(aiTaskComponent); + + waterQueen.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); + waterQueen.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return waterQueen; + } + /** + * Creates a water slime entity. + * + * @return entity + */ + public static Entity createBaseWaterSlime(int health) { + Entity waterSlime = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/water_slime.atlas", TextureAtlas.class)); + animator.addAnimation("water_slime_walk", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("water_slime_attack", 0.1f); + animator.addAnimation("water_slime_death", 0.2f); + animator.addAnimation("water_slime_freeze", 0.2f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.WATER_SLIME)); + + waterSlime + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new WaterSlimeAnimationController()) + .addComponent(aiTaskComponent); + + waterSlime.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); + waterSlime.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return waterSlime; + } + /** + * Creates a fire worm entity. + * + * @return entity + */ + public static Entity createFireWorm(int health) { + Entity fireWorm = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/fire_worm.atlas", TextureAtlas.class)); + animator.addAnimation("fire_worm_walk", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("fire_worm_attack", 0.1f); + animator.addAnimation("fire_worm_death", 0.1f); + animator.addAnimation("fire_worm_freeze", 0.1f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.FIRE_WORM)); + + fireWorm + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new FireWormAnimationController()) + .addComponent(aiTaskComponent); + + fireWorm.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); + fireWorm.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return fireWorm; + } + /** + * Creates a dragon Knight entity + * + * @return entity + */ + public static Entity createDragonKnight(int health) { + Entity dragonKnight = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/dragon_knight.atlas", TextureAtlas.class)); + animator.addAnimation("dragon_knight_run", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("dragon_knight_attack", 0.1f); + animator.addAnimation("dragon_knight_death", 0.1f); + animator.addAnimation("dragon_knight_freeze", 0.1f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.DRAGON_KNIGHT)); + + dragonKnight + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new DragonKnightAnimationController()) + .addComponent(aiTaskComponent); + + dragonKnight.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); + dragonKnight.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return dragonKnight; + } + + public static Entity createCoat(int health) { + Entity coat = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/coat.atlas", TextureAtlas.class)); + animator.addAnimation("coat_run", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("coat_attack", 0.1f); + animator.addAnimation("coat_death", 0.1f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.COAT)); + + coat + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new CoatAnimationController()) + .addComponent(aiTaskComponent); + + coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); + coat.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return coat; + } + + public static Entity createNightBorne(int health) { + Entity coat = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/night_borne.atlas", TextureAtlas.class)); + animator.addAnimation("night_borne_run", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("night_borne_attack", 0.1f); + animator.addAnimation("night_borne_death", 0.1f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.NIGHT_BORNE)); + + coat + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new NightBorneAnimationController()) + .addComponent(aiTaskComponent); + + coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); + coat.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return coat; + } + + public static Entity createRocky(int health) { + Entity coat = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/rocky.atlas", TextureAtlas.class)); + animator.addAnimation("rocky_move", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("rocky_attack", 0.1f); + animator.addAnimation("night_borne_death", 0.1f); + animator.addAnimation(DEFAULT, 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.NIGHT_BORNE)); + + coat + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new RockyAnimationController()) + .addComponent(aiTaskComponent); + + coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); + coat.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return coat; + } + + public static Entity createNecromancer(int health) { + Entity coat = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/necromancer.atlas", TextureAtlas.class)); + animator.addAnimation("necromancer_walk", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("necromancer_attack", 0.1f); + animator.addAnimation("necromancer_death", 0.1f); + animator.addAnimation(DEFAULT, 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.NECROMANCER)); + + coat + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new NecromancerAnimationController()) + .addComponent(aiTaskComponent); + + coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); + coat.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return coat; + } + + public static Entity createFirewizard(int health) { + Entity fireWizard = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/firewizard.atlas", TextureAtlas.class)); + animator.addAnimation("firewizard_move", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("firewizard_attack", 0.1f); + animator.addAnimation("firewizard_death", 0.1f); + animator.addAnimation(DEFAULT, 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.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(); + + return fireWizard; + } + + public static Entity createArcaneArcher(int health) { + Entity coat = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/arcane_archer.atlas", TextureAtlas.class)); + animator.addAnimation("arcane_archer_run", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("arcane_archer_attack", 0.1f); + animator.addAnimation("arcane_archer_death", 0.1f); + animator.addAnimation("arcane_archer_dodge", 0.1f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.ARCANE_ARCHER)); + + coat + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new ArcaneArcherAnimationController()) + .addComponent(aiTaskComponent); + + coat.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); + coat.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return coat; + } + + public static Entity createGregRangeMob(int health) { + Entity fireWorm = createBaseNPC(); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/fire_worm.atlas", TextureAtlas.class)); + animator.addAnimation("fire_worm_walk", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("fire_worm_attack", 0.1f); + animator.addAnimation("fire_worm_death", 0.1f); + animator.addAnimation("default", 0.1f); + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new MobTask(MobType.FIRE_WORM)); + + fireWorm + .addComponent(new CombatStatsComponent(health, 0, drops)) + .addComponent(animator) + .addComponent(new FireWormAnimationController()) + .addComponent(aiTaskComponent); + + fireWorm.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.CENTER); + fireWorm.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return fireWorm; + } + + + /** + * Creates a xeno grunt entity. + * + * @return entity + */ + public static Entity createXenoGrunt(int health) { + Entity xenoGrunt = createMeleeBaseNPC(); + BaseEnemyConfig config = configs.xenoGrunt; + ArrayList melee = new ArrayList<>(Arrays.asList(PredefinedWeapons.sword, PredefinedWeapons.kick)); + // tester projectiles + ArrayList projectiles = new ArrayList<>(Arrays.asList(PredefinedWeapons.fireBall, PredefinedWeapons.frostBall)); + ArrayList drops = new ArrayList<>(); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService().getAsset("images/mobs/xenoGrunt.atlas", TextureAtlas.class)); + animator.addAnimation("xeno_run", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("xeno_hurt", 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("xeno_shoot", 0.1f); + animator.addAnimation("xeno_melee_1", 0.1f); + animator.addAnimation("xeno_melee_2", 0.1f); + animator.addAnimation("xeno_die", 0.1f); + animator.addAnimation("xeno_freeze", 0.1f); + 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()); + + xenoGrunt.getComponent(HitboxComponent.class).setAsBoxAligned(new Vector2(.3f, .5f), PhysicsComponent.AlignX.RIGHT, PhysicsComponent.AlignY.BOTTOM); + xenoGrunt.getComponent(AnimationRenderComponent.class).scaleEntity(); + + return xenoGrunt; + } + + public static Entity createBaseNPC() { + Entity npc = + new Entity() + .addComponent(new PhysicsComponent()) + .addComponent(new PhysicsMovementComponent()) + .addComponent(new ColliderComponent()) + .addComponent(new HitboxComponent().setLayer(PhysicsLayer.NPC)) + .addComponent(new TouchAttackComponent(PhysicsLayer.HUMANS)); + PhysicsUtils.setScaledCollider(npc, 0.3f, 0.5f); + return npc; + } + + /** + * Creates a generic NPC to be used as a base entity by more specific NPC creation methods. + * + * @return entity + */ + public static Entity createMeleeBaseNPC() { + AITaskComponent aiComponent = + new AITaskComponent() + .addTask(new MobWanderTask(new Vector2(2f, 2f), 2f)) + .addTask(new MobMeleeAttackTask(2, 2f)); + // .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()) + .addComponent(new PhysicsMovementComponent()) + .addComponent(new ColliderComponent()) + .addComponent(new HitboxComponent().setLayer(PhysicsLayer.XENO)) + .addComponent(new TouchAttackComponent(PhysicsLayer.HUMANS)) + .addComponent(aiComponent); + PhysicsUtils.setScaledCollider(npc, 0.3f, 0.5f); + return npc; + } + /** + * Creates a generic NPC to be used as a base entity by more specific NPC creation methods. + * + * @return entity + */ + public static Entity createRangedBaseNPC() { + AITaskComponent aiComponent = + new AITaskComponent() + .addTask(new MobWanderTask(new Vector2(2f, 2f), 2f)) + // .addTask(new MobAttackTask(2, 2f)); + .addTask(new MobRangedAttackTask(2, 2f)); + // .addTask(new MeleeMobTask(new Vector2(2f, 2f), 2f)); + + // .addTask(new MobAttackTask(2, 40)); + Entity npc = + new Entity() + .addComponent(new PhysicsComponent()) + .addComponent(new PhysicsMovementComponent()) + .addComponent(new ColliderComponent()) + .addComponent(new HitboxComponent().setLayer(PhysicsLayer.XENO)) + .addComponent(new TouchAttackComponent(PhysicsLayer.HUMANS)) + .addComponent(aiComponent); + PhysicsUtils.setScaledCollider(npc, 0.3f, 0.5f); + return npc; + } + + private NPCFactory() { + throw new IllegalStateException("Instantiating static util class"); + } + + // * COW'S TESTING ARENA DONT TOUCH + public static Entity createSplittingXenoGrunt(int health) { + Entity splitXenoGrunt = createXenoGrunt(health) + // add the scaling yourself. can also scale the X and Y component, + // leading to some very interesting mob designs. + .addComponent(new SplitMoblings(MobType.XENO, 7, 0.5f)) + .addComponent(new DodgingComponent(PhysicsLayer.PROJECTILE, 0.25f)); + + // * TEMPORARY TESTING FOR PROJECTILE DODGING + splitXenoGrunt.getComponent(AITaskComponent.class).addTask(new MobDodgeTask(MobType.DRAGON_KNIGHT, 5)); + // splitXenoGrunt.getComponent(AITaskComponent.class).addTask(new MobDodgeTask(new Vector2(2f, 2f), 2f, 5)); + return splitXenoGrunt; + } + + /** + * Create Splitting water slime + * + * @require Entity to have a "splitDeath" + * @return + */ + public static Entity createSplittingWaterSlime(int health) { + Entity splitWaterSlime = createBaseWaterSlime(health) + + .addComponent(new SplitMoblings(MobType.WATER_SLIME, 7, 0.5f)); + + return splitWaterSlime; + } + + /** + * Create Splitting water slime + * + * @require Entity to have a "splitDeath" + * @return Splitting Rocky + */ + public static Entity createSplittingRocky(int health) { + return createRocky(health).addComponent(new SplitMoblings(MobType.ROCKY, 7, 0.5f)); + } + + /** + * Create Splitting night borne + * + * @require Entity to have a "splitDeath" + * @return + */ + public static Entity createSplittingNightBorne(int health) { + Entity splitWaterSlime = createNightBorne(health) + + .addComponent(new SplitMoblings(MobType.NIGHT_BORNE, 7, 0.5f)); + + return splitWaterSlime; + } + + /** + * Create a dodging Dragon Knight + * + * @return + */ + 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)); + PhysicsUtils.setScaledCollider(dodgeKnight, 0.3f, 0.7f); + dodgeKnight.setScale(0.3f, 0.7f); + + return dodgeKnight; + } + + /** + * Create a dodging Arcane Archer + * + * @return + */ + 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)); + PhysicsUtils.setScaledCollider(dodgeKnight, 0.3f, 0.7f); + dodgeKnight.setScale(0.3f, 0.7f); + + return dodgeKnight; + } + +// public static Entity createDeflectXenoGrunt(int health) { +// Entity deflectXenoGrunt = createXenoGrunt(health); +// deflectXenoGrunt.addComponent(new DeflectingComponent( + /** + * Creates a wizard that can deflect bullets + * @return + */ + public static Entity createDeflectWizard(int health) { + Entity deflectWizard = createWizard(health); + deflectWizard.addComponent(new DeflectingComponent( + PhysicsLayer.PROJECTILE, PhysicsLayer.TOWER, 10)); + + return deflectWizard; + } + + /** + * Creates a wizard that can deflect bullets + * @return Deflecting firewizard + */ + public static Entity createDeflectFireWizard(int health) { + return createFirewizard(health).addComponent(new DeflectingComponent( + PhysicsLayer.PROJECTILE, PhysicsLayer.TOWER, 10)); + } +} + + 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 b64959976..95c1d7ec8 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 @@ -1,373 +1,419 @@ -package com.csse3200.game.entities.factories; - -import com.badlogic.gdx.graphics.g2d.Animation; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.csse3200.game.components.*; -import com.csse3200.game.components.MobProjectileAnimationController; -import com.csse3200.game.components.tasks.TrajectTask; -import com.csse3200.game.ai.tasks.AITaskComponent; -import com.csse3200.game.components.projectile.*; -import com.csse3200.game.entities.configs.BaseEntityConfig; -import com.csse3200.game.entities.configs.NPCConfigs; -import com.csse3200.game.files.FileLoader; -import com.csse3200.game.entities.Entity; -import com.csse3200.game.rendering.AnimationRenderComponent; -import com.csse3200.game.services.ServiceLocator; -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; -import com.csse3200.game.physics.components.PhysicsMovementComponent; -import com.badlogic.gdx.math.Vector2; - -/** - * Responsible for creating projectiles within the game. - */ -public class ProjectileFactory { - /** - * Animation constants - */ - private static final String BASE_PROJECTILE_ATLAS = "images/projectiles/basic_projectile.atlas"; - private static final String START_ANIM = "projectile"; - private static final String FINAL_ANIM = "projectileFinal"; - private static final float START_SPEED = 0.1f; - private static final float FINAL_SPEED = 0.1f; - - private static final NPCConfigs configs = - FileLoader.readClass(NPCConfigs.class, "configs/NPCs.json"); - - /** - * Creates a single-targeting projectile with specified effect - * - * @param targetLayer The enemy layer that the projectile collides with. - * @param destination The destination the projectile heads towards. - * @param speed The speed of the projectile. - * @param effect Specified effect from the ProjectileEffects enums - * @return Returns a new single-target projectile entity - */ - public static Entity createEffectProjectile(short targetLayer, Vector2 destination, Vector2 speed, ProjectileEffects effect, boolean aoe) { - Entity projectile = createBaseProjectile(targetLayer, destination, speed); - - switch (effect) { - case FIREBALL -> { - projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.FIREBALL, aoe)); - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset(BASE_PROJECTILE_ATLAS, TextureAtlas.class)); - animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); - animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); - - projectile - .addComponent(animator) - .addComponent(new ProjectileAnimationController()); - } - case BURN -> { - projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.BURN, aoe)); - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/burn_effect.atlas", TextureAtlas.class)); - animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); - animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); - - projectile - .addComponent(animator) - .addComponent(new BurnEffectProjectileAnimationController()); - } - case SLOW -> { - projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.SLOW, aoe)); - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/snow_ball.atlas", TextureAtlas.class)); - animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); - animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); - - projectile - .addComponent(animator) - .addComponent(new SnowBallProjectileAnimationController()); - // * TEMPORARY - // .addComponent(new DeleteOnMapEdgeComponent()); - // .addComponent(new SelfDestructOnHitComponent(PhysicsLayer.OBSTACLE)); - - return projectile; - } - case STUN -> { - projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.STUN, aoe)); - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/stun_effect.atlas", TextureAtlas.class)); - animator.addAnimation(START_ANIM, 0.1f, Animation.PlayMode.LOOP); - - projectile - .addComponent(animator) - .addComponent(new StunEffectProjectileAnimationController()); - } - } - return projectile; - } - - /** - * Create a pierce fireball. - * Pierce fireball is basically a fireball that does damage but won't self destruct on hit. - */ - public static Entity createPierceFireBall(short targetLayer, Vector2 destination, Vector2 speed) { - Entity fireBall = createPierceBallAnim(targetLayer, destination, speed); - fireBall.getComponent(TouchAttackComponent.class).setDisposeOnHit(false); - fireBall.getComponent(TouchAttackComponent.class).setKnockBack(0f); - - return fireBall; - } - - /** - * Create a ricochet fireball. - * Ricochet fireball bounces off specified targets while applying intended effects i.e. damage - */ - public static Entity createRicochetFireball(short targetLayer, Vector2 destination, Vector2 speed, int bounceCount) { - Entity fireBall = createFireBall(targetLayer, destination, speed); - fireBall - .addComponent(new RicochetComponent(targetLayer, bounceCount)); - - setColliderSize(fireBall, (float) 0.1, (float) 0.1); - - return fireBall; - } - - public static Entity createSplitFireWorksFireball(short targetLayer, Vector2 destination, Vector2 speed, int amount) { - Entity fireBall = createFireBall(targetLayer, destination, speed); - fireBall - .addComponent(new SplitFireworksComponent(targetLayer, amount)); - - return fireBall; - } - - /** - * Creates a fireball Entity. - * - * @param targetLayer The enemy layer that the projectile collides with. - * @param destination The destination the projectile heads towards. - * @param speed The speed of the projectile. - * @return Returns a new fireball projectile entity. - */ - public static Entity createFireBall(short targetLayer, Vector2 destination, Vector2 speed) { - Entity projectile = createBaseProjectile(targetLayer, destination, speed); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset(BASE_PROJECTILE_ATLAS, TextureAtlas.class)); - animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); - animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); - - projectile - .addComponent(animator) - .addComponent(new ProjectileAnimationController()); - // * TEMPORARY - // .addComponent(new DeleteOnMapEdgeComponent()); - // .addComponent(new SelfDestructOnHitComponent(PhysicsLayer.OBSTACLE)); - - return projectile; - } - - /** - * Creates new animation and fireballs for SplitFireworkComponent. - * - * @param targetLayer The enemy layer that the projectile collides with. - * @param destination The destination the projectile heads towards. - * @param speed The speed of the projectile. - * @return Returns a new fireball projectile entity. - */ - public static Entity createFireworks(short targetLayer, Vector2 destination, Vector2 speed) { - Entity projectile = createBaseProjectile(targetLayer, destination, speed); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/firework_anim.atlas", TextureAtlas.class)); - animator.addAnimation(START_ANIM, 0.2f, Animation.PlayMode.LOOP); - projectile - .addComponent(animator) - .addComponent(new FireworkAnimationController()); - - return projectile; - } - - public static Entity createPierceBallAnim(short targetLayer, Vector2 destination, Vector2 speed) { - Entity projectile = createBaseProjectile(targetLayer, destination, speed); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/pierce_anim.atlas", TextureAtlas.class)); - animator.addAnimation(START_ANIM, 0.05f, Animation.PlayMode.LOOP); - projectile - .addComponent(animator) - .addComponent(new PierceProjectileAnimationController()); - - return projectile; - } - - - /** - * Creates a engineer bullet - * - * @param targetLayer The enemy layer that the projectile collides with. - * @param destination The destination the projectile heads towards. - * @param speed The speed of the projectile. - * @return Returns a new fireball projectile entity. - */ - public static Entity createEngineerBullet(short targetLayer, Vector2 destination, Vector2 speed) { - Entity projectile = createBaseProjectile(targetLayer, destination, speed); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/engineer_projectile.atlas", TextureAtlas.class)); - animator.addAnimation("bullet", START_SPEED, Animation.PlayMode.NORMAL); - animator.addAnimation("bulletFinal", FINAL_SPEED, Animation.PlayMode.NORMAL); - - projectile - .addComponent(animator) - .addComponent(new EngineerBulletsAnimationController()); - // .addComponent(new SelfDestructOnHitComponent(PhysicsLayer.OBSTACLE)); - - return projectile; - } - - /** - * Creates a projectile specifically for mobs to shoot - * - * @param targetLayer The enemy layer that the projectile collides with. - * @param destination The destination the projectile heads towards. - * @param speed The speed of the projectile. - * @return Returns a new fireball projectile entity. - */ - public static Entity createMobBall(short targetLayer, Vector2 destination, Vector2 speed) { - Entity projectile = createBaseProjectile(targetLayer, destination, speed); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/mobProjectile.atlas", TextureAtlas.class)); - - animator.addAnimation("rotate", 0.15f, Animation.PlayMode.LOOP); - - projectile - .addComponent(animator) - .addComponent(new MobProjectileAnimationController()); - // * TEMPORARY - // .addComponent(new DeleteOnMapEdgeComponent()); - - projectile - .getComponent(AnimationRenderComponent.class).scaleEntity(); - - - - return projectile; - } - public static Entity createBossBall(short targetLayer, Vector2 destination, Vector2 speed) { // function added by team 7 for Boss projectile - Entity projectile = createBaseProjectile(targetLayer, destination, speed); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/bossProjectile.atlas", TextureAtlas.class)); - - animator.addAnimation("rotate", 0.15f, Animation.PlayMode.LOOP); - - projectile - .addComponent(animator) - .addComponent(new BossProjectileAnimationController()); - - projectile - .getComponent(AnimationRenderComponent.class).scaleEntity(); - projectile.setScale(2,2); - - return projectile; - } - - /** - * Creates a projectile to be used by the MobBoss - * - * @param targetLayer The enemy layer that the projectile collides with. - * @param destination The destination the projectile heads towards. - * @param speed The speed of the projectile. - * @return Returns a new fireball projectile entity. - */ - public static Entity createMobBossBall(short targetLayer, Vector2 destination, Vector2 speed) { - Entity projectile = createBaseProjectile(targetLayer, destination, speed); - - AnimationRenderComponent animator = - new AnimationRenderComponent( - ServiceLocator.getResourceService() - .getAsset("images/projectiles/mobBoss_projectile.atlas", TextureAtlas.class)); - animator.addAnimation("mob_boss", 0.17f, Animation.PlayMode.NORMAL); - animator.addAnimation("mob_bossFinal", 0.17f, Animation.PlayMode.NORMAL); - - - projectile - .addComponent(animator) - .addComponent(new MobBossProjectAnimController()); - - projectile - .getComponent(AnimationRenderComponent.class).scaleEntity(); - - return projectile; - } - - /** - * Creates a generic projectile entity that can be used for multiple types of * projectiles. - * - * @param targetLayer The enemy layer that the projectile collides with. - * @param destination The destination the projectile heads towards. - * @param speed The speed of the projectile. - * @return Returns a generic projectile entity. - */ - public static Entity createBaseProjectile(short targetLayer, Vector2 - destination, Vector2 speed) { - BaseEntityConfig config = configs.fireBall; - - AITaskComponent aiComponent = - new AITaskComponent() - .addTask(new TrajectTask(destination)); - - Entity projectile = new Entity() - .addComponent(new PhysicsComponent()) - .addComponent(new PhysicsMovementComponent()) - .addComponent(new HitboxComponent().setLayer(PhysicsLayer.PROJECTILE)) - .addComponent(aiComponent) - .addComponent(new ColliderComponent().setSensor(true)) - // This is the component that allows the projectile to damage a - // specified target. - // Original knockback value: 1.5f - .addComponent(new TouchAttackComponent(targetLayer, 0f, true)) - .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) - // *TEMPORARY - .addComponent(new DeleteOnMapEdgeComponent()); - - projectile - .getComponent(PhysicsMovementComponent.class).setSpeed(speed); - - return projectile; - } - - /** - * Sets the projectile collider so that the collider size can be altered for flexibility. - * @param projectile Projectile's size collider to be scaled upon. - * @param x Horizontal scaling of the collider in respect ot the size of the entity - * @param y Veritcal scaling of the collider in respect to the size of the entity - */ - public static void setColliderSize(Entity projectile, float x, float y) { - PhysicsUtils.setScaledCollider(projectile, x, y); - } - - /** - * Prevents the creation of a Projectile Factory entity being created - */ - private ProjectileFactory() { - throw new IllegalStateException("Instantiating static util class"); - } -} +package com.csse3200.game.entities.factories; + +import com.badlogic.gdx.graphics.g2d.Animation; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.csse3200.game.components.*; +import com.csse3200.game.components.MobProjectileAnimationController; +import com.csse3200.game.components.tasks.TrajectTask; +import com.csse3200.game.ai.tasks.AITaskComponent; +import com.csse3200.game.components.projectile.*; +import com.csse3200.game.entities.configs.BaseEntityConfig; +import com.csse3200.game.entities.configs.NPCConfigs; +import com.csse3200.game.files.FileLoader; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; +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; +import com.csse3200.game.physics.components.PhysicsMovementComponent; +import com.badlogic.gdx.math.Vector2; + +/** + * Responsible for creating projectiles within the game. + */ +public class ProjectileFactory { + /** + * Animation constants + */ + private static final String BASE_PROJECTILE_ATLAS = "images/projectiles/basic_projectile.atlas"; + private static final String START_ANIM = "projectile"; + private static final String FINAL_ANIM = "projectileFinal"; + private static final float START_SPEED = 0.1f; + private static final float FINAL_SPEED = 0.1f; + + private static final NPCConfigs configs = + FileLoader.readClass(NPCConfigs.class, "configs/NPCs.json"); + + /** + * Creates a single-targeting projectile with specified effect + * + * @param targetLayer The enemy layer that the projectile collides with. + * @param destination The destination the projectile heads towards. + * @param speed The speed of the projectile. + * @param effect Specified effect from the ProjectileEffects enums + * @return Returns a new single-target projectile entity + */ + public static Entity createEffectProjectile(short targetLayer, Vector2 destination, Vector2 speed, ProjectileEffects effect, boolean aoe) { + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + + switch (effect) { + case FIREBALL -> { + projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.FIREBALL, aoe)); + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset(BASE_PROJECTILE_ATLAS, TextureAtlas.class)); + animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation("projectileCollide", START_SPEED, Animation.PlayMode.NORMAL); + + projectile + .addComponent(animator) + .addComponent(new ProjectileAnimationController(targetLayer)); + } + case BURN -> { + projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.BURN, aoe)); + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/burn_effect.atlas", TextureAtlas.class)); + animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation("explosion", 0.1f, Animation.PlayMode.NORMAL); + + projectile + .addComponent(animator) + .addComponent(new BurnEffectProjectileAnimationController(targetLayer)); + } + case SLOW -> { + projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.SLOW, aoe)); + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/snow_ball.atlas", TextureAtlas.class)); + animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation("collision", START_SPEED, Animation.PlayMode.NORMAL); + + projectile + .addComponent(animator) + .addComponent(new SnowBallProjectileAnimationController(targetLayer)); + // * TEMPORARY + // .addComponent(new DeleteOnMapEdgeComponent()); + // .addComponent(new SelfDestructOnHitComponent(PhysicsLayer.OBSTACLE)); + + return projectile; + } + case STUN -> { + projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.STUN, aoe)); + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/stun_effect.atlas", TextureAtlas.class)); + animator.addAnimation(START_ANIM, 0.1f, Animation.PlayMode.LOOP); + animator.addAnimation("stun", 0.3f, Animation.PlayMode.LOOP); + + projectile + .addComponent(animator) + .addComponent(new StunEffectProjectileAnimationController(targetLayer)); + } + } + return projectile; + } + + public static Entity createComboSnowBall(short targetLayer, Vector2 destination, Vector2 speed, boolean aoe) { + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + projectile.addComponent(new EffectsComponent(targetLayer, 3, ProjectileEffects.SLOW, aoe)); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/mobBoss_projectile.atlas", TextureAtlas.class), + ServiceLocator.getResourceService() + .getAsset("images/projectiles/snow_ball.atlas", TextureAtlas.class)); + animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation("collision", START_SPEED, Animation.PlayMode.NORMAL); + + projectile + .addComponent(animator) + .addComponent(new SnowBallProjectileAnimationController(targetLayer)); + // * TEMPORARY + // .addComponent(new DeleteOnMapEdgeComponent()); + // .addComponent(new SelfDestructOnHitComponent(PhysicsLayer.OBSTACLE)); + + return projectile; + } + + /** + * Create a pierce fireball. + * Pierce fireball is basically a fireball that does damage but won't self destruct on hit. + */ + public static Entity createPierceFireBall(short targetLayer, Vector2 destination, Vector2 speed) { + Entity fireBall = createPierceBallAnim(targetLayer, destination, speed); + fireBall.getComponent(TouchAttackComponent.class).setDisposeOnHit(false); + fireBall.getComponent(TouchAttackComponent.class).setKnockBack(0f); + + return fireBall; + } + + public static Entity createPierceArrow(short targetLayer, Vector2 destination, Vector2 speed) { + Entity arrow = createBaseProjectile(targetLayer, destination, speed); + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/arrow.atlas", TextureAtlas.class)); + animator.addAnimation("arrow", 0.1f, Animation.PlayMode.LOOP); + arrow + .addComponent(animator) + .addComponent(new PierceArrowAnimationController()); + arrow.getComponent(TouchAttackComponent.class).setDisposeOnHit(false); + arrow.getComponent(TouchAttackComponent.class).setKnockBack(0f); + + return arrow; + } + + /** + * Create a ricochet fireball. + * Ricochet fireball bounces off specified targets while applying intended effects i.e. damage + */ + public static Entity createRicochetFireball(short targetLayer, Vector2 destination, Vector2 speed, int bounceCount) { + Entity fireBall = createFireBall(targetLayer, destination, speed); + fireBall + .addComponent(new RicochetComponent(targetLayer, bounceCount)); + + setColliderSize(fireBall, (float) 0.1, (float) 0.1); + + return fireBall; + } + + public static Entity createSplitFireWorksFireball(short targetLayer, Vector2 destination, Vector2 speed, int amount) { + Entity fireBall = createFireBall(targetLayer, destination, speed); + fireBall + .addComponent(new SplitFireworksComponent(targetLayer, amount)); + + return fireBall; + } + + /** + * Creates a fireball Entity. + * + * @param targetLayer The enemy layer that the projectile collides with. + * @param destination The destination the projectile heads towards. + * @param speed The speed of the projectile. + * @return Returns a new fireball projectile entity. + */ + public static Entity createFireBall(short targetLayer, Vector2 destination, Vector2 speed) { + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset(BASE_PROJECTILE_ATLAS, TextureAtlas.class)); + animator.addAnimation(START_ANIM, START_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation(FINAL_ANIM, FINAL_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation("projectileCollide", START_SPEED, Animation.PlayMode.NORMAL); + + projectile + .addComponent(animator) + .addComponent(new ProjectileAnimationController(targetLayer)); + // * TEMPORARY + // .addComponent(new DeleteOnMapEdgeComponent()); + // .addComponent(new SelfDestructOnHitComponent(PhysicsLayer.OBSTACLE)); + + return projectile; + } + + /** + * Creates new animation and fireballs for SplitFireworkComponent. + * + * @param targetLayer The enemy layer that the projectile collides with. + * @param destination The destination the projectile heads towards. + * @param speed The speed of the projectile. + * @return Returns a new fireball projectile entity. + */ + public static Entity createFireworks(short targetLayer, Vector2 destination, Vector2 speed) { + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/firework_anim.atlas", TextureAtlas.class)); + animator.addAnimation(START_ANIM, 0.2f, Animation.PlayMode.LOOP); + projectile + .addComponent(animator) + .addComponent(new FireworkAnimationController()); + + return projectile; + } + + public static Entity createPierceBallAnim(short targetLayer, Vector2 destination, Vector2 speed) { + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/pierce_anim.atlas", TextureAtlas.class)); + animator.addAnimation(START_ANIM, 0.05f, Animation.PlayMode.LOOP); + projectile + .addComponent(animator) + .addComponent(new PierceProjectileAnimationController()); + + return projectile; + } + + + /** + * Creates a engineer bullet + * + * @param targetLayer The enemy layer that the projectile collides with. + * @param destination The destination the projectile heads towards. + * @param speed The speed of the projectile. + * @return Returns a new fireball projectile entity. + */ + public static Entity createEngineerBullet(short targetLayer, Vector2 destination, Vector2 speed) { + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/engineer_projectile.atlas", TextureAtlas.class)); + animator.addAnimation("bullet", START_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation("bulletFinal", FINAL_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation("bulletCollide", START_SPEED, Animation.PlayMode.NORMAL); + + projectile + .addComponent(animator) + .addComponent(new EngineerBulletsAnimationController(targetLayer)); + // .addComponent(new SelfDestructOnHitComponent(PhysicsLayer.OBSTACLE)); + + return projectile; + } + + /** + * Creates a projectile specifically for mobs to shoot + * + * @param targetLayer The enemy layer that the projectile collides with. + * @param destination The destination the projectile heads towards. + * @param speed The speed of the projectile. + * @return Returns a new fireball projectile entity. + */ + public static Entity createMobBall(short targetLayer, Vector2 destination, Vector2 speed) { + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/mobProjectile.atlas", TextureAtlas.class)); + + animator.addAnimation("rotate", 0.15f, Animation.PlayMode.LOOP); + + projectile + .addComponent(animator) + .addComponent(new MobProjectileAnimationController()); + // * TEMPORARY + // .addComponent(new DeleteOnMapEdgeComponent()); + + projectile + .getComponent(AnimationRenderComponent.class).scaleEntity(); + + + + return projectile; + } + public static Entity createBossBall(short targetLayer, Vector2 destination, Vector2 speed) { // function added by team 7 for Boss projectile + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/bossProjectile.atlas", TextureAtlas.class)); + + animator.addAnimation("rotate", 0.15f, Animation.PlayMode.LOOP); + + projectile + .addComponent(animator) + .addComponent(new BossProjectileAnimationController()); + + projectile + .getComponent(AnimationRenderComponent.class).scaleEntity(); + projectile.setScale(2,2); + + return projectile; + } + + /** + * Creates a projectile to be used by the MobBoss + * + * @param targetLayer The enemy layer that the projectile collides with. + * @param destination The destination the projectile heads towards. + * @param speed The speed of the projectile. + * @return Returns a new fireball projectile entity. + */ + public static Entity createMobBossBall(short targetLayer, Vector2 destination, Vector2 speed) { + Entity projectile = createBaseProjectile(targetLayer, destination, speed); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset("images/projectiles/mobBoss_projectile.atlas", TextureAtlas.class)); + animator.addAnimation("mob_boss", 0.17f, Animation.PlayMode.NORMAL); + animator.addAnimation("mob_bossFinal", 0.17f, Animation.PlayMode.NORMAL); + + + projectile + .addComponent(animator) + .addComponent(new MobBossProjectAnimController()); + + projectile + .getComponent(AnimationRenderComponent.class).scaleEntity(); + + return projectile; + } + + /** + * Creates a generic projectile entity that can be used for multiple types of * projectiles. + * + * @param targetLayer The enemy layer that the projectile collides with. + * @param destination The destination the projectile heads towards. + * @param speed The speed of the projectile. + * @return Returns a generic projectile entity. + */ + public static Entity createBaseProjectile(short targetLayer, Vector2 + destination, Vector2 speed) { + BaseEntityConfig config = configs.fireBall; + + AITaskComponent aiComponent = + new AITaskComponent() + .addTask(new TrajectTask(destination)); + + Entity projectile = new Entity() + .addComponent(new PhysicsComponent()) + .addComponent(new PhysicsMovementComponent()) + .addComponent(new HitboxComponent().setLayer(PhysicsLayer.PROJECTILE)) + .addComponent(aiComponent) + .addComponent(new ColliderComponent().setSensor(true)) + // 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 CombatStatsComponent(config.health, config.baseAttack)) + // *TEMPORARY + .addComponent(new DeleteOnMapEdgeComponent()); + + projectile + .getComponent(PhysicsMovementComponent.class).setSpeed(speed); + + return projectile; + } + + /** + * Sets the projectile collider so that the collider size can be altered for flexibility. + * @param projectile Projectile's size collider to be scaled upon. + * @param x Horizontal scaling of the collider in respect ot the size of the entity + * @param y Veritcal scaling of the collider in respect to the size of the entity + */ + public static void setColliderSize(Entity projectile, float x, float y) { + PhysicsUtils.setScaledCollider(projectile, x, y); + } + + /** + * Prevents the creation of a Projectile Factory entity being created + */ + private ProjectileFactory() { + throw new IllegalStateException("Instantiating static util class"); + } +} 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 387d9c59e..a6180b451 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,7 +1,9 @@ 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.*; @@ -21,24 +23,28 @@ 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 org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.util.HashSet; +import com.csse3200.game.input.UpgradeUIComponent;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"; @@ -99,29 +105,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.getIncome(); + IncomeTowerConfig config = configs.income; // Create the CurrencyIncomeTask and add it to the AITaskComponent - CurrencyTask currencyTask = new CurrencyTask(INCOME_TASK_PRIORITY, (int) config.getIncomeRate()); + CurrencyTask currencyTask = new CurrencyTask(INCOME_TASK_PRIORITY, (int) config.incomeRate); AITaskComponent aiTaskComponent = new AITaskComponent().addTask(currencyTask); + // Contains all the animations that the tower will have AnimationRenderComponent animator = new AnimationRenderComponent( @@ -131,10 +137,10 @@ public static Entity createIncomeTower() { animator.addAnimation(ECO_MOVE, ECO_IDLE_SPEED, Animation.PlayMode.NORMAL); income - .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) - .addComponent(new CostComponent(config.getCost())) - .addComponent(new IncomeUpgradeComponent(config.getIncomeRate())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(new UpgradableStatsComponent(config.attackRate)) + .addComponent(new CostComponent(config.cost)) + .addComponent(new IncomeUpgradeComponent(config.incomeRate)) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new EconTowerAnimationController()); @@ -142,13 +148,9 @@ public static Entity createIncomeTower() { return income; } - /** - * Create wall tower - * @return entity - */ public static Entity createWallTower() { Entity wall = createBaseTower(); - WallTowerConfig config = configs.getWall(); + WallTowerConfig config = configs.wall; AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new WallTowerDestructionTask(COMBAT_TASK_PRIORITY,TNT_TOWER_MAX_RANGE)); @@ -162,9 +164,9 @@ public static Entity createWallTower() { wall .addComponent(aiTaskComponent) - .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) - .addComponent(new CostComponent(config.getCost())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(new UpgradableStatsComponent(config.attackRate)) + .addComponent(new CostComponent(config.cost)) .addComponent(animator) .addComponent(new WallTowerAnimationController()); @@ -173,6 +175,7 @@ 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 @@ -184,7 +187,7 @@ public static Entity createTNTTower() { .setLayer(PhysicsLayer.NONE) .setSensor(true); TNTTower.getComponent(ColliderComponent.class).setSensor(true); - TNTTowerConfigs config = configs.getTNTTower(); + TNTTowerConfigs config = configs.TNTTower; AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new TNTTowerCombatTask(COMBAT_TASK_PRIORITY,TNT_TOWER_MAX_RANGE)); @@ -199,16 +202,15 @@ public static Entity createTNTTower() { animator.addAnimation(EXPLODE_ANIM,EXPLODE_SPEED, Animation.PlayMode.NORMAL); TNTTower - .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) - .addComponent(new CostComponent(config.getCost())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(new UpgradableStatsComponent(config.attackRate)) + .addComponent(new CostComponent(config.cost)) .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; } @@ -220,8 +222,8 @@ public static Entity createTNTTower() { * @return entity */ public static Entity createDroidTower() { - Entity droidTower = createBaseTower(); - DroidTowerConfig config = configs.getDroidTower(); + Entity DroidTower = createBaseTower(); + DroidTowerConfig config = configs.DroidTower; AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new DroidCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); @@ -239,15 +241,17 @@ 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.getHealth(), config.getBaseAttack())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) - .addComponent(new CostComponent(config.getCost())) + + + DroidTower + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(new UpgradableStatsComponent(config.attackRate)) + .addComponent(new CostComponent(config.cost)) .addComponent(new DroidAnimationController()) .addComponent(animator) .addComponent(aiTaskComponent); - return droidTower; + return DroidTower; } @@ -258,7 +262,7 @@ public static Entity createDroidTower() { */ public static Entity createWeaponTower() { Entity weapon = createBaseTower(); - WeaponTowerConfig config = configs.getWeapon(); + WeaponTowerConfig config = configs.weapon; // AiTaskComponent will run the tower task which carries out detection of targets and trigger events AITaskComponent aiTaskComponent = new AITaskComponent() @@ -275,14 +279,16 @@ public static Entity createWeaponTower() { animator.addAnimation(FIRE_ANIM, (2*FIRE_SPEED), Animation.PlayMode.LOOP); weapon - .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) - .addComponent(new CostComponent(config.getCost())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(new UpgradableStatsComponent(config.attackRate)) + .addComponent(new CostComponent(config.cost)) + .addComponent(new UpgradableStatsComponent(config.attackRate)) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new TowerAnimationController()); return weapon; + } /** @@ -291,7 +297,7 @@ public static Entity createWeaponTower() { */ public static Entity createFireTower() { Entity fireTower = createBaseTower(); - FireTowerConfig config = configs.getFireTower(); + FireTowerConfig config = configs.fireTower; //Component that handles triggering events and animations AITaskComponent aiTaskComponent = new AITaskComponent() @@ -307,13 +313,12 @@ public static Entity createFireTower() { animator.addAnimation(FIRE_TOWER_DEATH_ANIM, FIRE_TOWER_DEATH_SPEED, Animation.PlayMode.NORMAL); fireTower - .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) - .addComponent(new CostComponent(config.getCost())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(new UpgradableStatsComponent(config.attackRate)) + .addComponent(new CostComponent(config.cost)) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new FireTowerAnimationController()); - fireTower.setScale(1.25f, 1.25f); return fireTower; } @@ -324,7 +329,7 @@ public static Entity createFireTower() { */ public static Entity createStunTower() { Entity stunTower = createBaseTower(); - StunTowerConfig config = configs.getStunTower(); + StunTowerConfig config = configs.stunTower; AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new StunTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); @@ -334,13 +339,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.getHealth(), config.getBaseAttack())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) - .addComponent(new CostComponent(config.getCost())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(new UpgradableStatsComponent(config.attackRate)) + .addComponent((new CostComponent(config.cost))) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new StunTowerAnimationController()); @@ -355,11 +360,12 @@ public static Entity createStunTower() { */ public static Entity createFireworksTower() { Entity fireworksTower = createBaseTower(); - FireworksTowerConfig config = configs.getFireworksTower(); + FireworksTowerConfig config = configs.fireworksTower; AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new FireworksTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); + AnimationRenderComponent animator = new AnimationRenderComponent( ServiceLocator.getResourceService() @@ -369,9 +375,8 @@ public static Entity createFireworksTower() { animator.addAnimation(FIREWORKS_TOWER_DEATH_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.NORMAL); fireworksTower - .addComponent(new CombatStatsComponent(config.getHealth(), config.getBaseAttack())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) - .addComponent(new CostComponent(config.getCost())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent((new CostComponent(config.cost))) .addComponent(aiTaskComponent) .addComponent(animator) .addComponent(new FireworksTowerAnimationController()); @@ -385,7 +390,7 @@ public static Entity createFireworksTower() { */ public static Entity createPierceTower() { Entity pierceTower = createBaseTower(); - PierceTowerConfig config = configs.getPierceTower(); + PierceTowerConfig config = configs.pierceTower; AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new PierceTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); @@ -399,12 +404,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.getHealth(), config.getBaseAttack())) - .addComponent(new CostComponent(config.getCost())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent((new CostComponent(config.cost))) .addComponent(aiTaskComponent); pierceTower.setScale(1.5f, 1.5f); @@ -417,7 +422,7 @@ public static Entity createPierceTower() { */ public static Entity createRicochetTower() { Entity ricochetTower = createBaseTower(); - RicochetTowerConfig config = configs.getRicochetTower(); + RicochetTowerConfig config = configs.ricochetTower; AITaskComponent aiTaskComponent = new AITaskComponent() .addTask(new RicochetTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); @@ -427,13 +432,11 @@ 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.getHealth(), config.getBaseAttack())) - .addComponent(new CostComponent(config.getCost())) - .addComponent(new UpgradableStatsComponent(config.getAttackRate())) + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent((new CostComponent(config.cost))) .addComponent(aiTaskComponent); ricochetTower.setScale(1.5f, 1.5f); @@ -447,6 +450,7 @@ 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)) @@ -461,4 +465,27 @@ 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 0b9f6db73..53ea2007a 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 - final int LVL1_BOSS_BASE_HEALTH = 500; - final int LVL2_BOSS_BASE_HEALTH = 1000; - final int LVL3_BOSS_BASE_HEALTH = 2000; + int LVL1_BOSS_BASE_HEALTH = 500; + int LVL2_BOSS_BASE_HEALTH = 1000; + int LVL3_BOSS_BASE_HEALTH = 2000; switch (chosenLevel) { case 2: @@ -155,6 +155,7 @@ 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) { @@ -170,23 +171,26 @@ 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 - final int RANGE_BASE_HEALTH = 60; + int RANGE_BASE_HEALTH = 60; int health = RANGE_BASE_HEALTH; if (MELEE_MOBS.contains(mob)) { // The base health for the different mobs - final int MELEE_BASE_HEALTH = 80; + 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)); @@ -196,7 +200,9 @@ 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 2d514c43a..0dcb71dec 100644 --- a/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java +++ b/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java @@ -13,6 +13,8 @@ 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; /** @@ -20,6 +22,7 @@ * 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 = { @@ -41,6 +44,7 @@ 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, @@ -51,15 +55,10 @@ public BuildInputComponent(Camera camera) { Array defaultTowers = new Array<>(); defaultTowers.addAll(defaultTowerTypes); - if (towers.isEmpty() || towers.size < 5) { - for (TowerType tower : defaultTowers) { - if (towers.size < 5 && !towers.contains(tower, true)) { - towers.add(tower); - } - } + if (towers.isEmpty()) { + ServiceLocator.setTowerTypes(defaultTowers); + towers = defaultTowers; } - - ServiceLocator.setTowerTypes(towers); } /** @@ -91,9 +90,11 @@ 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; @@ -110,35 +111,31 @@ 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; - } - default -> { + case Input.Keys.ESCAPE: + + default: return false; - } } } @@ -164,26 +161,53 @@ 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 currencyService = ServiceLocator.getCurrencyService(); - TowerType tower = currencyService.getTower(); + currencyService = ServiceLocator.getCurrencyService(); + if (currencyService == null) { + // if the currency service fails or is not running + return false; + } + 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); - if (canAfford(cost)) { + // 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); - createTower(tower, x, y, cost); long soundId = buildSound.play(); buildSound.setVolume(soundId, 0.4f); - // deselect the tower after building if not in multiple placement mode + // deselect the tower after building if (!multipleTowerBuild) { ServiceLocator.getCurrencyService().setTowerType(null); } return true; - } else { // play a sound to indicate an invalid action long soundId = errorSound.play(); @@ -194,47 +218,6 @@ 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 857a14919..9d4c42f50 100644 --- a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java +++ b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java @@ -1,6 +1,5 @@ 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; @@ -20,7 +19,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.*; +import com.csse3200.game.areas.ForestGameArea; import com.csse3200.game.components.CombatStatsComponent; import com.csse3200.game.components.tasks.TowerCombatTask; import com.csse3200.game.components.tower.*; @@ -34,25 +33,7 @@ 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; @@ -104,10 +85,21 @@ 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); @@ -118,6 +110,8 @@ 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 @@ -155,11 +149,9 @@ 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().left(); + upgradeTable.top(); 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(); @@ -188,12 +180,11 @@ 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/crystal.png"))); - Drawable costDrawableScrap = new TextureRegionDrawable(new TextureRegion(new Texture("images/economy/scrap.png"))); + Drawable costDrawable = 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("You shouldn't see this", createLabelStyle()); + Label costDisplayLabel = new Label("100", createLabelStyle()); costDisplay.add(costDisplayLabel).padLeft(0); TextButton closeButton = new TextButton("X", style); @@ -226,15 +217,14 @@ 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().getCrystal().getAmount(); + value = ServiceLocator.getCurrencyService().getScrap().getAmount(); logger.info("clicked"); - if (value >= UPGRADE_COST) { - value -= UPGRADE_COST; - ServiceLocator.getCurrencyService().getCrystal().setAmount(value); - ServiceLocator.getCurrencyService().getDisplay().updateCrystalsStats(); + if (value >= 100) { + value -= 100; + ServiceLocator.getCurrencyService().getScrap().setAmount(value); + ServiceLocator.getCurrencyService().getDisplay().updateScrapsStats(); - turretEntity.getComponent(TowerUpgraderComponent.class) - .upgradeTower(TowerUpgraderComponent.UPGRADE.MAXHP, HEALTH_INCREASE); + turretEntity.getComponent(TowerUpgraderComponent.class).upgradeTower(TowerUpgraderComponent.UPGRADE.MAXHP, 10); int currentHealth = turretEntity.getComponent(CombatStatsComponent.class).getHealth(); int maxHealth = turretEntity.getComponent(CombatStatsComponent.class).getMaxHealth(); healthLabel.setText(String.format("%d/%d", currentHealth, maxHealth)); @@ -242,7 +232,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(String.format("%d", UPGRADE_COST)); + costDisplayLabel.setText("10"); costDisplay.setVisible(true); } @Override @@ -257,13 +247,12 @@ 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().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); + 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); int attack = turretEntity.getComponent(CombatStatsComponent.class).getBaseAttack(); attackLabel.setText(String.format("%d", attack)); @@ -271,7 +260,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(String.format("%d", UPGRADE_COST)); + costDisplayLabel.setText("10"); costDisplay.setVisible(true); } @Override @@ -287,18 +276,14 @@ 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().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); + 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); float fireRate = turretEntity.getComponent(UpgradableStatsComponent.class).getAttackRate(); fireRateLabel.setText(String.format("%.2f", fireRate)); @@ -308,7 +293,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(String.format("%d", UPGRADE_COST)); + costDisplayLabel.setText("10"); costDisplay.setVisible(true); } @Override @@ -324,12 +309,11 @@ 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 >= REPAIR_COST) { - value -= REPAIR_COST; + if (value >= 100) { + value -= 100; 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)); } @@ -337,13 +321,11 @@ 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(String.format("%d", REPAIR_COST)); - costImage.setDrawable(costDrawableScrap); + costDisplayLabel.setText("10"); costDisplay.setVisible(true); } @Override public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { - costImage.setDrawable(costDrawable); costDisplay.setVisible(false); } @@ -371,12 +353,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().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; + 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; turretEntity.getComponent(IncomeUpgradeComponent.class).setIncomeRate(newIncome); turretEntity.getComponent(TowerUpgraderComponent.class).upgradeTower(TowerUpgraderComponent.UPGRADE.INCOME, (int) newIncome); incomeLabel.setText(String.format("%.2f", newIncome)); @@ -387,7 +369,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(String.format("%d", UPGRADE_COST)); + costDisplayLabel.setText("10"); costDisplay.setVisible(true); } @Override @@ -396,7 +378,6 @@ 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 deleted file mode 100644 index 1aebf5c26..000000000 --- a/source/core/src/main/com/csse3200/game/screens/AnimationTexturePair.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * 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 d224c8e78..e3fe516b5 100644 --- a/source/core/src/main/com/csse3200/game/screens/AssetLoader.java +++ b/source/core/src/main/com/csse3200/game/screens/AssetLoader.java @@ -1,17 +1,13 @@ package com.csse3200.game.screens; - import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.audio.Sound; -import com.badlogic.gdx.graphics.Texture; 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.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", @@ -89,8 +85,7 @@ 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/HelpScreen/hs.jpg" + "images/red_tile.png" }; public static final String[] textureAtlases = { @@ -141,7 +136,6 @@ 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", @@ -162,6 +156,7 @@ public class AssetLoader { "sounds/mobs/waterQueenSpell.mp3", "sounds/mobs/boneBreak.mp3", "sounds/mobs/fireWormRoar.mp3", + "sounds/mobs/archerArrow.mp3", "sounds/mobBoss/demonBreath.mp3", "sounds/mobBoss/demonSpawn.wav", "sounds/mobBoss/demonAttack.wav", @@ -241,13 +236,5 @@ 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 new file mode 100644 index 000000000..14c8cd5dc --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/HelpScreen.java @@ -0,0 +1,85 @@ +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 deleted file mode 100644 index 772c72e32..000000000 --- a/source/core/src/main/com/csse3200/game/screens/HelpScreen/BossDescriptionHelpScreen.java +++ /dev/null @@ -1,164 +0,0 @@ -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 deleted file mode 100644 index 625ab1bd9..000000000 --- a/source/core/src/main/com/csse3200/game/screens/HelpScreen/HowToPlay.java +++ /dev/null @@ -1,132 +0,0 @@ -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 deleted file mode 100644 index 1d89925fa..000000000 --- a/source/core/src/main/com/csse3200/game/screens/HelpScreen/MobsDescriptionHelpScreen.java +++ /dev/null @@ -1,205 +0,0 @@ -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