diff --git a/source/core/assets/images/skeleton.jpg b/source/core/assets/images/skeleton.jpg new file mode 100644 index 000000000..1e357b6b4 Binary files /dev/null and b/source/core/assets/images/skeleton.jpg differ diff --git a/source/core/assets/images/skeleton.png b/source/core/assets/images/skeleton.png new file mode 100644 index 000000000..1a6d75422 Binary files /dev/null and b/source/core/assets/images/skeleton.png differ diff --git a/source/core/assets/images/ui/buttons/determination_mono_22.fnt b/source/core/assets/images/ui/buttons/determination_mono_22.fnt new file mode 100644 index 000000000..d21e29871 --- /dev/null +++ b/source/core/assets/images/ui/buttons/determination_mono_22.fnt @@ -0,0 +1,191 @@ +info face="determination_mono_22" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0 +common lineHeight=22 base=17 scaleW=506 scaleH=89 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0 +page id=0 file="determination_mono_22.png" +chars count=186 +char id=0 x=2 y=2 width=8 height=17 xoffset=-1 yoffset=1 xadvance=9 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 +char id=33 x=244 y=25 width=8 height=16 xoffset=1 yoffset=2 xadvance=13 page=0 chnl=0 +char id=34 x=70 y=78 width=10 height=8 xoffset=-1 yoffset=3 xadvance=13 page=0 chnl=0 +char id=35 x=154 y=44 width=12 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=36 x=24 y=2 width=10 height=21 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=0 +char id=37 x=196 y=44 width=12 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=38 x=129 y=44 width=11 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=39 x=500 y=61 width=5 height=8 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=40 x=376 y=44 width=8 height=15 xoffset=2 yoffset=3 xadvance=12 page=0 chnl=0 +char id=41 x=366 y=44 width=8 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=42 x=0 y=78 width=13 height=10 xoffset=-2 yoffset=6 xadvance=12 page=0 chnl=0 +char id=43 x=25 y=78 width=10 height=9 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=44 x=493 y=61 width=5 height=9 xoffset=-1 yoffset=13 xadvance=12 page=0 chnl=0 +char id=45 x=167 y=78 width=8 height=5 xoffset=1 yoffset=8 xadvance=13 page=0 chnl=0 +char id=46 x=160 y=78 width=5 height=5 xoffset=-1 yoffset=13 xadvance=12 page=0 chnl=0 +char id=47 x=12 y=25 width=10 height=17 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=48 x=491 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=49 x=98 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=50 x=86 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=51 x=74 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=52 x=61 y=61 width=11 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=53 x=49 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=54 x=37 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=55 x=24 y=61 width=11 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=56 x=12 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=57 x=0 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=58 x=444 y=61 width=5 height=12 xoffset=2 yoffset=6 xadvance=12 page=0 chnl=0 +char id=59 x=400 y=44 width=5 height=14 xoffset=2 yoffset=6 xadvance=12 page=0 chnl=0 +char id=60 x=313 y=44 width=9 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=61 x=48 y=78 width=10 height=8 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=62 x=301 y=44 width=10 height=15 xoffset=0 yoffset=3 xadvance=12 page=0 chnl=0 +char id=63 x=443 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=64 x=270 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=65 x=359 y=25 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=66 x=371 y=25 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=67 x=397 y=25 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=68 x=409 y=25 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=69 x=421 y=25 width=11 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=70 x=434 y=25 width=11 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=71 x=459 y=25 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=72 x=471 y=25 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=73 x=483 y=25 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=74 x=495 y=25 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=75 x=14 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=76 x=50 y=44 width=11 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=77 x=91 y=44 width=12 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=78 x=105 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=79 x=117 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=80 x=142 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=81 x=308 y=2 width=10 height=19 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=82 x=184 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=83 x=210 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=84 x=236 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=85 x=248 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=86 x=282 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=87 x=386 y=44 width=12 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=88 x=407 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=89 x=419 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=90 x=431 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=91 x=356 y=44 width=8 height=15 xoffset=2 yoffset=3 xadvance=12 page=0 chnl=0 +char id=92 x=260 y=44 width=8 height=15 xoffset=1 yoffset=3 xadvance=13 page=0 chnl=0 +char id=93 x=346 y=44 width=8 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=94 x=82 y=78 width=11 height=8 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=95 x=177 y=78 width=10 height=5 xoffset=-1 yoffset=17 xadvance=11 page=0 chnl=0 +char id=96 x=130 y=78 width=6 height=6 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=97 x=416 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=98 x=455 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=99 x=392 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=100 x=467 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=101 x=365 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=102 x=479 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=103 x=184 y=25 width=10 height=16 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=104 x=122 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=105 x=196 y=25 width=10 height=16 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 +char id=106 x=12 y=2 width=10 height=21 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=107 x=148 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=108 x=160 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=109 x=265 y=61 width=12 height=12 xoffset=-1 yoffset=6 xadvance=12 page=0 chnl=0 +char id=110 x=253 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=111 x=241 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=112 x=208 y=25 width=10 height=16 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=113 x=220 y=25 width=10 height=16 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=114 x=229 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=115 x=404 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=116 x=184 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=117 x=279 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=118 x=291 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=119 x=315 y=61 width=12 height=12 xoffset=-1 yoffset=6 xadvance=12 page=0 chnl=0 +char id=120 x=329 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=121 x=232 y=25 width=10 height=16 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=122 x=353 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=123 x=335 y=44 width=9 height=15 xoffset=1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=124 x=294 y=44 width=5 height=15 xoffset=2 yoffset=3 xadvance=12 page=0 chnl=0 +char id=125 x=324 y=44 width=9 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=126 x=116 y=78 width=12 height=6 xoffset=-1 yoffset=8 xadvance=12 page=0 chnl=0 +char id=160 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=17 xadvance=12 page=0 chnl=0 +char id=161 x=174 y=25 width=8 height=16 xoffset=1 yoffset=6 xadvance=13 page=0 chnl=0 +char id=162 x=110 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=163 x=134 y=61 width=12 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=165 x=172 y=61 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=166 x=196 y=61 width=5 height=15 xoffset=2 yoffset=3 xadvance=12 page=0 chnl=0 +char id=167 x=320 y=2 width=10 height=19 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=168 x=148 y=78 width=10 height=5 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=169 x=254 y=25 width=14 height=16 xoffset=-3 yoffset=3 xadvance=12 page=0 chnl=0 +char id=170 x=216 y=61 width=11 height=13 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=171 x=478 y=61 width=13 height=10 xoffset=-2 yoffset=6 xadvance=12 page=0 chnl=0 +char id=172 x=95 y=78 width=11 height=8 xoffset=-1 yoffset=8 xadvance=12 page=0 chnl=0 +char id=173 x=138 y=78 width=8 height=5 xoffset=1 yoffset=8 xadvance=13 page=0 chnl=0 +char id=174 x=319 y=25 width=14 height=16 xoffset=-3 yoffset=3 xadvance=12 page=0 chnl=0 +char id=176 x=15 y=78 width=8 height=9 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=177 x=341 y=61 width=10 height=12 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=180 x=108 y=78 width=6 height=6 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=181 x=347 y=25 width=10 height=16 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=182 x=383 y=25 width=12 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=183 x=189 y=78 width=5 height=5 xoffset=2 yoffset=9 xadvance=12 page=0 chnl=0 +char id=184 x=37 y=78 width=9 height=8 xoffset=-1 yoffset=15 xadvance=12 page=0 chnl=0 +char id=186 x=203 y=61 width=11 height=13 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=187 x=463 y=61 width=13 height=10 xoffset=-2 yoffset=6 xadvance=12 page=0 chnl=0 +char id=191 x=447 y=25 width=10 height=15 xoffset=-1 yoffset=7 xadvance=11 page=0 chnl=0 +char id=192 x=132 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=193 x=144 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=194 x=36 y=2 width=10 height=21 xoffset=-1 yoffset=-3 xadvance=11 page=0 chnl=0 +char id=195 x=156 y=2 width=12 height=20 xoffset=-1 yoffset=-2 xadvance=12 page=0 chnl=0 +char id=196 x=332 y=2 width=10 height=19 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 +char id=197 x=60 y=2 width=10 height=21 xoffset=-1 yoffset=-3 xadvance=11 page=0 chnl=0 +char id=198 x=0 y=44 width=12 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=199 x=344 y=2 width=10 height=19 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=200 x=170 y=2 width=11 height=20 xoffset=-1 yoffset=-2 xadvance=12 page=0 chnl=0 +char id=201 x=183 y=2 width=11 height=20 xoffset=-1 yoffset=-2 xadvance=12 page=0 chnl=0 +char id=202 x=84 y=2 width=10 height=21 xoffset=-1 yoffset=-3 xadvance=11 page=0 chnl=0 +char id=203 x=356 y=2 width=10 height=19 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 +char id=204 x=196 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=205 x=208 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=206 x=96 y=2 width=10 height=21 xoffset=-1 yoffset=-3 xadvance=11 page=0 chnl=0 +char id=207 x=380 y=2 width=11 height=19 xoffset=-1 yoffset=-1 xadvance=12 page=0 chnl=0 +char id=208 x=63 y=44 width=12 height=15 xoffset=-2 yoffset=3 xadvance=12 page=0 chnl=0 +char id=209 x=220 y=2 width=12 height=20 xoffset=-1 yoffset=-2 xadvance=12 page=0 chnl=0 +char id=210 x=234 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=211 x=246 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=212 x=108 y=2 width=10 height=21 xoffset=-1 yoffset=-3 xadvance=11 page=0 chnl=0 +char id=213 x=258 y=2 width=12 height=20 xoffset=-1 yoffset=-2 xadvance=12 page=0 chnl=0 +char id=214 x=393 y=2 width=10 height=19 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 +char id=215 x=451 y=61 width=10 height=11 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=216 x=168 y=44 width=14 height=15 xoffset=-3 yoffset=3 xadvance=12 page=0 chnl=0 +char id=217 x=272 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=218 x=284 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=219 x=120 y=2 width=10 height=21 xoffset=-1 yoffset=-3 xadvance=11 page=0 chnl=0 +char id=220 x=405 y=2 width=10 height=19 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 +char id=221 x=296 y=2 width=10 height=20 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 +char id=222 x=38 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=223 x=26 y=44 width=10 height=15 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=224 x=138 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=225 x=48 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=226 x=477 y=2 width=10 height=18 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=0 +char id=227 x=60 y=25 width=12 height=17 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=0 +char id=228 x=283 y=25 width=10 height=16 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 +char id=229 x=368 y=2 width=10 height=19 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 +char id=230 x=377 y=61 width=13 height=12 xoffset=-2 yoffset=6 xadvance=12 page=0 chnl=0 +char id=231 x=307 y=25 width=10 height=16 xoffset=-1 yoffset=6 xadvance=11 page=0 chnl=0 +char id=232 x=150 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=233 x=489 y=2 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=234 x=465 y=2 width=10 height=18 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=0 +char id=235 x=162 y=25 width=10 height=16 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 +char id=236 x=0 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=237 x=24 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=238 x=453 y=2 width=10 height=18 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=0 +char id=239 x=270 y=25 width=11 height=16 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=0 +char id=240 x=77 y=44 width=12 height=15 xoffset=-1 yoffset=3 xadvance=12 page=0 chnl=0 +char id=241 x=86 y=25 width=12 height=17 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=0 +char id=242 x=100 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=243 x=112 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=244 x=429 y=2 width=10 height=18 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=0 +char id=245 x=124 y=25 width=12 height=17 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=0 +char id=246 x=335 y=25 width=10 height=16 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 +char id=247 x=303 y=61 width=10 height=12 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=0 +char id=248 x=428 y=61 width=14 height=12 xoffset=-3 yoffset=6 xadvance=12 page=0 chnl=0 +char id=249 x=36 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=250 x=74 y=25 width=10 height=17 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=251 x=441 y=2 width=10 height=18 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=0 +char id=252 x=295 y=25 width=10 height=16 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 +char id=253 x=72 y=2 width=10 height=21 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=254 x=417 y=2 width=10 height=18 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=255 x=48 y=2 width=10 height=21 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 +char id=8226 x=60 y=78 width=8 height=8 xoffset=1 yoffset=7 xadvance=13 page=0 chnl=0 +char id=8364 x=222 y=44 width=12 height=15 xoffset=-2 yoffset=3 xadvance=12 page=0 chnl=0 +kernings count=0 diff --git a/source/core/assets/images/ui/buttons/glass.atlas b/source/core/assets/images/ui/buttons/glass.atlas index 919126acb..4a7987fe5 100644 --- a/source/core/assets/images/ui/buttons/glass.atlas +++ b/source/core/assets/images/ui/buttons/glass.atlas @@ -6,686 +6,693 @@ filter: Linear, Linear repeat: none dot_gothic_16 rotate: false - xy: 1017, 1928 + xy: 1, 989 size: 505, 107 orig: 505, 107 offset: 0, 0 index: -1 dot_gothic_32 rotate: false - xy: 1, 853 + xy: 509, 1527 size: 505, 240 orig: 505, 240 offset: 0, 0 index: -1 Emulogic-zrEw rotate: false - xy: 1, 627 + xy: 1, 763 size: 505, 224 orig: 505, 224 offset: 0, 0 index: -1 determination_mono_18 rotate: false - xy: 1017, 1862 + xy: 1525, 1974 size: 505, 64 orig: 505, 64 offset: 0, 0 index: -1 determination_mono_18_bold rotate: false - xy: 509, 1766 + xy: 509, 1769 size: 506, 106 orig: 506, 106 offset: 0, 0 index: -1 +determination_mono_22 + rotate: false + xy: 1017, 1949 + size: 506, 89 + orig: 506, 89 + offset: 0, 0 + index: -1 determination_mono_32 rotate: false - xy: 1524, 1890 + xy: 509, 1380 size: 503, 145 orig: 503, 145 offset: 0, 0 index: -1 determination_mono_48_title rotate: false - xy: 1, 1639 + xy: 1, 1642 size: 506, 396 orig: 506, 396 offset: 0, 0 index: -1 emulogic_18 rotate: false - xy: 509, 1667 + xy: 1017, 1850 size: 505, 97 orig: 505, 97 offset: 0, 0 index: -1 game_paused_24 rotate: false - xy: 1, 1584 + xy: 1, 1587 size: 506, 53 orig: 506, 53 offset: 0, 0 index: -1 game_paused_title rotate: false - xy: 509, 1561 + xy: 1, 657 size: 502, 104 orig: 502, 104 offset: 0, 0 index: -1 glitch_24 rotate: false - xy: 509, 1874 + xy: 509, 1877 size: 506, 161 orig: 506, 161 offset: 0, 0 index: -1 glitch_title rotate: false - xy: 1, 1095 + xy: 1, 1098 size: 506, 487 orig: 506, 487 offset: 0, 0 index: -1 UI_Glass_Arrow_Large_01a rotate: false - xy: 607, 1223 + xy: 965, 1346 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Arrow_Medium_01a rotate: false - xy: 759, 1375 + xy: 99, 167 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Arrow_Small_01a rotate: false - xy: 99, 137 + xy: 251, 319 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Banner_01a rotate: false - xy: 1017, 1828 + xy: 1017, 1816 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Banner_01b rotate: false - xy: 251, 289 + xy: 403, 589 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Textfield_01a rotate: false - xy: 251, 289 + xy: 403, 589 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a1 rotate: false - xy: 305, 593 + xy: 509, 1194 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a3 rotate: false - xy: 305, 593 + xy: 509, 1194 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a2 rotate: false - xy: 509, 1223 + xy: 305, 623 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a2 rotate: false - xy: 509, 1223 + xy: 305, 623 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a3 rotate: false - xy: 661, 1375 + xy: 1, 167 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a1 rotate: false - xy: 661, 1375 + xy: 1, 167 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Lock_01a4 rotate: false - xy: 813, 1527 + xy: 153, 319 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a1 rotate: false - xy: 1, 137 + xy: 1017, 1782 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a2 rotate: false - xy: 153, 289 + xy: 1115, 1816 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a3 rotate: false - xy: 1017, 1794 + xy: 509, 1160 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Press_01a4 rotate: false - xy: 1115, 1828 + xy: 607, 1194 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Large_Release_01a4 rotate: false - xy: 1115, 1828 + xy: 607, 1194 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a1 rotate: false - xy: 403, 593 + xy: 403, 623 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a3 rotate: false - xy: 403, 593 + xy: 403, 623 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a2 rotate: false - xy: 813, 1493 + xy: 1115, 1782 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a2 rotate: false - xy: 813, 1493 + xy: 1115, 1782 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a3 rotate: false - xy: 911, 1527 + xy: 1213, 1816 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a1 rotate: false - xy: 911, 1527 + xy: 1213, 1816 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Lock_01a4 rotate: false - xy: 1, 103 + xy: 509, 1126 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a1 rotate: false - xy: 153, 255 + xy: 607, 1160 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a2 rotate: false - xy: 1115, 1794 + xy: 705, 1194 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a3 rotate: false - xy: 1213, 1828 + xy: 305, 555 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Press_01a4 rotate: false - xy: 305, 525 + xy: 1, 35 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Medium_Release_01a4 rotate: false - xy: 305, 525 + xy: 1, 35 size: 64, 32 orig: 64, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a1 _1 rotate: false - xy: 403, 559 + xy: 469, 623 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a3 rotate: false - xy: 403, 559 + xy: 469, 623 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a2_2 rotate: false - xy: 469, 593 + xy: 1181, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a2 rotate: false - xy: 469, 593 + xy: 1181, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a3_3 rotate: false - xy: 813, 1459 + xy: 1279, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a1 rotate: false - xy: 813, 1459 + xy: 1279, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Lock_01a4_4 rotate: false - xy: 879, 1493 + xy: 575, 1126 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a1_ rotate: false - xy: 977, 1527 + xy: 673, 1160 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a2 rotate: false - xy: 1, 69 + xy: 771, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a3 rotate: false - xy: 67, 103 + xy: 305, 521 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Press_01a4 rotate: false - xy: 153, 221 + xy: 371, 555 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Button_Small_Release_01a4 rotate: false - xy: 153, 221 + xy: 371, 555 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Large_01a rotate: false - xy: 219, 255 + xy: 1, 1 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Medium_01a rotate: false - xy: 1181, 1794 + xy: 965, 1312 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Checkmark_Small_01a rotate: false - xy: 1279, 1828 + xy: 99, 133 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Large_01a rotate: false - xy: 305, 491 + xy: 251, 285 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Medium_01a rotate: false - xy: 371, 525 + xy: 437, 589 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Cross_Small_01a rotate: false - xy: 607, 1189 + xy: 1215, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Dropdown_01a rotate: false - xy: 759, 1341 + xy: 1313, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Dropdown_Handle_01a rotate: false - xy: 437, 559 + xy: 609, 1126 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Fillbar_01a rotate: false - xy: 813, 1425 + xy: 707, 1160 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Fillbar_Filler_01a rotate: false - xy: 847, 1459 + xy: 805, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Horizontal_01a rotate: false - xy: 305, 559 + xy: 305, 589 size: 96, 32 orig: 96, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Inward_01a rotate: false - xy: 509, 1125 + xy: 1, 69 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 UI_Glass_Frame_Lite_01a rotate: false - xy: 913, 1493 + xy: 305, 487 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Frame_Standard_01a rotate: false - xy: 661, 1277 + xy: 153, 221 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 UI_Glass_Frame_Vertical_01a rotate: false - xy: 305, 393 + xy: 305, 389 size: 32, 96 orig: 32, 96 offset: 0, 0 index: -1 UI_Glass_Minus_Large_01a rotate: false - xy: 1, 35 + xy: 339, 521 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Minus_Medium_01a rotate: false - xy: 35, 69 + xy: 405, 555 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Minus_Small_01a rotate: false - xy: 153, 187 + xy: 965, 1278 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Large_01a rotate: false - xy: 187, 221 + xy: 99, 99 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Medium_01a rotate: false - xy: 1215, 1794 + xy: 251, 251 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Plus_Small_01a rotate: false - xy: 1313, 1828 + xy: 1249, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Scrollbar_01a rotate: false - xy: 339, 491 + xy: 1347, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Scrollbar_Handle_01a rotate: false - xy: 405, 525 + xy: 643, 1126 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a1 rotate: false - xy: 607, 1155 + xy: 741, 1160 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a2 rotate: false - xy: 759, 1307 + xy: 839, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a4 rotate: false - xy: 759, 1307 + xy: 839, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Select_01a3 rotate: false - xy: 847, 1425 + xy: 305, 355 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_01a rotate: false - xy: 881, 1459 + xy: 339, 487 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_Filler_01a rotate: false - xy: 947, 1493 + xy: 373, 521 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slider_Handle_01a rotate: false - xy: 305, 359 + xy: 965, 1244 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Available_01a rotate: false - xy: 1, 1 + xy: 1283, 1782 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Selected_01a rotate: false - xy: 35, 35 + xy: 1381, 1816 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Slot_Unavailable_01a rotate: false - xy: 187, 187 + xy: 677, 1126 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Bar_01a rotate: false - xy: 1249, 1794 + xy: 775, 1160 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Cover_01a rotate: false - xy: 1347, 1828 + xy: 873, 1194 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 UI_Glass_Toggle_Handle_01a rotate: false - xy: 339, 457 + xy: 339, 453 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 Weapon-Tower-Default rotate: false - xy: 153, 323 + xy: 153, 353 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 droid-tower-default rotate: false - xy: 1, 475 + xy: 509, 1228 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 fire-tower-default rotate: false - xy: 509, 1409 + xy: 1, 505 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 imageedit_2_8132799771 rotate: false - xy: 1, 323 + xy: 661, 1228 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 mine-tower-default rotate: false - xy: 153, 475 + xy: 1, 353 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 stun-tower-default rotate: false - xy: 509, 1257 + xy: 153, 505 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 tnt-tower-default rotate: false - xy: 661, 1409 + xy: 813, 1228 size: 150, 150 orig: 150, 150 offset: 0, 0 index: -1 wall-tower-default rotate: false - xy: 1, 171 + 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 d3077c5ee..8637af19f 100644 --- a/source/core/assets/images/ui/buttons/glass.json +++ b/source/core/assets/images/ui/buttons/glass.json @@ -12,6 +12,12 @@ com.badlogic.gdx.graphics.g2d.BitmapFont: { markupEnabled: false flip: false } + determination_mono_22: { + file: determination_mono_22.fnt + scaledSize: -1 + markupEnabled: false + flip: false + } determination_mono_32: { file: determination_mono_32.fnt scaledSize: -1 @@ -402,7 +408,7 @@ com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: { fontColor: White } small: { - font: determination_mono_18_bold + font: determination_mono_22 fontColor: White } } diff --git a/source/core/assets/images/ui/buttons/glass.png b/source/core/assets/images/ui/buttons/glass.png index 76461215e..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/src/main/com/csse3200/game/areas/ForestGameArea.java b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java index db2890793..8fccaf74b 100644 --- a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java +++ b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java @@ -206,16 +206,15 @@ public class ForestGameArea extends GameArea { "sounds/mobs/archerArrow.mp3" }; - private static final String backgroundMusic = "sounds/background/Sci-Fi1.ogg"; + private static final String BACKGROUND_MUSIC = "sounds/background/Sci-Fi1.ogg"; - private static final String[] forestMusic = {backgroundMusic}; + private static final String[] forestMusic = {BACKGROUND_MUSIC}; private Entity player; private Entity waves; /** * Initialise this ForestGameArea to use the provided TerrainFactory. - * - * @requires terrainFactory != null + * @requires terrainFactory != null */ public ForestGameArea() { super(); @@ -292,7 +291,6 @@ public void create() { 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); @@ -439,9 +437,6 @@ private void spawnProjectile(Vector2 position, short targetLayer, int space, int public void spawnMob(String entity, GridPoint2 randomPos, int health) { Entity mob; switch (entity) { - case "Xeno": - mob = NPCFactory.createXenoGrunt(health); - break; case "SplittingWaterSlime": mob = NPCFactory.createSplittingWaterSlime(health); break; @@ -893,7 +888,7 @@ private void spawnDroidTower() { } private void playMusic() { - Music music = ServiceLocator.getResourceService().getAsset(backgroundMusic, Music.class); + Music music = ServiceLocator.getResourceService().getAsset(BACKGROUND_MUSIC, Music.class); music.setLooping(true); music.setVolume(0.3f); music.play(); diff --git a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainComponent.java b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainComponent.java index 5c639fcac..c6c67b642 100644 --- a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainComponent.java +++ b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainComponent.java @@ -24,7 +24,6 @@ * shows the 'ground' in the game. Enabling/disabling this component will show/hide the terrain. */ public class TerrainComponent extends RenderComponent { - private static final Logger logger = LoggerFactory.getLogger(TerrainComponent.class); private static final int TERRAIN_LAYER = 0; private final TiledMap tiledMap; @@ -33,7 +32,6 @@ public class TerrainComponent extends RenderComponent { private final TerrainOrientation orientation; private final float tileSize; private TiledMapTileLayer.Cell lastHoveredCell = null; - private TiledMapTile originalTile = null; private TextureRegion originalRegion = null; @@ -107,41 +105,6 @@ public int getLayer() { return TERRAIN_LAYER; } - // TODO : This is just a visual effect that we might not need in the end but just keeping it here for now - public void colorTile(final int x, final int y) { - final TiledMapTileLayer tileLayer = (TiledMapTileLayer) tiledMap.getLayers().get(0); - final TiledMapTile originalTile = tileLayer.getCell(x, y).getTile(); - - ResourceService resourceService = ServiceLocator.getResourceService(); - - // Load all the tiles into an array - final TerrainTile[] terrainTiles = new TerrainTile[7]; - for (int i = 0; i < 7; i++) { - Texture texture = resourceService.getAsset("images/GrassTile/grass_tile_" + (i + 1) + ".png", Texture.class); - terrainTiles[i] = new TerrainTile(new TextureRegion(texture)); - } - - final float interval = 0.2f; // Switch every 0.2 seconds - final float duration = 1.4f; // 7 images * 0.2 seconds each - - Timer.schedule(new Timer.Task() { - float timeElapsed = 0.0f; - - @Override - public void run() { - timeElapsed += interval; - - if (timeElapsed >= duration) { - tileLayer.getCell(x, y).setTile(originalTile); // Reset to original tile after the total duration - this.cancel(); // End the timer task - } else { - int index = (int) (timeElapsed / interval); - tileLayer.getCell(x, y).setTile(terrainTiles[index]); - } - } - }, 0, interval, (int) (duration / interval) - 1); // Scheduling the task - } - /** * Highlights the tile under the mouse cursor by changing its texture region. * diff --git a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainFactory.java b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainFactory.java index f38977a92..d1bf5eae9 100644 --- a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainFactory.java +++ b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainFactory.java @@ -1,7 +1,6 @@ package com.csse3200.game.areas.terrain; import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.maps.tiled.TiledMap; @@ -9,7 +8,6 @@ import com.badlogic.gdx.maps.tiled.TiledMapTileLayer; import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell; import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; -import com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile; import com.badlogic.gdx.math.GridPoint2; import com.csse3200.game.components.CameraComponent; import com.csse3200.game.services.ResourceService; @@ -52,14 +50,12 @@ public TerrainComponent createTerrain(TerrainType terrainType) { ResourceService resourceService = ServiceLocator.getResourceService(); resourceService.loadTextures(new String[]{"images/terrain_use.png"}); resourceService.loadAll(); - switch (terrainType) { - case ALL_DEMO: - TextureRegion orthogonal = - new TextureRegion(resourceService.getAsset("images/terrain_use.png", Texture.class)); - return createTerrain(1f, orthogonal); - default: - return null; + if (terrainType == TerrainType.ALL_DEMO) { + TextureRegion orthogonal = + new TextureRegion(resourceService.getAsset("images/terrain_use.png", Texture.class)); + return createTerrain(1f, orthogonal); } + return null; } /** @@ -86,12 +82,10 @@ private TerrainComponent createTerrain(float tileWorldSize, TextureRegion terrai */ public TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) { - switch (orientation) { - case ORTHOGONAL: - return new OrthogonalTiledMapRenderer(tiledMap, tileScale); - default: - return null; + if (orientation == TerrainComponent.TerrainOrientation.ORTHOGONAL) { + return new OrthogonalTiledMapRenderer(tiledMap, tileScale); } + return null; } /** @@ -104,9 +98,9 @@ public TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) { private TiledMap createTiles(GridPoint2 tileSize, TextureRegion terrain) { TiledMap tiledMap = new TiledMap(); - TiledMapTileLayer Layer = new TiledMapTileLayer(20, 6, tileSize.x, tileSize.y); - fillInvisibleTiles(Layer, new GridPoint2(20, 6), terrain); - tiledMap.getLayers().add(Layer); + TiledMapTileLayer layer = new TiledMapTileLayer(20, 6, tileSize.x, tileSize.y); + fillInvisibleTiles(layer, new GridPoint2(20, 6), terrain); + tiledMap.getLayers().add(layer); return tiledMap; } diff --git a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainGrid.java b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainGrid.java deleted file mode 100644 index 667af8742..000000000 --- a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainGrid.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.csse3200.game.areas.terrain; - -public class TerrainGrid { -} 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 c4388e0cf..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 @@ -28,7 +28,7 @@ public class CurrencyDisplay extends UIComponent { private TextButton scrapsTb; private TextButton crystalsTb; private Sound clickSound; - private static final String defaultFont = "determination_mono_18"; + private static final String DEFAULT_FONT = "determination_mono_18"; /** * Adds actors to stage @@ -58,12 +58,15 @@ private void addActors() { table.add(scrapsTb).width(scrapsTb.getWidth() * 0.5f).height(scrapsTb.getHeight() * 0.5f); table.add(crystalsTb).width(crystalsTb.getWidth() * 0.5f).height(crystalsTb.getHeight() * 0.5f); stage.addActor(table); + + scrapsTb.addAction(new SequenceAction(Actions.fadeIn(4f))); + crystalsTb.addAction(new SequenceAction(Actions.fadeIn(8f))); } private TextButton createButton(String imageFilePath, int value) { Drawable drawable = new TextureRegionDrawable(new TextureRegion(new Texture(imageFilePath))); TextButton.TextButtonStyle style = new TextButton.TextButtonStyle( - drawable, drawable, drawable, getSkin().getFont(defaultFont)); + drawable, drawable, drawable, getSkin().getFont(DEFAULT_FONT)); // create button TextButton tb = new TextButton(String.format("%d", value), style); 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 3f569d147..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 @@ -4,10 +4,11 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Touchable; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; +import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.ui.TextTooltip; -import com.badlogic.gdx.scenes.scene2d.ui.TooltipManager; import com.badlogic.gdx.scenes.scene2d.utils.Drawable; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Align; @@ -16,7 +17,10 @@ public class EngineerCountDisplay extends UIComponent { private TextButton engineerTb; - private static final String defaultFont = "determination_mono_18"; + + private static final String DEFAULT_FONT = "determination_mono_18"; + + private static final float Z_INDEX = 2f; @Override public void create() { @@ -37,7 +41,7 @@ private void addActors() { Drawable drawable = new TextureRegionDrawable(new TextureRegion( new Texture("images/engineers/engineerBanner.png"))); TextButton.TextButtonStyle style = new TextButton.TextButtonStyle( - drawable, drawable, drawable, getSkin().getFont(defaultFont)); + drawable, drawable, drawable, getSkin().getFont(DEFAULT_FONT)); String text = String.format("%d", ServiceLocator.getGameEndService().getEngineerCount()); engineerTb = new TextButton(text, style); @@ -45,13 +49,15 @@ private void addActors() { engineerTb.getLabel().setAlignment(Align.right); engineerTb.setTouchable(Touchable.enabled); engineerTb.pad(0, 0, 0, 50); -// engineerTb.setTransform(true); + engineerTb.setTransform(true); TextTooltip tooltip = new TextTooltip( "Humans left. If this reaches 0, the game ends", getSkin()); engineerTb.addListener(tooltip); table.add(engineerTb).width(engineerTb.getWidth() * 0.5f).height(engineerTb.getHeight() * 0.5f); stage.addActor(table); + + engineerTb.addAction(new SequenceAction(Actions.fadeIn(4f))); } /** @@ -61,11 +67,16 @@ public void updateCount() { 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)))); -// } + 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)))); + } + } + + @Override + public float getZIndex() { + return Z_INDEX; } @Override diff --git a/source/core/src/main/com/csse3200/game/components/maingame/LevelProgressBar.java b/source/core/src/main/com/csse3200/game/components/maingame/LevelProgressBar.java new file mode 100644 index 000000000..d885beb87 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/components/maingame/LevelProgressBar.java @@ -0,0 +1,78 @@ +package com.csse3200.game.components.maingame; + +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.csse3200.game.screens.GameLevelData; +import com.csse3200.game.services.ServiceLocator; + +public class LevelProgressBar extends ProgressBar { + + static int selectedLevel = GameLevelData.getSelectedLevel(); + + /** + * @param width of the health bar + * @param height of the health bar + */ + public LevelProgressBar(int width, int height) { + super(0f, getMobCount(), 0.01f, false, new ProgressBarStyle()); + getStyle().background = getColoredDrawable(width, height, Color.RED); + getStyle().knob = new TextureRegionDrawable(new TextureRegion(new Texture("images/skeleton.png"))); + getStyle().knobBefore = getColoredDrawable(width, height, Color.GREEN); + + setWidth(width); + setHeight(height); + + setAnimateDuration(0.0f); + setValue(1f); + + setAnimateDuration(0.25f); + } + + /** + * Color filling for the Progress Bar + * @param width the width in pixels + * @param height the height in pixels + * @param color the color of the filling + * @return Drawable + */ + public static Drawable getColoredDrawable(int width, int height, Color color) { + Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888); + pixmap.setColor(color); + pixmap.fill(); + + TextureRegionDrawable drawable = new TextureRegionDrawable(new TextureRegion(new Texture(pixmap))); + + pixmap.dispose(); + + return drawable; + } + + /** + * Get the number of mobs based on the level + * @return number of total mobs + */ + public static int getMobCount() { + + switch (selectedLevel) { + // Desert + case 1 -> { // Ice + ServiceLocator.getWaveService().setTotalMobs(91); + return 91; + } + case 2 -> { // Lava + ServiceLocator.getWaveService().setTotalMobs(204); + return 204; + } + default -> { + ServiceLocator.getWaveService().setTotalMobs(27); + return 27; + } + } + } +} 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 efb046633..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 @@ -35,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 5a0d9e1bb..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 @@ -1,15 +1,22 @@ package com.csse3200.game.components.maingame; +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.EventListener; import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; +import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; 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; import com.csse3200.game.services.ServiceLocator; @@ -27,23 +34,38 @@ public class MainGameDisplay extends UIComponent { private static final float Z_INDEX = 2f; private final Table towerTable = new Table(); private final Table buttonTable = new Table(); - private String[] sounds = { + private final Table progressTable = new Table(); + private final Table levelNameTable = new Table(); + private final String[] sounds = { "sounds/ui/click/click_01.ogg", - "sounds/ui/hover/hover_01.ogg", "sounds/ui/open_close/open_01.ogg" }; + private String level; + private static final String[] levels = { + "Desert Planet", + "Ice Planet", + "Lava Planet" + }; private Sound click; - private Sound hover; private Sound openSound; - private Sound closeSound; - private GdxGame game; + private final GdxGame game; + private Array towers = new Array<>(); + private final Array towerButtons = new Array<>(); + private ImageButton tower1; + private ImageButton tower2; + private ImageButton tower3; + private ImageButton tower4; + private ImageButton tower5; + private LevelProgressBar progressbar; + private Entity pauseMenu; /** * The constructor for the display * @param screenSwitchHandle a handle back to the game entry point that manages screen switching */ - public MainGameDisplay(GdxGame screenSwitchHandle) { + public MainGameDisplay(GdxGame screenSwitchHandle, int level) { game = screenSwitchHandle; + this.level = levels[level]; } /** @@ -64,13 +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.top().left().padLeft(20f).padTop(20f); + levelNameTable.setFillParent(true); + // Stores tower defaults, in case towers haven't been set in the tower select screen TowerType[] defaultTowers = { TowerType.TNT, @@ -81,7 +109,7 @@ private void addActors() { }; // Fetch the selected tower types if set - Array towers = new Array<>(); + towers = new Array<>(); for (TowerType tower : ServiceLocator.getTowerTypes()) { towers.add(tower); @@ -103,14 +131,24 @@ private void addActors() { // Update the centrally located towerTypes list - ServiceLocator.setTowerTypes(towers); - // Create the buttons - TODO This needs overhauling to pretty buttons - TextButton tower1 = ButtonFactory.createButton(towers.get(0).getTowerName()); - TextButton tower2 = ButtonFactory.createButton(towers.get(1).getTowerName()); - TextButton tower3 = ButtonFactory.createButton(towers.get(2).getTowerName()); - TextButton tower4 = ButtonFactory.createButton(towers.get(3).getTowerName()); - TextButton tower5 = ButtonFactory.createButton(towers.get(4).getTowerName()); + tower1 = new ImageButton(skin, towers.get(0).getSkinName()); + towerButtons.add(tower1); + tower2 = new ImageButton(skin, towers.get(1).getSkinName()); + towerButtons.add(tower2); + tower3 = new ImageButton(skin, towers.get(2).getSkinName()); + towerButtons.add(tower3); + tower4 = new ImageButton(skin, towers.get(3).getSkinName()); + towerButtons.add(tower4); + tower5 = new ImageButton(skin, towers.get(4).getSkinName()); + towerButtons.add(tower5); + TextButton pauseBtn = ButtonFactory.createButton("Pause"); + // Starting animation for pause button + pauseBtn.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - 150); + pauseBtn.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - 200, + Gdx.graphics.getHeight() - 150, 1f, Interpolation.fastSlow))); + // Spawns a pause menu when the button is pressed. pauseBtn.addListener( new ChangeListener() { @@ -118,7 +156,27 @@ private void addActors() { public void changed(ChangeEvent changeEvent, Actor actor) { logger.debug("Pause button clicked"); openSound.play(0.4f); - PauseMenuFactory.createPauseMenu(game); + pauseMenu = PauseMenuFactory.createPauseMenu(game); + ServiceLocator.getTimeSource().setPaused(true); + } + }); + + + // Pause menu escape key opening listener + stage.addListener( + new InputListener() { + @Override + public boolean keyUp(InputEvent event, int keycode) { + if ((keycode == Input.Keys.ESCAPE) && !ServiceLocator.getTimeSource().getPaused()) { + openSound.play(0.4f); + pauseMenu = PauseMenuFactory.createPauseMenu(game); + ServiceLocator.getTimeSource().setPaused(true); + return true; + } else if ((keycode == Input.Keys.ESCAPE) && ServiceLocator.getTimeSource().getPaused()) { + pauseMenu.dispose(); + return false; + } + return false; } }); @@ -131,8 +189,14 @@ 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); } @@ -149,8 +213,14 @@ 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); } @@ -159,23 +229,51 @@ public void clicked(InputEvent event, float x, float y) { tower2.addListener(tower2Tooltip); tower3.addListener( - new ChangeListener() { + new ClickListener() { @Override - public void changed(ChangeEvent changeEvent, Actor actor) { - logger.debug("Tower 3 build button clicked"); - ServiceLocator.getCurrencyService().setTowerType(towers.get(2)); + 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 ChangeListener() { + new ClickListener() { @Override - public void changed(ChangeEvent changeEvent, Actor actor) { - logger.debug("Tower 4 build button clicked"); - ServiceLocator.getCurrencyService().setTowerType(towers.get(3)); + 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); } }); @@ -183,28 +281,69 @@ public void changed(ChangeEvent changeEvent, Actor actor) { tower4.addListener(tower4Tooltip); tower5.addListener( - new ChangeListener() { + new ClickListener() { @Override - public void changed(ChangeEvent changeEvent, Actor actor) { - logger.debug("Tower 5 build button clicked"); - ServiceLocator.getCurrencyService().setTowerType(towers.get(4)); + 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; @@ -214,8 +353,62 @@ public void changed(ChangeEvent changeEvent, Actor actor) { @Override public void draw(SpriteBatch batch) { // draw is handled by the stage + towerUpdate(); } + /** + * Update the level progress bar value + */ + public void updateLevelProgressBar() { + int totalSecs = ServiceLocator.getWaveService().totalMobs() - ServiceLocator.getWaveService().remainingMobsForLevel(); + progressbar.setValue(totalSecs); + } + + /** + * Update function for the tower build menu buttons that is called with every draw, updates button states + * depending on button selection and currency balance + */ + private void towerUpdate() { + // no tower selected, set all to off + if (ServiceLocator.getCurrencyService().getTower() == null) { + // toggle all buttons to off + towerToggle(null); + } else { + // for handling shortcut key selection of tower build buttons + for (int i = 0; i < towerButtons.size; i++) { + if (ServiceLocator.getCurrencyService().getTower() == towers.get(i)) { + towerToggle(towerButtons.get(i)); + } + } + } + // update button state based on currency balance + int balance = ServiceLocator.getCurrencyService().getScrap().getAmount(); + for (int i = 0; i < towerButtons.size; i++) { + towerButtons.get(i).setDisabled(Integer.parseInt(towers.get(i).getPrice()) > balance); + } + updateLevelProgressBar(); + } + + /** + * Helper method for toggling tower build buttons. The expected behaviour is that if one button is pressed, + * all other buttons should be set to off. If a null button value is passed in then all buttons are set to off. + *

+ * @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; @@ -225,6 +418,7 @@ public float getZIndex() { public void dispose() { buttonTable.clear(); towerTable.clear(); + unloadSounds(); super.dispose(); } @@ -235,6 +429,16 @@ public void loadSounds() { ServiceLocator.getResourceService().loadSounds(sounds); ServiceLocator.getResourceService().loadAll(); click = ServiceLocator.getResourceService().getAsset(sounds[0], Sound.class); - openSound = ServiceLocator.getResourceService().getAsset(sounds[2], 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))); } -} +} \ No newline at end of file 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 afa6b7369..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 @@ -1,28 +1,23 @@ package com.csse3200.game.components.maingame; import com.badlogic.gdx.Gdx; -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.actions.Actions; import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; -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.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; -import com.badlogic.gdx.scenes.scene2d.utils.Drawable; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.Null; -import com.csse3200.game.screens.TowerType; 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. @@ -33,7 +28,6 @@ public class UIElementsDisplay extends UIComponent { private final Table buttonTable = new Table(); private TextButton remainingMobsButton; private TextButton timerButton; - private final int timer = 110; @Override public void create() { @@ -48,25 +42,36 @@ private void addActors() { remainingMobsButton = ButtonFactory.createButton("Mobs:" + ServiceLocator.getWaveService().getEnemyCount()); - buttonTable.top().right().padTop(160f).padRight(80f); + 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(130f).padRight(80f); buttonTable.setFillParent(true); - buttonTable.add(remainingMobsButton).right();//.padTop(10f).padRight(10f); + buttonTable.add(remainingMobsButton).right(); buttonTable.row(); - buttonTable.add(timerButton);//.padRight(10f); + buttonTable.add(timerButton); stage.addActor(buttonTable); createTimerButton(); } - /** * This method updates the mob count button as mobs die in the game */ public void updateMobCount() { remainingMobsButton.setText("Mobs:" + ServiceLocator.getWaveService().getEnemyCount()); + remainingMobsButton.addListener( + new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + ServiceLocator.getWaveService().toggleDelay(); + } + } + ); } /** @@ -74,10 +79,11 @@ public void updateMobCount() { */ public void createTimerButton() { -// timerButton = new ButtonFactory().createButton("Next wave in:" -// + (ServiceLocator.getWaveService().getNextWaveTime() / 1000)); timerButton = ButtonFactory.createButton("Next wave in:" + (ServiceLocator.getWaveService().getNextWaveTime() / 1000)); + timerButton.setPosition(Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - 300); + timerButton.addAction(new SequenceAction(Actions.moveTo(Gdx.graphics.getWidth() - 445, + Gdx.graphics.getHeight() - 300, 1f, Interpolation.fastSlow))); buttonTable.row(); buttonTable.add(timerButton).padRight(10f); } @@ -86,27 +92,28 @@ public void createTimerButton() { * This method updates the text for timer button. */ public void updateTimerButton() { - int totalSecs = (int) ((ServiceLocator.getWaveService().getNextWaveTime() - - ServiceLocator.getTimeSource().getTime()) / 1000); + if (!(ServiceLocator.getWaveService().getGamePaused())) { + 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) { + // 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)) { - createTimerButton(); } - timerButton.setText("Next wave in: " + finalTime); - } else { - timerButton.addAction(new SequenceAction(Actions.fadeOut(1f), Actions.removeActor())); -// buttonTable.removeActor(timerButton); - stage.act(); - stage.draw(); + 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)) { + createTimerButton(); + } + timerButton.setText("Next wave in: " + finalTime); + } else { + timerButton.addAction(new SequenceAction(Actions.fadeOut(1f), Actions.removeActor())); + stage.act(); + stage.draw(); + } } } 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 5896c2f10..1127cd4ad 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 @@ -1,7 +1,7 @@ package com.csse3200.game.components.npc; import com.csse3200.game.components.Component; -import com.csse3200.game.components.tasks.mobtask.MobType; +import com.csse3200.game.components.tasks.MobTask.MobType; import com.csse3200.game.entities.Entity; import com.csse3200.game.entities.factories.NPCFactory; import com.csse3200.game.services.ServiceLocator; 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 e0241e660..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,15 +1,23 @@ 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; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; 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; @@ -21,8 +29,8 @@ public class PauseMenuButtonComponent extends UIComponent { private static final float Z_INDEX = 2f; private Window window; private final GdxGame game; - private static final float windowSizeX = 300; - private static final float windowSizeY = 400; + private static final float WINDOW_SIZE_X = 300; + private static final float WINDOW_SIZE_Y = 400; private final String[] sounds = { "sounds/ui/click/click_01.ogg", "sounds/ui/open_close/close_01.ogg", @@ -47,7 +55,7 @@ public void create() { */ private void addActors() { - window = new Window("Game Paused", new Skin(Gdx.files.internal("images/ui/buttons/glass.json"))); + window = new Window("", new Skin(Gdx.files.internal("images/ui/buttons/glass.json"))); TextButton continueBtn = ButtonFactory.createButton("Continue"); continueBtn.pad(20f); @@ -65,6 +73,7 @@ public void changed(ChangeEvent changeEvent, Actor actor) { logger.debug("Continue button clicked"); click.play(0.5f); closeSound.play(0.5f); + ServiceLocator.getTimeSource().setPaused(false); entity.dispose(); } }); @@ -96,7 +105,7 @@ public void changed(ChangeEvent changeEvent, Actor actor) { } }); - window.setKeepWithinStage(true); + window.setResizable(true); window.setModal(true); window.setTouchable(Touchable.enabled); @@ -110,10 +119,10 @@ public void changed(ChangeEvent changeEvent, Actor actor) { window.add(planetSelectBtn).center(); window.row(); window.add(mainMenuBtn).center(); - window.setWidth(windowSizeX); - window.setHeight(windowSizeY); - window.setX((ServiceLocator.getRenderService().getStage().getWidth() / 2) - (windowSizeX / 2)); - window.setY((ServiceLocator.getRenderService().getStage().getHeight() / 2) - (windowSizeY / 2)); + 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)); stage.addActor(window); } @@ -140,6 +149,9 @@ public float getZIndex() { @Override public void dispose() { + click.play(0.5f); + closeSound.play(0.5f); + ServiceLocator.getTimeSource().setPaused(false); window.clear(); window.remove(); super.dispose(); 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 e2c08c105..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 @@ -13,6 +13,7 @@ public class PauseMenuTimeStopComponent extends Component { private Array freezeList; public PauseMenuTimeStopComponent() { + // Not implemented } /** @@ -20,6 +21,7 @@ public PauseMenuTimeStopComponent() { */ @Override public void create() { + ServiceLocator.getWaveService().toggleGamePause(); freezeList = ServiceLocator.getEntityService().getEntities(); for (Entity pauseTarget : freezeList) { if (pauseTarget.getId() != getEntity().getId()) { @@ -35,6 +37,7 @@ public void create() { */ @Override public void dispose() { + ServiceLocator.getWaveService().toggleGamePause(); for (Entity pauseTarget : freezeList) { pauseTarget.setEnabled(true); } 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 1c597fc2e..502f1c4b7 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 @@ -48,7 +48,7 @@ public class DroidCombatTask extends DefaultTask implements PriorityTask { public enum STATE { IDLE, UP, DOWN, SHOOT_UP, SHOOT_DOWN, WALK, DIE } - public STATE towerState = STATE.WALK; + private STATE towerState = STATE.WALK; /** * @param priority Task priority when targets are detected (0 when nothing detected). Must be a positive integer. @@ -156,7 +156,6 @@ public void updateTowerState() { owner.getEntity().getEvents().trigger(GO_UP); towerState = STATE.IDLE; - } } case DIE -> { @@ -166,13 +165,6 @@ public void updateTowerState() { } } } - /** - * For stopping the running task - */ - @Override - public void stop() { - super.stop(); - } /** * Returns the current state of the tower. @@ -183,6 +175,10 @@ public STATE getState() { return this.towerState; } + public void setState(STATE state) { + this.towerState = state; + } + /** * Returns the current priority of the task. * @return active priority value if targets detected, inactive priority otherwise 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 c5fc7f0bf..39215cb9e 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 @@ -36,7 +36,7 @@ public class MobAttackTask extends DefaultTask implements PriorityTask { 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 @@ -50,7 +50,6 @@ 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) { this.priority = priority; @@ -69,9 +68,7 @@ public void start() { startTime = timeSource.getTime(); Vector2 mobPosition = owner.getEntity().getCenterPosition(); this.maxRangePosition.set(0, mobPosition.y); - //owner.getEntity().getEvents().trigger(IDLE); - endTime = timeSource.getTime() + (INTERVAL * 500); -// owner.getEntity().getEvents().trigger("shootStart"); + long endTime = timeSource.getTime() + (INTERVAL * 500); } /** @@ -130,7 +127,6 @@ public void updateMobState() { 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; } @@ -193,11 +189,10 @@ 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. * - * returns the Weapon (Melee or Projectile) the mob will use to attack the target. null if immune target or no target + * @return 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; 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 478623bcf..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 @@ -7,10 +7,8 @@ import com.csse3200.game.entities.Entity; import com.csse3200.game.entities.factories.DropFactory; import com.csse3200.game.physics.PhysicsEngine; -import com.csse3200.game.physics.raycast.RaycastHit; import com.csse3200.game.services.ServiceLocator; import com.csse3200.game.services.GameTime; -//import com.csse3200.game.rendering.DebugRenderer; /** @@ -60,7 +58,6 @@ public void update() { public void updateBossState() { mobHealth = owner.getEntity().getComponent(CombatStatsComponent.class).getHealth(); - // TODO: inset a bit that picks from a list of drop options and drops this if (mobIsDead(mobHealth)) { killMob(); 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 f50ca2ebd..a437fbdbf 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,7 +1,7 @@ package com.csse3200.game.components.tasks; -import com.csse3200.game.components.tasks.mobtask.MobTask; -import com.csse3200.game.components.tasks.mobtask.MobType; +import com.csse3200.game.components.tasks.MobTask.MobTask; +import com.csse3200.game.components.tasks.MobTask.MobType; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; @@ -29,11 +29,9 @@ public class MobDodgeTask extends MobTask { * Initialises a mob dodge task with a specified wander range, wait time, and * priority level. * - * @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. + * @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. */ public MobDodgeTask(MobType mobType, int priority) { super(mobType); 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 5ad20684e..08aa0b627 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,4 +1,4 @@ -package com.csse3200.game.components.tasks.mobtask; +package com.csse3200.game.components.tasks.MobTask; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Timer; @@ -15,6 +15,7 @@ import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.components.tasks.MobTask.MobType; /** * The AI Task for all general mobs. This task handles the sequencing for melee @@ -163,7 +164,6 @@ public void update() { runFlag = true; } } - case DEATH, DEFAULT -> {} } } @@ -180,67 +180,6 @@ private void animate() { } 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"); - // } - // } - // } } /** 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 8bf4e3b7e..335b2a7e7 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,4 +1,4 @@ -package com.csse3200.game.components.tasks.mobtask; +package com.csse3200.game.components.tasks.MobTask; public enum MobType { SKELETON(true), diff --git a/source/core/src/main/com/csse3200/game/components/tasks/SpawnWaveTask.java b/source/core/src/main/com/csse3200/game/components/tasks/SpawnWaveTask.java index d6c4a3d85..912a2451b 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/SpawnWaveTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/SpawnWaveTask.java @@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory; public class SpawnWaveTask extends DefaultTask implements PriorityTask { - private static final Logger logger = LoggerFactory.getLogger(SpawnWaveTask.class); + private final GameTime globalTime; private long endTime = 0; private final int SPAWNING_INTERVAL = 10; diff --git a/source/core/src/main/com/csse3200/game/components/tasks/TNTTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/TNTTowerCombatTask.java index bcb210846..48e28fdd9 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/TNTTowerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/TNTTowerCombatTask.java @@ -35,7 +35,7 @@ public class TNTTowerCombatTask extends DefaultTask implements PriorityTask { private final GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); - public boolean readToDelete = false; + private boolean readToDelete = false; public enum STATE { IDLE, EXPLODE, REMOVE @@ -103,19 +103,8 @@ public void updateTowerState() { owner.getEntity().getEvents().trigger(DAMAGE); towerState = STATE.REMOVE; } - case REMOVE -> { - readToDelete = true; - } + case REMOVE -> readToDelete = true; } - - - } - /** - * For stopping the running task - */ - @Override - public void stop() { - super.stop(); } /** @@ -124,7 +113,6 @@ public void stop() { */ @Override public int getPriority() { - if (isReadyToDelete()) { owner.getEntity().setFlagForDelete(true); return -1; 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 c9f5c2b33..6ea6dd9d3 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 @@ -40,11 +40,11 @@ public class TowerCombatTask extends DefaultTask implements PriorityTask { private final float maxRange; private Vector2 towerPosition = new Vector2(10, 10); // initial placeholder value - will be overwritten private final Vector2 maxRangePosition = new Vector2(); - private PhysicsEngine physics; - private GameTime timeSource; + private final PhysicsEngine physics; + private final GameTime timeSource; private long endTime; private final RaycastHit hit = new RaycastHit(); - private static final Logger logger = LoggerFactory.getLogger(ForestGameArea.class); + private static final Logger logger = LoggerFactory.getLogger(TowerCombatTask.class); private boolean shoot = true; private enum STATE { @@ -154,26 +154,8 @@ public void updateTowerState() { Entity newProjectile = ProjectileFactory.createFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f)); newProjectile.setScale(1.1f, 0.8f); - newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.5), (float) (owner.getEntity().getPosition().y)); + newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.5), (owner.getEntity().getPosition().y)); ServiceLocator.getEntityService().register(newProjectile); - - // * TEMPRORARYYYYYYYY PLS DON'T DELETE THIS - // PIERCE FIREBALL - // Entity pierceFireball = ProjectileFactory.createPierceFireBall(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f)); - // pierceFireball.setPosition((float) (owner.getEntity().getPosition().x + 0), (float) (owner.getEntity().getPosition().y + 0.4)); - // ServiceLocator.getEntityService().register(pierceFireball); - - // RICOCHET FIREBALL - // Entity ricochetProjectile = ProjectileFactory.createRicochetFireball(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f), 0); - - // ricochetProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0), (float) (owner.getEntity().getPosition().y + 0.4)); - // ServiceLocator.getEntityService().register(ricochetProjectile); - - // SPLIT FIREWORKS FIREBALLL - // Entity splitFireWorksProjectile = ProjectileFactory.createSplitFireWorksFireball(PhysicsLayer.NPC, new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f,2f), 16); - - // splitFireWorksProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.75), (float) (owner.getEntity().getPosition().y + 0.4)); - // ServiceLocator.getEntityService().register(splitFireWorksProjectile); } } shoot = !shoot; diff --git a/source/core/src/main/com/csse3200/game/components/tasks/human/EngineerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/human/EngineerCombatTask.java index a6894551f..3598a245a 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/human/EngineerCombatTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/human/EngineerCombatTask.java @@ -34,8 +34,7 @@ public class EngineerCombatTask extends DefaultTask implements PriorityTask { // weaponCapacity is the number of shots fired before the engineer has to reload private static final int weaponCapacity = 10; private int shotsFired = 0; // Tracks the number of shots fired in the current cycle - - private Vector2 engineerPosition = new Vector2(10, 50); // Placeholder value for the Engineer's position. + private final Vector2 maxRangePosition = new Vector2(); private PhysicsEngine physics; private GameTime timeSource; @@ -68,7 +67,8 @@ public EngineerCombatTask(float maxRange) { public void start() { super.start(); // Set the tower's coordinates - this.engineerPosition = owner.getEntity().getCenterPosition(); + // Placeholder value for the Engineer's position. + Vector2 engineerPosition = owner.getEntity().getCenterPosition(); this.maxRangePosition.set(engineerPosition.x + maxRange, engineerPosition.y); // Default to idle mode owner.getEntity().getEvents().trigger(IDLE_RIGHT); diff --git a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java index 41f031858..3e197601e 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java @@ -1,18 +1,14 @@ package com.csse3200.game.components.tasks.waves; -import com.badlogic.gdx.math.GridPoint2; -import com.csse3200.game.entities.Entity; + import com.csse3200.game.services.GameTime; -import com.csse3200.game.services.ServiceLocator; + import java.util.*; public class WaveClass { private HashMap entities; - private GameTime gameTime; - private long startTime; private List wave; - private Random rand = new Random(); private int mobIndex; /** diff --git a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java index 2b04e4bc0..d49816692 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java @@ -83,7 +83,6 @@ public void start() { this.currentWave = level.getWave(currentWaveIndex); ServiceLocator.getWaveService().setEnemyCount(currentWave.getSize()); logger.info("Wave {} starting with {} enemies", currentWaveIndex, ServiceLocator.getWaveService().getEnemyCount()); - this.waveStart.play(); // endTime = globalTime.getTime() + (SPAWNING_INTERVAL * 1000); } @@ -105,15 +104,16 @@ public void update() { // logger.info("No enemies remaining, begin next wave"); if (nextWaveAt == 0) { logger.info("Next wave in 10 seconds"); + this.waveEnd.play(); nextWaveAt = globalTime.getTime() + 10000; ServiceLocator.getWaveService().setNextWaveTime(nextWaveAt); } else { if (globalTime.getTime() >= nextWaveAt || ServiceLocator.getWaveService().shouldSkip()) { + this.waveStart.play(); ServiceLocator.getWaveService().toggleDelay(); currentWaveIndex++; ServiceLocator.getWaveService().setNextWaveTime(0); nextWaveAt = 0; - this.waveEnd.play(); this.waveInProgress = true; this.level.setWaveIndex(currentWaveIndex); // Set the service wave count to the current wave index. 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 19406ff99..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 @@ -92,30 +92,28 @@ void animateDeath() { void animateDefault() { animator.startAnimation("idle");} - //TODO: For the time being, these items will be positioned here. Next, we should create a component that enables an entity to fire projectiles. - /** * Fires a projectile upwards from the entity's current position. */ void shootUp() { - Entity Projectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, new Vector2(100, + Entity projectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, new Vector2(100, entity.getPosition().y), new Vector2(2,2), ProjectileEffects.SLOW, false); - Projectile.setScale(new Vector2(0.5f,0.5f)); - Projectile.setPosition((float) (entity.getPosition().x + 0.2), + projectile.setScale(new Vector2(0.5f,0.5f)); + projectile.setPosition((float) (entity.getPosition().x + 0.2), (float) (entity.getPosition().y + 0.5)); - ServiceLocator.getEntityService().register(Projectile); + ServiceLocator.getEntityService().register(projectile); } /** * Fires a projectile downwards from the entity's current position. */ void shootDown() { - Entity Projectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, new Vector2(100, + Entity projectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.NPC, new Vector2(100, entity.getPosition().y), new Vector2(2,2), ProjectileEffects.SLOW, false); - Projectile.setScale(new Vector2(0.5f,0.5f)); - Projectile.setPosition((float) (entity.getPosition().x + 0.2), - (float) (entity.getPosition().y)); - ServiceLocator.getEntityService().register(Projectile); + projectile.setScale(new Vector2(0.5f,0.5f)); + projectile.setPosition((float) (entity.getPosition().x + 0.2), + (entity.getPosition().y)); + ServiceLocator.getEntityService().register(projectile); } } diff --git a/source/core/src/main/com/csse3200/game/components/tower/TNTDamageComponent.java b/source/core/src/main/com/csse3200/game/components/tower/TNTDamageComponent.java index e7ba86ef6..c01556781 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/TNTDamageComponent.java +++ b/source/core/src/main/com/csse3200/game/components/tower/TNTDamageComponent.java @@ -67,8 +67,6 @@ private void applyTNTDamage() { for (int i = 0; i < allEntities.size; i++) { Entity otherEntity = allEntities.get(i); - if (entity == otherEntity) continue; // Skip the source entity - Vector2 positionSource = entity.getPosition(); Vector2 positionOther = otherEntity.getPosition(); @@ -77,7 +75,7 @@ private void applyTNTDamage() { HitboxComponent otherHitbox = otherEntity.getComponent(HitboxComponent.class); // Check for null components and log specifics - if (sourceHitbox == null || otherHitbox == null) { + if (sourceHitbox == null || otherHitbox == null || entity == otherEntity) { continue; } 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 1ceb66b31..65185b27e 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 @@ -12,8 +12,8 @@ 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.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; 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 c0526e42b..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 @@ -27,25 +27,23 @@ public class WaveFactory { private static final Logger logger = LoggerFactory.getLogger(WaveFactory.class); private static Random rand = new Random(); - - // TODO: include necromancer private static final ArrayList MELEE_MOBS = new ArrayList<>(Arrays.asList( - "Skeleton", "Coat", "DragonKnight" + "Skeleton", "Coat", "DragonKnight", "Necromancer" )); private static final ArrayList> lvl1Structure = new ArrayList<>(Arrays.asList( new ArrayList<>(Arrays.asList("Coat" )), new ArrayList<>(Arrays.asList("Coat", "WaterQueen" - )), new ArrayList<>(Arrays.asList("WaterQueen", "WaterQueen" - )), new ArrayList<>(Arrays.asList("Coat", "WaterQueen", "Coat" + )), new ArrayList<>(Arrays.asList("WaterQueen", "SplittingWaterSlime" + )), new ArrayList<>(Arrays.asList("Coat", "WaterQueen", "SplittingWaterSlime" )) )); private static final ArrayList> lvl2Structure = new ArrayList<>(Arrays.asList( new ArrayList<>(Arrays.asList("Skeleton" - )), new ArrayList<>(Arrays.asList("Skeleton", "SplittingNightBorne" - )), new ArrayList<>(Arrays.asList("Skeleton", "Wizard" )), new ArrayList<>(Arrays.asList("Skeleton", "ArcaneArcher" + )), new ArrayList<>(Arrays.asList("Skeleton", "Wizard" + )), new ArrayList<>(Arrays.asList("Skeleton", "SplittingNightBorne" )), new ArrayList<>(Arrays.asList("Wizard", "SplittingNightBorne" )), new ArrayList<>(Arrays.asList("SplittingNightBorne", "Skeleton" )), new ArrayList<>(Arrays.asList("Wizard", "SplittingNightBorne" @@ -58,28 +56,20 @@ public class WaveFactory { new ArrayList<>(Arrays.asList("Necromancer" )), new ArrayList<>(Arrays.asList("Necromancer", "DodgingDragon" )), new ArrayList<>(Arrays.asList("Necromancer", "FireWorm" - )), new ArrayList<>(Arrays.asList("Necromancer", "FireWorm" - )), new ArrayList<>(Arrays.asList("SplittingRocky", "FireWorm" + )), new ArrayList<>(Arrays.asList("Necromancer", "DeflectFireWizard" + )), new ArrayList<>(Arrays.asList("DeflectFireWizard", "FireWorm" )), new ArrayList<>(Arrays.asList("DodgingDragon", "FireWorm" )), new ArrayList<>(Arrays.asList("DodgingDragon", "Necromancer" )), new ArrayList<>(Arrays.asList("FireWorm", "Necromancer" - )), new ArrayList<>(Arrays.asList("DeflectFireWiza","SplittingRocky", "Necromancer" - )), new ArrayList<>(Arrays.asList("DodgingDragon", "DeflectFireWizard", "SplittingRocky", "Necromancer" - )), new ArrayList<>(Arrays.asList("FireWorm", "DeflectWizard", "DodgingDragon" - )), new ArrayList<>(Arrays.asList("FireWorm", "DeflectWizard", "Necromancer" - )), new ArrayList<>(Arrays.asList("Necromancer", "DeflectFireWizard", "SplittingRocky", "DodgingDragon", "FireWorm" + )), new ArrayList<>(Arrays.asList("DeflectFireWizard", "Necromancer" + )), new ArrayList<>(Arrays.asList("DodgingDragon", "DeflectFireWizard", "Necromancer" + )), new ArrayList<>(Arrays.asList("FireWorm", "Necromancer", "DodgingDragon" + )), new ArrayList<>(Arrays.asList("FireWorm", "SplittingRocky", "Necromancer" + )), new ArrayList<>(Arrays.asList("SplittingRocky", "DeflectFireWizard", "FireWorm" + )), new ArrayList<>(Arrays.asList("DeflectFireWizard", "SplittingRocky", "Necromancer", "DodgingDragon", "FireWorm" )) )); - // The base health for the different mobs - private static int MELEE_BASE_HEALTH = 80; - private static int RANGE_BASE_HEALTH = 60; - - // Base health of the bosses - private static int LVL1_BOSS_BASE_HEALTH = 500; - private static int LVL2_BOSS_BASE_HEALTH = 1000; - private static int LVL3_BOSS_BASE_HEALTH = 2000; - private static final String BOSS_1 = "IceBoss"; private static final String BOSS_2 = "PatrickBoss"; private static final String BOSS_3 = "FireBoss"; @@ -139,6 +129,11 @@ public static LevelWaves createLevel(int chosenLevel) { String boss = ""; int bossHealth; int minMobs; + // Base health of the bosses + int LVL1_BOSS_BASE_HEALTH = 500; + int LVL2_BOSS_BASE_HEALTH = 1000; + int LVL3_BOSS_BASE_HEALTH = 2000; + switch (chosenLevel) { case 2: boss = BOSS_2; @@ -160,7 +155,7 @@ public static LevelWaves createLevel(int chosenLevel) { break; } - int totalMobs = 0; +// int totalMobs = 0; // Create mxWaves number of waves with mob stats increasing int atWave = 1; for (ArrayList wave : possibleMobs) { @@ -176,21 +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; + num = rand.nextInt(minMobs - currentMobs - (2 * leftToSort) - 2) + 2; + System.out.println(num + " for " + mob + " at wave " + atWave); currentMobs += num; } // Calculate the health + int RANGE_BASE_HEALTH = 60; int health = RANGE_BASE_HEALTH; if (MELEE_MOBS.contains(mob)) { + // The base health for the different mobs + int MELEE_BASE_HEALTH = 80; health = MELEE_BASE_HEALTH; } int[] mobStats = {num, health + (atWave * chosenLevel)}; mobs.put(mob, mobStats); leftToSort --; - totalMobs += num; +// totalMobs += num; } minMobs ++; level.addWave(new WaveClass(mobs)); @@ -200,9 +200,9 @@ public static LevelWaves createLevel(int chosenLevel) { // Add boss wave HashMap bossMob = new HashMap<>(); bossMob.put(boss, new int[]{1, bossHealth}); - totalMobs ++; +// totalMobs ++; - ServiceLocator.getWaveService().setTotalMobs(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 666a6878a..97e293747 100644 --- a/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java +++ b/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java @@ -7,7 +7,6 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.Array; -import com.csse3200.game.areas.ForestGameArea; import com.csse3200.game.entities.Entity; import com.csse3200.game.entities.EntityService; import com.csse3200.game.entities.factories.TowerFactory; @@ -23,7 +22,7 @@ * DropInputComponent */ public class BuildInputComponent extends InputComponent { - private static final Logger logger = LoggerFactory.getLogger(ForestGameArea.class); + private static final Logger logger = LoggerFactory.getLogger(BuildInputComponent.class); private final EntityService entityService; private final Camera camera; private final String[] sounds = { @@ -33,7 +32,6 @@ public class BuildInputComponent extends InputComponent { private Sound buildSound; private Sound errorSound; private Array towers = new Array<>(); - private Array defaultTowers = new Array<>(); private boolean multipleTowerBuild = false; /** @@ -46,7 +44,7 @@ public BuildInputComponent(Camera camera) { loadSounds(); towers.addAll(ServiceLocator.getTowerTypes()); - logger.debug("selected towers in buildInputComponent are " + towers); + logger.debug(String.format("selected towers in buildInputComponent are %s", towers)); TowerType[] defaultTowerTypes = { TowerType.TNT, TowerType.DROID, @@ -54,6 +52,7 @@ public BuildInputComponent(Camera camera) { TowerType.WALL, TowerType.WEAPON }; + Array defaultTowers = new Array<>(); defaultTowers.addAll(defaultTowerTypes); if (towers.isEmpty()) { @@ -85,20 +84,19 @@ public Camera getCamera() { @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { - Vector3 worldCoordinates = new Vector3((float) screenX , (float) screenY, 0); + Vector3 worldCoordinates = new Vector3(screenX , screenY, 0); getCamera().unproject(worldCoordinates); // translate from screen to world coordinates Vector2 cursorPosition = new Vector2(worldCoordinates.x, worldCoordinates.y); // determine if the tile is unoccupied boolean tileOccupied = entityService.entitiesInTile((int)cursorPosition.x, (int)cursorPosition.y); - logger.debug("Tile is occupied: " + tileOccupied ); + logger.debug(String.format("Tile is occupied: %s", tileOccupied)); // check that no entities are occupying the tile if (!tileOccupied) { - logger.debug("spawning a tower at {}, {}", cursorPosition.x, cursorPosition.y); + logger.debug(String.format("spawning a tower at %f, %f", cursorPosition.x, cursorPosition.y)); return buildTower((int)cursorPosition.x, (int)cursorPosition.y); } else { - // TODO: Create a tile indication of invalid placement here?? return false; } } @@ -144,8 +142,9 @@ public boolean keyUp(int keycode) { /** * * @param keycode one of the constants in {@link Input.Keys} - * @return + * @return true if the multipleBuild key is down, otherwise false */ + @Override public boolean keyDown(int keycode) { if (keycode == Input.Keys.CONTROL_LEFT) { multipleTowerBuild = true; @@ -187,9 +186,7 @@ public boolean buildTower(int x, int y) { }; // build the selected tower newTower.setPosition(x, y); - EntityService entityService; - entityService = ServiceLocator.getEntityService(); if (entityService == null){ return false; } diff --git a/source/core/src/main/com/csse3200/game/physics/PhysicsLayer.java b/source/core/src/main/com/csse3200/game/physics/PhysicsLayer.java index 32487b9a8..3aa7896f7 100644 --- a/source/core/src/main/com/csse3200/game/physics/PhysicsLayer.java +++ b/source/core/src/main/com/csse3200/game/physics/PhysicsLayer.java @@ -2,9 +2,8 @@ public class PhysicsLayer { public static final short NONE = 0; - public static final short DEFAULT = (1 << 0); public static final short ENGINEER = (1 << 1); - public static final short BOMBSHIP = (1 << 1); + public static final short BOMBSHIP = ENGINEER; // Terrain obstacle, e.g. trees public static final short OBSTACLE = (1 << 2); // NPC (Non-Playable Character) colliders diff --git a/source/core/src/main/com/csse3200/game/rendering/CameraShaker.java b/source/core/src/main/com/csse3200/game/rendering/CameraShaker.java index cbfc432d1..37e67e847 100644 --- a/source/core/src/main/com/csse3200/game/rendering/CameraShaker.java +++ b/source/core/src/main/com/csse3200/game/rendering/CameraShaker.java @@ -18,7 +18,6 @@ */ public class CameraShaker { - private static final Logger logger = LoggerFactory.getLogger(CameraShaker.class); private Camera camera; private boolean isShaking = false; private float origShakeRadius; @@ -29,7 +28,7 @@ public class CameraShaker { private float timer; private Vector3 offset; private Vector3 currentPosition; - public Vector3 origPosition; + private Vector3 origPosition; /** * Constructor @@ -45,7 +44,6 @@ public CameraShaker(Camera camera, float shakeRadius, float minimumShakeRadius, this.offset = new Vector3(); this.currentPosition = new Vector3(); this.origPosition = camera.position.cpy(); - logger.info("Start | Camera Position: " + camera.position); reset(); } @@ -69,7 +67,6 @@ public CameraShaker(Camera camera){ this.offset = new Vector3(); this.currentPosition = new Vector3(); this.origPosition = camera.position.cpy(); - logger.info("Start | Camera Position: " + camera.position); reset(); } @@ -143,10 +140,16 @@ public boolean isCameraShaking(){ Private methods below */ + /** + * Seeds a random angle between 1 and 360 degrees. + */ private void seedRandomAngle(){ randomAngle = MathUtils.random(1, 360); } + /** + * Computes the camera offset based on the current shake radius and random angle. + */ private void computeCameraOffset(){ float sine = MathUtils.sinDeg(randomAngle); float cosine = MathUtils.cosDeg(randomAngle); @@ -154,12 +157,17 @@ private void computeCameraOffset(){ offset.y = sine * shakeRadius; } + /** + * Computes the current camera position based on the original position and the offset. + */ private void computeCurrentPosition() { currentPosition.x = origPosition.x + offset.x; currentPosition.y = origPosition.y + offset.y; - } + /** + * Reduces the shake effect over time based on the fall off factor. + */ private void diminishShake(){ if(shakeRadius < minimumShakeRadius){ reset(); @@ -170,14 +178,21 @@ private void diminishShake(){ randomAngle = MathUtils.random(1, 360); } + /** + * Validates and adjusts the provided parameters for the shake effect. + * + * @param shakeRadius The intended maximum shake radius. + * @param minimumShakeRadius The intended minimum shake radius. + * @param radiusFallOffFactor The intended fall off factor for shake radius. + */ private void checkParameters(float shakeRadius, float minimumShakeRadius, float radiusFallOffFactor) { // validation checks on parameters - if (radiusFallOffFactor >= 1f) radiusFallOffFactor = 0.9f; // radius fall off factor must be less than 1 - if (radiusFallOffFactor <= 0) radiusFallOffFactor = 0.9f; // radius fall off factor must be greater than 0 - if (shakeRadius <= 0) shakeRadius = 30f; // shake radius must be greater than 0 - if (minimumShakeRadius < 0) minimumShakeRadius = 0; // minimum shake radius must be greater than 0 - if (minimumShakeRadius >= shakeRadius) // minimum shake radius must be less than shake radius, if not - minimumShakeRadius = 0.15f * shakeRadius; // then set minimum shake radius to 15% of shake radius + if (radiusFallOffFactor >= 1f) radiusFallOffFactor = 0.9f; + if (radiusFallOffFactor <= 0) radiusFallOffFactor = 0.9f; + if (shakeRadius <= 0) shakeRadius = 30f; + if (minimumShakeRadius < 0) minimumShakeRadius = 0; + if (minimumShakeRadius >= shakeRadius) + minimumShakeRadius = 0.15f * shakeRadius; this.shakeRadius = shakeRadius; this.origShakeRadius = shakeRadius; @@ -185,16 +200,40 @@ private void checkParameters(float shakeRadius, float minimumShakeRadius, float this.radiusFallOffFactor = radiusFallOffFactor; } + /** + * Retrieves the current shake radius. + * + * @return The current shake radius. + */ public float getShakeRadius() { return shakeRadius; } + /** + * Retrieves the minimum shake radius. + * + * @return The minimum shake radius. + */ public float getMinimumRadius() { return minimumShakeRadius; } + /** + * Retrieves the fall off factor for the shake radius. + * + * @return The radius fall off factor. + */ public float getFallOffFactor() { return radiusFallOffFactor; } + /** + * Retrieves the original position of the camera before the shake effect began. + * + * @return The original position as a {@link Vector3} object. + */ + public Vector3 getOrigPosition() { + return origPosition; + } + } \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java b/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java index f14c14de0..ec0ab7ea0 100644 --- a/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java @@ -32,6 +32,7 @@ import org.w3c.dom.Text; import static com.badlogic.gdx.scenes.scene2d.ui.Table.Debug.table; +import static com.csse3200.game.ui.UIComponent.getSkin; /** * The game screen where you can choose a planet to play on. @@ -46,6 +47,7 @@ public class LevelSelectScreen extends ScreenAdapter { private Stage stage; private AnimatedText text; private BitmapFont font; + private static final String defaultFont = "determination_mono_32"; private Sprite background; private String[] bgm = { @@ -60,7 +62,7 @@ public class LevelSelectScreen extends ScreenAdapter { private static final String BG_PATH = "planets/background.png"; public LevelSelectScreen(GdxGame game) { - font = new BitmapFont(); + font = getSkin().getFont(defaultFont); text = new AnimatedText(INTRO_TEXT, font, 0.05f); this.game = game; diff --git a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java index 9d7e252fe..93471edd3 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java @@ -11,7 +11,6 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.csse3200.game.GdxGame; import com.csse3200.game.areas.ForestGameArea; import com.csse3200.game.components.gamearea.PerformanceDisplay; @@ -34,7 +33,7 @@ /** * The game screen containing the main game. * - *

Details on libGDX screens: https://happycoding.io/tutorials/libgdx/game-screens + *

Details on libGDX screens: ... */ public class MainGameScreen extends ScreenAdapter { private static final Logger logger = LoggerFactory.getLogger(MainGameScreen.class); @@ -84,13 +83,13 @@ public class MainGameScreen extends ScreenAdapter { private final GdxGame game; private final Renderer renderer; private final PhysicsEngine physicsEngine; - - private InputComponent upgradedInputHandler; + private final InputComponent buildHandler; + private final InputComponent upgradedInputHandler; static int screenWidth = Gdx.graphics.getWidth(); static int screenHeight = Gdx.graphics.getHeight(); private Entity ui; - public static int viewportWidth = screenWidth; - public static int viewportHeight= screenHeight; + public static final int viewportWidth = screenWidth; + public static final int viewportHeight= screenHeight; int selectedLevel = GameLevelData.getSelectedLevel(); private final OrthographicCamera camera; @@ -108,9 +107,6 @@ public MainGameScreen(GdxGame game) { batch = new SpriteBatch(); - Stage stage = new Stage(new ScreenViewport()); - - logger.debug("Initialising main game screen services"); ServiceLocator.registerTimeSource(new GameTime()); @@ -133,7 +129,7 @@ public MainGameScreen(GdxGame game) { renderer.getCamera().getCamera().position.set(CAMERA_POSITION.x,CAMERA_POSITION.y,0); renderer.getDebug().renderPhysicsWorld(physicsEngine.getWorld()); InputComponent inputHandler = new DropInputComponent(renderer.getCamera().getCamera()); - InputComponent buildHandler = new BuildInputComponent(renderer.getCamera().getCamera()); + buildHandler = new BuildInputComponent(renderer.getCamera().getCamera()); upgradedInputHandler = new UpgradeUIComponent(renderer.getCamera().getCamera(), renderer.getStage()); InputComponent engineerInputHandler = new EngineerInputComponent(game, renderer.getCamera().getCamera()); ServiceLocator.getInputService().register(inputHandler); @@ -224,7 +220,7 @@ public void render(float delta) { } else if (ServiceLocator.getWaveService().isLevelCompleted()) { // Check if all waves are completed and the level has been completed logger.info("Main game level completed detected, go to win screen"); - ui.getEvents().trigger("lose"); // needs to change to: ui.getEvents().trigger("win"); + ui.getEvents().trigger("win"); // needs to change to: ui.getEvents().trigger("win"); // Add something in to unlock the next planet/level? } } @@ -300,8 +296,9 @@ private void createUI() { .addComponent(new MainGameActions(this.game)) .addComponent(ServiceLocator.getWaveService().getDisplay()) //.addComponent(new MainGameWinDisplay()) <- needs to be uncommented when team 3 have implemented the ui - .addComponent(new MainGameDisplay(this.game)) + .addComponent(new MainGameDisplay(this.game, selectedLevel)) .addComponent(new Terminal()) + .addComponent(buildHandler) .addComponent(inputComponent) .addComponent(new TerminalDisplay()); diff --git a/source/core/src/main/com/csse3200/game/screens/TowerType.java b/source/core/src/main/com/csse3200/game/screens/TowerType.java index 1be6c2bc9..78ee04192 100644 --- a/source/core/src/main/com/csse3200/game/screens/TowerType.java +++ b/source/core/src/main/com/csse3200/game/screens/TowerType.java @@ -1,22 +1,23 @@ package com.csse3200.game.screens; public enum TowerType { - WEAPON("Weapon Tower", "The Weapon Tower is a simple and basic turret that fires rapid shots at enemies dealing damage over time.", + WEAPON("Weapon Tower", "weapon_tower", "The Weapon Tower is a simple and basic turret that fires rapid shots at enemies dealing damage over time.", 0, "15", "images/turret-select/Weapon-Tower-Default.png", "images/turret-select/Weapon-Tower-Clicked.png"), - TNT("TNT Tower", "The TNT Tower launches explosive projectiles, dealing area damage to groups of enemies.", + TNT("TNT Tower", "tnt_tower", "The TNT Tower launches explosive projectiles, dealing area damage to groups of enemies.", 1, "30", "images/turret-select/tnt-tower-default.png", "images/turret-select/tnt-tower-clicked.png"), - DROID("Droid Tower", "Droid Towers deploy robotic helpers that assist in combat and provide support to nearby turrets.", + DROID("Droid Tower", "droid_tower", "Droid Towers deploy robotic helpers that assist in combat and provide support to nearby turrets.", 2, "45", "images/turret-select/droid-tower-default.png", "images/turret-select/droid-tower-clicked.png"), - WALL("Wall Tower", "The Wall Tower creates barriers to block enemy paths, slowing down their progress.", + WALL("Wall Tower", "wall", "The Wall Tower creates barriers to block enemy paths, slowing down their progress.", 3, "45", "images/turret-select/wall-tower-default.png", "images/turret-select/wall-tower-clicked.png"), - FIRE("Fire Tower", "The Fire Tower emits flames, causing damage over time to enemies caught in its fiery radius.", + FIRE("Fire Tower", "fire_tower", "The Fire Tower emits flames, causing damage over time to enemies caught in its fiery radius.", 4, "45", "images/turret-select/fire-tower-default.png", "images/turret-select/fire-tower-clicked.png"), - STUN("Stun Tower", "The Stun Tower releases electric shocks that temporarily immobilize and damage enemies.", + STUN("Stun Tower", "stun_tower", "The Stun Tower releases electric shocks that temporarily immobilize and damage enemies.", 5, "45", "images/turret-select/stun-tower-default.png", "images/turret-select/stun-tower-clicked.png"), - INCOME("Income Tower", "The Income Tower generates additional in-game currency over time.", + INCOME("Income Tower", "income_tower", "The Income Tower generates additional in-game currency over time.", 6, "10", "images/turret-select/mine-tower-default.png", "images/turret-select/mine-tower-clicked.png"); private final String towerName; + private final String skinName; private final String description; private final int id; private final String cost; @@ -24,8 +25,9 @@ public enum TowerType { private final String clickedImage; - TowerType(String towerName, String description, int id, String cost, String defaultImage, String clickedImage) { + TowerType(String towerName, String skinName, String description, int id, String cost, String defaultImage, String clickedImage) { this.towerName = towerName; + this.skinName = skinName; this.description = description; this.id = id; this.cost = cost; @@ -37,6 +39,8 @@ public enum TowerType { public String getTowerName() { return towerName; } + public String getSkinName() { return skinName; } + public String getDescription() { return description; } public String getPrice() { return cost; } diff --git a/source/core/src/main/com/csse3200/game/services/GameEndService.java b/source/core/src/main/com/csse3200/game/services/GameEndService.java index a97762059..8be490699 100644 --- a/source/core/src/main/com/csse3200/game/services/GameEndService.java +++ b/source/core/src/main/com/csse3200/game/services/GameEndService.java @@ -55,7 +55,7 @@ public void updateEngineerCount() { * @return the warning threshold int */ public float getThreshold() { - return (float)(0.25 * STARTING_COUNT); + return (float)(0.3 * STARTING_COUNT); } /** diff --git a/source/core/src/main/com/csse3200/game/services/GameTime.java b/source/core/src/main/com/csse3200/game/services/GameTime.java index ad60c9e59..8ac6f9d5a 100644 --- a/source/core/src/main/com/csse3200/game/services/GameTime.java +++ b/source/core/src/main/com/csse3200/game/services/GameTime.java @@ -7,9 +7,10 @@ /** Controls the game time */ public class GameTime { - private static Logger logger = LoggerFactory.getLogger(GameTime.class); + private static final Logger logger = LoggerFactory.getLogger(GameTime.class); private final long startTime; private float timeScale = 1f; + private boolean paused = false; public GameTime() { startTime = TimeUtils.millis(); @@ -44,4 +45,12 @@ public long getTime() { public long getTimeSince(long lastTime) { return getTime() - lastTime; } + + public boolean getPaused() { + return paused; + } + + public void setPaused(boolean status) { + paused = status; + } } diff --git a/source/core/src/main/com/csse3200/game/services/ServiceLocator.java b/source/core/src/main/com/csse3200/game/services/ServiceLocator.java index 7c16fc03f..f2273efae 100644 --- a/source/core/src/main/com/csse3200/game/services/ServiceLocator.java +++ b/source/core/src/main/com/csse3200/game/services/ServiceLocator.java @@ -14,11 +14,11 @@ /** * A simplified implementation of the Service Locator pattern: - * https://martinfowler.com/articles/injection.html#UsingAServiceLocator + * ... * *

Allows global access to a few core game services. * Warning: global access is a trap and should be used extremely sparingly. - * Read the wiki for details (https://github.com/UQcsse3200/game-engine/wiki/Service-Locator). + * Read the wiki for details (...). */ public class ServiceLocator { private static final Logger logger = LoggerFactory.getLogger(ServiceLocator.class); diff --git a/source/core/src/main/com/csse3200/game/services/WaveService.java b/source/core/src/main/com/csse3200/game/services/WaveService.java index a32f6c0f2..5b95d3766 100644 --- a/source/core/src/main/com/csse3200/game/services/WaveService.java +++ b/source/core/src/main/com/csse3200/game/services/WaveService.java @@ -20,6 +20,8 @@ public class WaveService { private int spawnDelay; private boolean skipDelay = false; + private boolean gamePaused = false; + private long pauseBeginTime = 0; private int levelEnemyCount = 0; private int remainingLevelEnemyCount = 0; @@ -166,6 +168,27 @@ public boolean shouldSkip() { return this.skipDelay; } + /** + * Return whether the game is currently paused or not. + * @return the gamePaused variable. + */ + public boolean getGamePaused() {return this.gamePaused;} + + /** + * Toggles whether the game is paused or not, to keep track of how long the game is paused. + * When unpaused, offsets the NextWaveTime by however long the game has been paused. + */ + public void toggleGamePause() { + if (gamePaused) { + long pauseDuration = ServiceLocator.getTimeSource().getTime() - pauseBeginTime; + long updatedNextWaveTime = getNextWaveTime() + pauseDuration; + setNextWaveTime(updatedNextWaveTime); + } else { + pauseBeginTime = ServiceLocator.getTimeSource().getTime(); + } + gamePaused = !gamePaused; + } + /** * retrieve the number of enemies in the level * */ diff --git a/source/core/src/test/com/csse3200/game/components/DodgingComponentTest.java b/source/core/src/test/com/csse3200/game/components/DodgingComponentTest.java index 05369c3a5..0cac4e836 100644 --- a/source/core/src/test/com/csse3200/game/components/DodgingComponentTest.java +++ b/source/core/src/test/com/csse3200/game/components/DodgingComponentTest.java @@ -14,8 +14,8 @@ import com.csse3200.game.components.npc.DodgingComponent; import com.csse3200.game.components.tasks.MobDodgeTask; 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.components.tasks.MobTask.MobTask; +import com.csse3200.game.components.tasks.MobTask.MobType; import com.csse3200.game.entities.Entity; import com.csse3200.game.entities.EntityService; import com.csse3200.game.entities.factories.NPCFactory; diff --git a/source/core/src/test/com/csse3200/game/components/SplitMoblingsTest.java b/source/core/src/test/com/csse3200/game/components/SplitMoblingsTest.java index a28f836a1..d21af300c 100644 --- a/source/core/src/test/com/csse3200/game/components/SplitMoblingsTest.java +++ b/source/core/src/test/com/csse3200/game/components/SplitMoblingsTest.java @@ -19,7 +19,7 @@ import com.badlogic.gdx.math.Vector2; import com.csse3200.game.components.npc.SplitMoblings; -import com.csse3200.game.components.tasks.mobtask.MobType; +import com.csse3200.game.components.tasks.MobTask.MobType; import com.csse3200.game.entities.Entity; import com.csse3200.game.entities.EntityService; import com.csse3200.game.entities.factories.NPCFactory; diff --git a/source/core/src/test/com/csse3200/game/components/pausemenu/PauseMenuTimeStopComponentTest.java b/source/core/src/test/com/csse3200/game/components/pausemenu/PauseMenuTimeStopComponentTest.java index 65cf8cb8b..f097b5bb3 100644 --- a/source/core/src/test/com/csse3200/game/components/pausemenu/PauseMenuTimeStopComponentTest.java +++ b/source/core/src/test/com/csse3200/game/components/pausemenu/PauseMenuTimeStopComponentTest.java @@ -3,7 +3,9 @@ import com.csse3200.game.entities.Entity; import com.csse3200.game.entities.EntityService; import com.csse3200.game.extensions.GameExtension; +import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.services.WaveService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -17,6 +19,10 @@ public class PauseMenuTimeStopComponentTest { void beforeEach() { EntityService entityService = new EntityService(); ServiceLocator.registerEntityService(entityService); + WaveService waveService = new WaveService(); + ServiceLocator.registerWaveService(waveService); + GameTime gameTime = new GameTime(); + ServiceLocator.registerTimeSource(gameTime); entity = mock(Entity.class); when(entity.getId()).thenReturn(-1); //Ensure it does not coincide with the pause menu's ID entityService.register(entity); diff --git a/source/core/src/test/com/csse3200/game/components/tasks/DroidCombatTaskTest.java b/source/core/src/test/com/csse3200/game/components/tasks/DroidCombatTaskTest.java index 5878ea061..c7f71512e 100644 --- a/source/core/src/test/com/csse3200/game/components/tasks/DroidCombatTaskTest.java +++ b/source/core/src/test/com/csse3200/game/components/tasks/DroidCombatTaskTest.java @@ -64,7 +64,7 @@ public void testUpdateTowerStateWithTargetInRange() { entity.getEvents().addListener(DroidCombatTask.SHOOT_DOWN,shootDown); //Jump to IDLE state droidCombatTask.start(); - droidCombatTask.towerState = DroidCombatTask.STATE.IDLE; + droidCombatTask.setState(DroidCombatTask.STATE.IDLE); ServiceLocator.getPhysicsService().getPhysics().update(); entity.update(); @@ -110,7 +110,7 @@ public void testUpdateTowerStateWithTargetNotInRange() { entity.getEvents().addListener(DroidCombatTask.IDLE, idle); entity.getEvents().addListener(DroidCombatTask.ATTACK_UP,attackUp); //Jump to IDLE state - droidCombatTask.towerState = DroidCombatTask.STATE.IDLE; + droidCombatTask.setState(DroidCombatTask.STATE.IDLE); ServiceLocator.getPhysicsService().getPhysics().update(); entity.update(); diff --git a/source/core/src/test/com/csse3200/game/components/tasks/EngineerCombatTaskTest.java b/source/core/src/test/com/csse3200/game/components/tasks/EngineerCombatTaskTest.java index bf638a663..70236cac5 100644 --- a/source/core/src/test/com/csse3200/game/components/tasks/EngineerCombatTaskTest.java +++ b/source/core/src/test/com/csse3200/game/components/tasks/EngineerCombatTaskTest.java @@ -27,7 +27,6 @@ @ExtendWith(GameExtension.class) class EngineerCombatTaskTest { - private final int MAX_RANGE = 10; private EngineerCombatTask COMBAT_TASK; private Entity MOCK_ENGINEER; @@ -69,6 +68,7 @@ void setUp() { resourceService.loadAll(); // Create a mock engineer and add the combat task. + int MAX_RANGE = 10; COMBAT_TASK = new EngineerCombatTask(MAX_RANGE); MOCK_ENGINEER = EngineerFactory.createEngineer(); MOCK_ENGINEER.getComponent(AITaskComponent.class).addTask(COMBAT_TASK); diff --git a/source/core/src/test/com/csse3200/game/entities/factories/PauseMenuFactoryTest.java b/source/core/src/test/com/csse3200/game/entities/factories/PauseMenuFactoryTest.java index e62fe61cc..1feb7101f 100644 --- a/source/core/src/test/com/csse3200/game/entities/factories/PauseMenuFactoryTest.java +++ b/source/core/src/test/com/csse3200/game/entities/factories/PauseMenuFactoryTest.java @@ -7,8 +7,10 @@ import com.csse3200.game.entities.EntityService; import com.csse3200.game.extensions.GameExtension; import com.csse3200.game.rendering.RenderService; +import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ResourceService; import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.services.WaveService; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; @@ -27,6 +29,10 @@ public class PauseMenuFactoryTest { void beforeEach() { EntityService entityService = new EntityService(); ServiceLocator.registerEntityService(entityService); + WaveService waveService = new WaveService(); + ServiceLocator.registerWaveService(waveService); + GameTime gameTime = new GameTime(); + ServiceLocator.registerTimeSource(gameTime); RenderService renderService = mock(RenderService.class); when(renderService.getStage()).thenReturn(mock(Stage.class)); ServiceLocator.registerRenderService(renderService); diff --git a/source/core/src/test/com/csse3200/game/entities/factories/TowerFactoryTest.java b/source/core/src/test/com/csse3200/game/entities/factories/TowerFactoryTest.java index 2b5aa28b7..e3d20b53a 100644 --- a/source/core/src/test/com/csse3200/game/entities/factories/TowerFactoryTest.java +++ b/source/core/src/test/com/csse3200/game/entities/factories/TowerFactoryTest.java @@ -160,20 +160,13 @@ public void testCreateBaseTowerPhysicsComponentStaticBody() { PhysicsComponent physicsComponent5 = tntTower.getComponent(PhysicsComponent.class); PhysicsComponent physicsComponent6 = droidTower.getComponent(PhysicsComponent.class); - assertTrue(physicsComponent.getBody().getType() == BodyType.StaticBody, - "PhysicsComponent should be of type StaticBody"); - assertTrue(physicsComponent1.getBody().getType() == BodyType.StaticBody, - "PhysicsComponent1 should be of type StaticBody"); - assertTrue(physicsComponent2.getBody().getType() == BodyType.StaticBody, - "PhysicsComponent2 should be of type StaticBody"); - assertTrue(physicsComponent3.getBody().getType() == BodyType.StaticBody, - "StunTower's PhysicsComponent should be of type StaticBody"); - assertTrue(physicsComponent4.getBody().getType() == BodyType.StaticBody, - "FireTower's PhysicsComponent should be of type StaticBody"); - assertTrue(physicsComponent5.getBody().getType() == BodyType.StaticBody, - "TNT tower's PhysicsComponent should be of type StaticBody"); - assertTrue(physicsComponent6.getBody().getType() == BodyType.StaticBody, - "Droid Tower's PhysicsComponent should be of type StaticBody"); + assertSame(physicsComponent.getBody().getType(), BodyType.StaticBody, "PhysicsComponent should be of type StaticBody"); + assertSame(physicsComponent1.getBody().getType(), BodyType.StaticBody, "PhysicsComponent1 should be of type StaticBody"); + assertSame(physicsComponent2.getBody().getType(), BodyType.StaticBody, "PhysicsComponent2 should be of type StaticBody"); + assertSame(physicsComponent3.getBody().getType(), BodyType.StaticBody, "StunTower's PhysicsComponent should be of type StaticBody"); + assertSame(physicsComponent4.getBody().getType(), BodyType.StaticBody, "FireTower's PhysicsComponent should be of type StaticBody"); + assertSame(physicsComponent5.getBody().getType(), BodyType.StaticBody, "TNT tower's PhysicsComponent should be of type StaticBody"); + assertSame(physicsComponent6.getBody().getType(), BodyType.StaticBody, "Droid Tower's PhysicsComponent should be of type StaticBody"); } @Test @@ -213,14 +206,9 @@ public void testWeaponTowerCombatStatsComponentAndCostComponent() { @Test public void testWallTowerCombatStatsComponentAndCostComponent() { - - assertTrue(wallTower.getComponent(CombatStatsComponent.class).getHealth() == 300, - "Health should be 300"); - assertTrue(wallTower.getComponent(CombatStatsComponent.class).getBaseAttack() == 0, - "BaseAttack should be 0"); - assertTrue(wallTower.getComponent(CostComponent.class).getCost() == 45, - "Cost should be 5"); - + assertEquals(300, wallTower.getComponent(CombatStatsComponent.class).getHealth(), "Health should be 300"); + assertEquals(0, wallTower.getComponent(CombatStatsComponent.class).getBaseAttack(), "BaseAttack should be 0"); + assertEquals(45, wallTower.getComponent(CostComponent.class).getCost(), "Cost should be 45"); } @Test diff --git a/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java b/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java index 6abe8ec1a..eca488c8f 100644 --- a/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java +++ b/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java @@ -1,232 +1,298 @@ -//package com.csse3200.game.entities.factories; -// -//import com.csse3200.game.components.tasks.waves.LevelWaves; -//import com.badlogic.gdx.assets.AssetManager; -//import com.csse3200.game.components.tasks.waves.LevelWaves; -//import com.csse3200.game.components.tasks.waves.WaveClass; -//import com.csse3200.game.extensions.GameExtension; -//import com.csse3200.game.physics.PhysicsService; -//import com.csse3200.game.rendering.DebugRenderer; -//import com.csse3200.game.rendering.RenderService; -//import com.csse3200.game.screens.GameLevelData; -//import com.csse3200.game.services.GameTime; -//import com.csse3200.game.services.ResourceService; -//import com.csse3200.game.services.ServiceLocator; -//import com.csse3200.game.services.WaveService; -//import org.junit.jupiter.api.BeforeEach; -//import org.junit.jupiter.api.Disabled; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.api.extension.ExtendWith; -//import org.mockito.junit.jupiter.MockitoExtension; -// -//import static org.junit.jupiter.api.Assertions.*; -//import static org.mockito.Mockito.*; -// -//import com.csse3200.game.entities.Entity; -// -//import java.security.Provider; -//import java.util.ArrayList; -//import java.util.Arrays; -//import java.util.List; -//import java.util.Map; -// -//@ExtendWith(GameExtension.class) -//@ExtendWith(MockitoExtension.class) -//class WaveFactoryTest { -// -// private LevelWaves lvl1; -// private LevelWaves lvl2; -// private LevelWaves lvl3; -// -// private final int MIN_HEALTH = 60; -// private final int MIN_BOSS_HEALTH = 80; -// -// // level stats for level 1 - water planet -// private final int LVL1_DIFF = 2; -// private final int LVL1_WAVES = 5; -// private final int LVL1_CHOSEN_LVL = 1; -// private final ArrayList LVL1_MOBS = new ArrayList<>(Arrays.asList("Coat", "SplittingWaterSlime", "WaterQueen")); -// private final String LVL1_BOSS = "IceBoss"; -// -// // level stats for level 2 - magic planet -// private final int LVL2_DIFF = 3; -// private final int LVL2_WAVES = 10; -// private final int LVL2_CHOSEN_LVL = 0; -// private final ArrayList LVL2_MOBS = new ArrayList<>(Arrays.asList("ArcaneArcher", "SplittingNightBorne", "Skeleton", "DeflectWizard")); -// private final String LVL2_BOSS = "PatrickBoss"; -// -// // level stats for level 3 - fire planet -// private final int LVL3_DIFF = 5; -// private final int LVL3_WAVES = 15; -// private final int LVL3_CHOSEN_LVL = 2; -// private final ArrayList LVL3_MOBS = new ArrayList<>(Arrays.asList("Xeno", "DodgingDragon", "FireWorm")); -// private final String LVL3_BOSS = "FireBoss"; -//// private final String LVL3_BOSS = "FireBoss"; -// //TODO: make this a fire boss in sprint 4 -// -// private static final String[] waveSounds = { -// "sounds/waves/wave-start/Wave_Start_Alarm.ogg", -// "sounds/waves/wave-end/Wave_Over_01.ogg" -// }; -// -// @BeforeEach -// void setUp() { -// GameTime gameTime = mock(GameTime.class); -// ServiceLocator.registerTimeSource(gameTime); -// ServiceLocator.registerPhysicsService(new PhysicsService()); -// RenderService render = new RenderService(); -// render.setDebug(mock(DebugRenderer.class)); -// ServiceLocator.registerRenderService(render); -// ResourceService resourceService = mock(ResourceService.class); -// ServiceLocator.registerResourceService(resourceService); -// WaveService waveService = new WaveService(); -// ServiceLocator.registerWaveService(waveService); -// ServiceLocator.getResourceService().loadSounds(waveSounds); -// -// lvl1 = WaveFactory.createLevel(LVL1_DIFF, LVL1_WAVES, LVL1_CHOSEN_LVL); -// lvl2 = WaveFactory.createLevel(LVL2_DIFF, LVL2_WAVES, LVL2_CHOSEN_LVL); -// lvl3 = WaveFactory.createLevel(LVL3_DIFF, LVL3_WAVES, LVL3_CHOSEN_LVL); -// } -// -// @Test -// void createBaseWaves() { -// GameLevelData.setSelectedLevel(0); -// Entity level1 = WaveFactory.createWaves(); -// assertNotNull(level1); -// -// GameLevelData.setSelectedLevel(1); -// Entity level2 = WaveFactory.createWaves(); -// assertNotNull(level2); -// -// GameLevelData.setSelectedLevel(2); -// Entity level3 = WaveFactory.createWaves(); -// assertNotNull(level3); -// } -// -// @Test -// void testCreateLevel() { -// assertNotNull(lvl1); -// assertNotNull(lvl2); -// assertNotNull(lvl3); -// } -// -// /** -// * The three following tests ensure that every wave in the level is created correctly -// * Since the waves are stored in a hashmap, by definition the mobs are unique and this -// * quality does not have to be checked. -// * */ -// @Test -// void testLevel1Creation() { -// List lvl1Mobs = lvl1.getWaves(); -// -// int waveNum = 1; -// for (WaveClass wave : lvl1Mobs) { -// -// // check the number of mobs in a wave -// if (waveNum % 5 != 0) { -// assertEquals(2, wave.getEntities().size(), "Wave should contain 2 mobs."); -// } else { -// assertEquals(3, wave.getEntities().size(), "Wave should contain 3 mobs: 2 general and 1 boss."); -// } -// -// // check if the boss is in the wave if it is a boss wave -// if (waveNum % 5 == 0) { -// assertTrue(wave.getEntities().containsKey(LVL1_BOSS), "This wave should contain a boss."); -// } -// -// // check the health of the mobs and ensure the mobs are the correct type -// for (Map.Entry entry : wave.getEntities().entrySet()) { -// String mob = entry.getKey(); -// int[] spawn = entry.getValue(); -// -// if (waveNum % 5 != 0) { -// assertTrue(LVL1_MOBS.contains(mob), "This mob is not assigned to this level."); -// assertEquals(MIN_HEALTH + waveNum, spawn[1], "The health of the mob should be " + MIN_HEALTH + waveNum + " ."); -// } else { -// if (mob == LVL1_BOSS) { -// assertEquals(MIN_BOSS_HEALTH + waveNum, spawn[1], "The health of the boss should be " + MIN_BOSS_HEALTH + waveNum + " ."); -// } -// } -// } -// -// waveNum++; -// } -// assertEquals(6, waveNum, "The should be 5 waves making numWave 6."); -// } -// @Test -// void testLevel2Creation() { -// -// List lvl1Mobs = lvl2.getWaves(); -// -// int waveNum = 1; -// for (WaveClass wave : lvl1Mobs) { -// -// // check the number of mobs in a wave -// if (waveNum % 5 != 0) { -// assertEquals(2, wave.getEntities().size(), "Wave should contain 2 mobs."); -// } else { -// assertEquals(3, wave.getEntities().size(), "Wave should contain 3 mobs: 2 general and 1 boss."); -// } -// -// // check if the boss is in the wave if it is a boss wave -// if (waveNum % 5 == 0) { -// assertTrue(wave.getEntities().containsKey(LVL2_BOSS), "This wave should contain a boss."); -// } -// -// for (Map.Entry entry : wave.getEntities().entrySet()) { -// String mob = entry.getKey(); -// int[] spawn = entry.getValue(); -// -// if (waveNum % 5 != 0) { -// assertTrue(LVL2_MOBS.contains(mob)); -// assertEquals(MIN_HEALTH + (waveNum * 2), spawn[1], "The health of the mob should be " + MIN_HEALTH + (waveNum * 2) + " ."); -// } else { -// if (mob == LVL2_BOSS) { -// assertEquals(MIN_BOSS_HEALTH + (waveNum * 2), spawn[1], "The health of the boss should be " + MIN_BOSS_HEALTH + (waveNum * 2) + " ."); -// } -// } -// } -// -// waveNum++; -// } -// assertEquals(11, waveNum, "There should be 10 waves making numWave 11."); -// } -// @Test -// void testLevel3Creation() { -// -// List lvl1Mobs = lvl3.getWaves(); -// -// int waveNum = 1; -// for (WaveClass wave : lvl1Mobs) { -// // check the number of mobs in a wave -// if (waveNum % 5 != 0) { -// assertEquals(2, wave.getEntities().size(), "Wave should contain 2 mobs."); -// } else { -// assertEquals(3, wave.getEntities().size(), "Wave should contain 3 mobs: 2 general and 1 boss."); -// } -// -// // check if the boss is in the wave if it is a boss wave -// if (waveNum % 5 == 0) { -// assertTrue(wave.getEntities().containsKey(LVL3_BOSS), "This wave should contain a boss."); -// } -// -// // check the health of the mobs and ensure the mobs are the correct type -// for (Map.Entry entry : wave.getEntities().entrySet()) { -// String mob = entry.getKey(); -// int[] spawn = entry.getValue(); -// -// if (waveNum % 5 != 0) { -// assertTrue(LVL3_MOBS.contains(mob)); -// assertEquals(MIN_HEALTH + (waveNum * 3), spawn[1], "The health of the mob should be " + MIN_HEALTH + (waveNum * 3) + " ."); -// } else { -// if (mob == LVL3_BOSS) { -// assertEquals(MIN_BOSS_HEALTH + (waveNum * 3), spawn[1], "The health of the boss should be " + MIN_BOSS_HEALTH + (waveNum * 3) + " ."); -// } -// } -// } -// waveNum++; -// } -// assertEquals(16, waveNum, "There should be 15 waves making numWave 16."); -// } -// -//} +package com.csse3200.game.entities.factories; + +import com.csse3200.game.components.tasks.waves.LevelWaves; +import com.csse3200.game.components.tasks.waves.WaveClass; +import com.csse3200.game.extensions.GameExtension; +import com.csse3200.game.physics.PhysicsService; +import com.csse3200.game.rendering.DebugRenderer; +import com.csse3200.game.rendering.RenderService; +import com.csse3200.game.screens.GameLevelData; +import com.csse3200.game.services.GameTime; +import com.csse3200.game.services.ResourceService; +import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.services.WaveService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import com.csse3200.game.entities.Entity; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + + + +@ExtendWith(GameExtension.class) +@ExtendWith(MockitoExtension.class) +class WaveFactoryTest { + + private LevelWaves lvl1; + private LevelWaves lvl2; + private LevelWaves lvl3; + + private final int MIN_MELEE_HEALTH = 80; + private final int MIN_RANGE_HEALTH = 60; + private final int MIN_BOSS_HEALTH = 80; + private final int LVL1_LVL = 1; + private final int LVL2_LVL = 2; + private final int LVL3_LVL = 3; + private static final ArrayList MELEE_MOBS = new ArrayList<>(Arrays.asList( + "Skeleton", "Coat", "DragonKnight", "Necromancer" + )); + + private static final ArrayList> LVL1_WAVES_STRUC = new ArrayList<>(Arrays.asList( + new ArrayList<>(Arrays.asList("Coat" + )), new ArrayList<>(Arrays.asList("Coat", "WaterQueen" + )), new ArrayList<>(Arrays.asList("WaterQueen", "SplittingWaterSlime" + )), new ArrayList<>(Arrays.asList("Coat", "WaterQueen", "SplittingWaterSlime" + )) + )); + + private static final ArrayList> LVL2_WAVES_STRUC = new ArrayList<>(Arrays.asList( + 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" + )), new ArrayList<>(Arrays.asList("SplittingNightBorne", "Skeleton" + )), new ArrayList<>(Arrays.asList("Wizard", "SplittingNightBorne" + )), new ArrayList<>(Arrays.asList("ArcaneArcher", "SplittingNightBorne", "Wizard" + )), new ArrayList<>(Arrays.asList("Skeleton", "ArcaneArcher", "Wizard", "SplittingNightBorne" + )) + )); + + private static final ArrayList> LVL3_WAVES_STRUC = new ArrayList<>(Arrays.asList( + new ArrayList<>(Arrays.asList("Necromancer" + )), new ArrayList<>(Arrays.asList("Necromancer", "DodgingDragon" + )), new ArrayList<>(Arrays.asList("Necromancer", "FireWorm" + )), new ArrayList<>(Arrays.asList("Necromancer", "DeflectFireWizard" + )), new ArrayList<>(Arrays.asList("DeflectFireWizard", "FireWorm" + )), new ArrayList<>(Arrays.asList("DodgingDragon", "FireWorm" + )), new ArrayList<>(Arrays.asList("DodgingDragon", "Necromancer" + )), new ArrayList<>(Arrays.asList("FireWorm", "Necromancer" + )), new ArrayList<>(Arrays.asList("DeflectFireWizard", "Necromancer" + )), new ArrayList<>(Arrays.asList("DodgingDragon", "DeflectFireWizard", "Necromancer" + )), new ArrayList<>(Arrays.asList("FireWorm", "Necromancer", "DodgingDragon" + )), new ArrayList<>(Arrays.asList("FireWorm", "SplittingRocky", "Necromancer" + )), new ArrayList<>(Arrays.asList("SplittingRocky", "DeflectFireWizard", "FireWorm" + )), new ArrayList<>(Arrays.asList("DeflectFireWizard", "SplittingRocky", "Necromancer", "DodgingDragon", "FireWorm" + )) + )); + + private static final String[] waveSounds = { + "sounds/waves/wave-start/Wave_Start_Alarm.ogg", + "sounds/waves/wave-end/Wave_Over_01.ogg" + }; + + @BeforeEach + void setUp() { + GameTime gameTime = mock(GameTime.class); + ServiceLocator.registerTimeSource(gameTime); + ServiceLocator.registerPhysicsService(new PhysicsService()); + RenderService render = new RenderService(); + render.setDebug(mock(DebugRenderer.class)); + ServiceLocator.registerRenderService(render); + ResourceService resourceService = mock(ResourceService.class); + ServiceLocator.registerResourceService(resourceService); + WaveService waveService = new WaveService(); + ServiceLocator.registerWaveService(waveService); + ServiceLocator.getResourceService().loadSounds(waveSounds); + + lvl1 = WaveFactory.createLevel(LVL1_LVL); + lvl2 = WaveFactory.createLevel(LVL2_LVL); + lvl3 = WaveFactory.createLevel(LVL3_LVL); + } + + @Test + void createBaseWaves() { + GameLevelData.setSelectedLevel(0); + Entity level1 = WaveFactory.createWaves(); + assertNotNull(level1); + + GameLevelData.setSelectedLevel(1); + Entity level2 = WaveFactory.createWaves(); + assertNotNull(level2); + + GameLevelData.setSelectedLevel(2); + Entity level3 = WaveFactory.createWaves(); + assertNotNull(level3); + } + + @Test + void testCreateLevel() { + assertNotNull(lvl1); + assertNotNull(lvl2); + assertNotNull(lvl3); + } + + /** + * The three following tests ensure that every wave in the level is created correctly + * Since the waves are stored in a hashmap, by definition the mobs are unique and this + * quality does not have to be checked. + * */ + @Test + void testLevel1Creation() { + List lvl1Mobs = lvl1.getWaves(); + int bossHealth = 500; + int mobCount = 5; + + int waveNum = 1; + for (WaveClass wave : lvl1Mobs) { + int mobsRemaining = wave.getEntities().size() - 1; + int totalMobsSpawned = 0; + + // check the number of mobs in a wave + if (waveNum == 5 || waveNum == 1) { + assertEquals(1, wave.getEntities().size(), "Wave should contain 1 mob."); + } else if (waveNum == 2 || waveNum == 3) { + assertEquals(2, wave.getEntities().size(), "Wave should contain 2 mobs."); + } else { + assertEquals(3, wave.getEntities().size(), "Wave should contain 3 mobs."); + } + + + if (waveNum != 5) { + Set mobNames = new HashSet<>(wave.getEntities().keySet()); + Set expectedMobNames = new HashSet<>(LVL1_WAVES_STRUC.get(waveNum - 1)); + assertTrue(mobNames.equals(expectedMobNames), "The mobs in the wave should be " + expectedMobNames + " ."); + + for (String key: wave.getEntities().keySet()) { + int[] values = wave.getEntities().get(key); + assertTrue(values[0] > 1 && values[0] <= (mobCount - totalMobsSpawned - (2 * mobsRemaining))); + totalMobsSpawned += values[0]; + mobsRemaining --; + + if (MELEE_MOBS.contains(key)) { + assertTrue(values[1] == MIN_MELEE_HEALTH + waveNum, "The health of the mob should be " + MIN_MELEE_HEALTH + waveNum + " ."); + } else { + assertTrue(values[1] == MIN_RANGE_HEALTH + waveNum, "The health of the mob should be " + MIN_RANGE_HEALTH + waveNum + " ."); + } + } + } else { + assertTrue(wave.getEntities().keySet().size() == 1); + for (String key: wave.getEntities().keySet()) { + int[] values = wave.getEntities().get(key); + assertTrue(values[1] == bossHealth, "The health of the boss should be " + MIN_BOSS_HEALTH); + } + } + mobCount ++; + waveNum++; + } + assertEquals(6, waveNum, "The should be 5 waves making numWave 6."); + } + @Test + void testLevel2Creation() { + + List lvl2Mobs = lvl2.getWaves(); + int bossHealth = 1000; + int mobCount = 6; + + int waveNum = 1; + for (WaveClass wave : lvl2Mobs) { + int mobsRemaining = wave.getEntities().size() - 1; + int totalMobsSpawned = 0; + + // check the number of mobs in a wave + if (waveNum == 1 || waveNum == 10) { + assertEquals(1, wave.getEntities().size(), "Wave should contain 1 mob."); + } else if (1 < waveNum && waveNum < 8) { + assertEquals(2, wave.getEntities().size(), "Wave should contain 2 mobs."); + } else if (waveNum == 8){ + assertEquals(3, wave.getEntities().size(), "Wave should contain 3 mobs."); + } else { + assertEquals(4, wave.getEntities().size(), "Wave should contain 4 mobs."); + } + + if (waveNum != 10) { + Set mobNames = new HashSet<>(wave.getEntities().keySet()); + Set expectedMobNames = new HashSet<>(LVL2_WAVES_STRUC.get(waveNum - 1)); + assertTrue(mobNames.equals(expectedMobNames), "The mobs in the wave should be " + expectedMobNames + " ."); + + for (String key: wave.getEntities().keySet()) { + int[] values = wave.getEntities().get(key); + + assertTrue(values[0] > 1 && values[0] <= (mobCount - totalMobsSpawned - (2 * mobsRemaining))); + totalMobsSpawned += values[0]; + mobsRemaining --; + System.out.println("wave is: "+ wave); + + if (MELEE_MOBS.contains(key)) { + System.out.println("the health is: " + values[1]); + System.out.println("I want it to be: " + (MIN_MELEE_HEALTH + (waveNum * 2))); + + assertEquals(values[1], (MIN_MELEE_HEALTH + (waveNum * 2)), "The health of the mob should be " + (MIN_MELEE_HEALTH + (waveNum * 2)) + " ."); + } else { + assertEquals(values[1], (MIN_RANGE_HEALTH + (waveNum * 2)), "The health of the mob should be " + (MIN_RANGE_HEALTH + (waveNum * 2)) + " ."); + } + } + + } else { + assertTrue(wave.getEntities().keySet().size() == 1); + for (String key: wave.getEntities().keySet()) { + int[] values = wave.getEntities().get(key); + assertTrue(values[1] == bossHealth, "The health of the boss should be " + MIN_BOSS_HEALTH); + } + } + mobCount ++; + waveNum++; + } + assertEquals(11, waveNum, "There should be 10 waves making numWave 11."); + } + @Test + void testLevel3Creation() { + + List lvl3Mobs = lvl3.getWaves(); + + int bossHealth = 2000; + int mobCount = 8; + + int waveNum = 1; + for (WaveClass wave : lvl3Mobs) { + int mobsRemaining = wave.getEntities().size() - 1; + int totalMobsSpawned = 0; + + // check the number of mobs in a wave + if (waveNum == 1 || waveNum == 15) { + assertEquals(1, wave.getEntities().size(), "Wave should contain 1 mob."); + } else if (1 < waveNum && waveNum < 10) { + assertEquals(2, wave.getEntities().size(), "Wave should contain 2 mobs."); + } else if (9 < waveNum && waveNum < 14){ + assertEquals(3, wave.getEntities().size(), "Wave should contain 3 mobs."); + } else if (waveNum == 14){ + assertEquals(5, wave.getEntities().size(), "Wave should contain 4 mobs."); + } + + if (waveNum != 15) { + Set mobNames = new HashSet<>(wave.getEntities().keySet()); + Set expectedMobNames = new HashSet<>(LVL3_WAVES_STRUC.get(waveNum - 1)); + assertTrue(mobNames.equals(expectedMobNames), "The mobs in the wave should be " + expectedMobNames + " ."); + + for (String key: wave.getEntities().keySet()) { + int[] values = wave.getEntities().get(key); + + assertTrue(values[0] > 1 && values[0] <= (mobCount - totalMobsSpawned - (2 * mobsRemaining))); + totalMobsSpawned += values[0]; + mobsRemaining --; + + if (MELEE_MOBS.contains(key)) { + assertEquals(values[1], (MIN_MELEE_HEALTH + (waveNum * 3)), "The health of the mob should be " + (MIN_MELEE_HEALTH + (waveNum * 2)) + " ."); + } else { + assertEquals(values[1], (MIN_RANGE_HEALTH + (waveNum * 3)), "The health of the mob should be " + (MIN_RANGE_HEALTH + (waveNum * 2)) + " ."); + } + } + + } else { + assertTrue(wave.getEntities().keySet().size() == 1); + for (String key: wave.getEntities().keySet()) { + int[] values = wave.getEntities().get(key); + assertTrue(values[1] == bossHealth, "The health of the boss should be " + MIN_BOSS_HEALTH); + } + } + mobCount ++; + waveNum++; + } + assertEquals(16, waveNum, "There should be 15 waves making numWave 16."); + } + +} diff --git a/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java b/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java index 1182420c5..77e81bb5b 100644 --- a/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java +++ b/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java @@ -15,6 +15,7 @@ import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.rendering.DebugRenderer; import com.csse3200.game.rendering.RenderService; +import com.csse3200.game.screens.MainGameScreen; import com.csse3200.game.screens.TowerType; import com.csse3200.game.services.*; import org.junit.jupiter.api.BeforeEach; diff --git a/source/core/src/test/com/csse3200/game/rendering/CameraShakerTest.java b/source/core/src/test/com/csse3200/game/rendering/CameraShakerTest.java index 303f36277..8fedf33d8 100644 --- a/source/core/src/test/com/csse3200/game/rendering/CameraShakerTest.java +++ b/source/core/src/test/com/csse3200/game/rendering/CameraShakerTest.java @@ -29,7 +29,7 @@ public void testReset() { cameraShaker.startShaking(); cameraShaker.reset(); assertFalse(cameraShaker.isCameraShaking()); - assertEquals(cameraShaker.origPosition, camera.position); + assertEquals(cameraShaker.getOrigPosition(), camera.position); } @Test