Implemented new enemy system (largely untested)
|
Before Width: | Height: | Size: 287 B After Width: | Height: | Size: 287 B |
|
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 339 B |
|
Before Width: | Height: | Size: 301 B After Width: | Height: | Size: 301 B |
@@ -405,7 +405,7 @@ blocks/grassblock2
|
|||||||
index: -1
|
index: -1
|
||||||
blocks/grassedge
|
blocks/grassedge
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 152, 91
|
xy: 124, 91
|
||||||
size: 12, 12
|
size: 12, 12
|
||||||
orig: 12, 12
|
orig: 12, 12
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -433,7 +433,7 @@ blocks/ice3
|
|||||||
index: -1
|
index: -1
|
||||||
blocks/iceedge
|
blocks/iceedge
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 166, 91
|
xy: 138, 91
|
||||||
size: 12, 12
|
size: 12, 12
|
||||||
orig: 12, 12
|
orig: 12, 12
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -538,7 +538,7 @@ blocks/lava
|
|||||||
index: -1
|
index: -1
|
||||||
blocks/lavaedge
|
blocks/lavaedge
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 95, 75
|
xy: 152, 91
|
||||||
size: 12, 12
|
size: 12, 12
|
||||||
orig: 12, 12
|
orig: 12, 12
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -650,7 +650,7 @@ blocks/oil
|
|||||||
index: -1
|
index: -1
|
||||||
blocks/oiledge
|
blocks/oiledge
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 109, 75
|
xy: 95, 75
|
||||||
size: 12, 12
|
size: 12, 12
|
||||||
orig: 12, 12
|
orig: 12, 12
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -839,7 +839,7 @@ blocks/sandblock3
|
|||||||
index: -1
|
index: -1
|
||||||
blocks/sandedge
|
blocks/sandedge
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 95, 47
|
xy: 95, 61
|
||||||
size: 12, 12
|
size: 12, 12
|
||||||
orig: 12, 12
|
orig: 12, 12
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -937,7 +937,7 @@ blocks/snowblock3
|
|||||||
index: -1
|
index: -1
|
||||||
blocks/snowedge
|
blocks/snowedge
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 95, 33
|
xy: 95, 47
|
||||||
size: 12, 12
|
size: 12, 12
|
||||||
orig: 12, 12
|
orig: 12, 12
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1278,72 +1278,44 @@ enemies/empenemy-t3
|
|||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/enemy-t1
|
|
||||||
rotate: false
|
|
||||||
xy: 646, 243
|
|
||||||
size: 14, 14
|
|
||||||
orig: 14, 14
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
enemies/targetenemy-t1
|
|
||||||
rotate: false
|
|
||||||
xy: 646, 243
|
|
||||||
size: 14, 14
|
|
||||||
orig: 14, 14
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
enemies/enemy-t2
|
|
||||||
rotate: false
|
|
||||||
xy: 124, 91
|
|
||||||
size: 12, 12
|
|
||||||
orig: 12, 12
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
enemies/enemy-t3
|
|
||||||
rotate: false
|
|
||||||
xy: 138, 91
|
|
||||||
size: 12, 12
|
|
||||||
orig: 12, 12
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
enemies/fastenemy-t1
|
enemies/fastenemy-t1
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 718, 297
|
xy: 646, 243
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/fastenemy-t2
|
enemies/fastenemy-t2
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 495, 120
|
xy: 718, 297
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/fastenemy-t3
|
enemies/fastenemy-t3
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 492, 104
|
xy: 495, 120
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/flamerenemy-t1
|
enemies/flamerenemy-t1
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 511, 120
|
xy: 492, 104
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/flamerenemy-t2
|
enemies/flamerenemy-t2
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 508, 104
|
xy: 511, 120
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/flamerenemy-t3
|
enemies/flamerenemy-t3
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 519, 208
|
xy: 508, 104
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1371,67 +1343,95 @@ enemies/fortressenemy-t3
|
|||||||
index: -1
|
index: -1
|
||||||
enemies/healerenemy-t1
|
enemies/healerenemy-t1
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 519, 192
|
xy: 519, 208
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/healerenemy-t2
|
enemies/healerenemy-t2
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 521, 162
|
xy: 519, 192
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/healerenemy-t3
|
enemies/healerenemy-t3
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 521, 146
|
xy: 521, 162
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/mortarenemy-t1
|
enemies/mortarenemy-t1
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 738, 396
|
xy: 738, 412
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/mortarenemy-t2
|
enemies/mortarenemy-t2
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 754, 414
|
xy: 738, 396
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/mortarenemy-t3
|
enemies/mortarenemy-t3
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 754, 398
|
xy: 754, 414
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/rapidenemy-t1
|
enemies/rapidenemy-t1
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 770, 414
|
xy: 754, 398
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/rapidenemy-t2
|
enemies/rapidenemy-t2
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 770, 398
|
xy: 770, 414
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
enemies/rapidenemy-t3
|
enemies/rapidenemy-t3
|
||||||
|
rotate: false
|
||||||
|
xy: 770, 398
|
||||||
|
size: 14, 14
|
||||||
|
orig: 14, 14
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
enemies/standardenemy-t1
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 786, 419
|
xy: 786, 419
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
|
enemies/targetenemy-t1
|
||||||
|
rotate: false
|
||||||
|
xy: 786, 419
|
||||||
|
size: 14, 14
|
||||||
|
orig: 14, 14
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
enemies/standardenemy-t2
|
||||||
|
rotate: false
|
||||||
|
xy: 109, 61
|
||||||
|
size: 12, 12
|
||||||
|
orig: 12, 12
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
enemies/standardenemy-t3
|
||||||
|
rotate: false
|
||||||
|
xy: 95, 33
|
||||||
|
size: 12, 12
|
||||||
|
orig: 12, 12
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
enemies/tankenemy-t1
|
enemies/tankenemy-t1
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 786, 403
|
xy: 786, 403
|
||||||
@@ -1560,14 +1560,14 @@ laserfull
|
|||||||
index: -1
|
index: -1
|
||||||
mechs/mech-standard
|
mechs/mech-standard
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 95, 61
|
xy: 166, 91
|
||||||
size: 12, 12
|
size: 12, 12
|
||||||
orig: 12, 12
|
orig: 12, 12
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
mechs/ship-standard
|
mechs/ship-standard
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 109, 61
|
xy: 109, 75
|
||||||
size: 12, 12
|
size: 12, 12
|
||||||
orig: 12, 12
|
orig: 12, 12
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1715,7 +1715,7 @@ ui/icons/controller-cursor
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-add
|
ui/icons/icon-add
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 535, 209
|
xy: 521, 146
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1729,7 +1729,7 @@ ui/icons/icon-areaDelete
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-arrow
|
ui/icons/icon-arrow
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 535, 193
|
xy: 535, 209
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1771,14 +1771,14 @@ ui/icons/icon-back
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-cancel
|
ui/icons/icon-cancel
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 551, 211
|
xy: 535, 193
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-check
|
ui/icons/icon-check
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 551, 195
|
xy: 551, 211
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1827,7 +1827,7 @@ ui/icons/icon-defense
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-discord
|
ui/icons/icon-discord
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 567, 211
|
xy: 551, 195
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1841,28 +1841,28 @@ ui/icons/icon-distribution
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-donate
|
ui/icons/icon-donate
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 567, 195
|
xy: 567, 211
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-dots
|
ui/icons/icon-dots
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 583, 213
|
xy: 567, 195
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-editor
|
ui/icons/icon-editor
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 583, 197
|
xy: 583, 213
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-file-text
|
ui/icons/icon-file-text
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 599, 216
|
xy: 583, 197
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1876,21 +1876,21 @@ ui/icons/icon-fill
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-floppy
|
ui/icons/icon-floppy
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 599, 200
|
xy: 599, 216
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-folder
|
ui/icons/icon-folder
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 615, 216
|
xy: 599, 200
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-folder-parent
|
ui/icons/icon-folder-parent
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 615, 200
|
xy: 615, 216
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1918,14 +1918,14 @@ ui/icons/icon-holdDelete
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-home
|
ui/icons/icon-home
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 631, 220
|
xy: 615, 200
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-host
|
ui/icons/icon-host
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 631, 204
|
xy: 631, 220
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -1946,7 +1946,7 @@ ui/icons/icon-line
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-load
|
ui/icons/icon-load
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 647, 227
|
xy: 631, 204
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -2016,7 +2016,7 @@ ui/icons/icon-play
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-play-2
|
ui/icons/icon-play-2
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 647, 211
|
xy: 647, 227
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -2037,7 +2037,7 @@ ui/icons/icon-production
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-quit
|
ui/icons/icon-quit
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 647, 195
|
xy: 647, 211
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -2051,7 +2051,7 @@ ui/icons/icon-redo
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-rename
|
ui/icons/icon-rename
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 631, 188
|
xy: 647, 195
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -2065,35 +2065,35 @@ ui/icons/icon-resize
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-rotate
|
ui/icons/icon-rotate
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 647, 179
|
xy: 631, 188
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-rotate-arrow
|
ui/icons/icon-rotate-arrow
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 722, 411
|
xy: 647, 179
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-rotate-left
|
ui/icons/icon-rotate-left
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 722, 395
|
xy: 722, 411
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-rotate-right
|
ui/icons/icon-rotate-right
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 724, 365
|
xy: 722, 395
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-save
|
ui/icons/icon-save
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 724, 349
|
xy: 724, 365
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -2128,7 +2128,7 @@ ui/icons/icon-terrain
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-tools
|
ui/icons/icon-tools
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 724, 333
|
xy: 724, 349
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@@ -2149,14 +2149,14 @@ ui/icons/icon-touchDelete
|
|||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-trash
|
ui/icons/icon-trash
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 724, 317
|
xy: 724, 333
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ui/icons/icon-tutorial
|
ui/icons/icon-tutorial
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 738, 412
|
xy: 724, 317
|
||||||
size: 14, 14
|
size: 14, 14
|
||||||
orig: 14, 14
|
orig: 14, 14
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
@@ -2,9 +2,7 @@
|
|||||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "https://raw.githubusercontent.com/gwtproject/gwt/master/distro-source/core/src/gwt-module.dtd">
|
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "https://raw.githubusercontent.com/gwtproject/gwt/master/distro-source/core/src/gwt-module.dtd">
|
||||||
<module>
|
<module>
|
||||||
<source path="io/anuke/mindustry" />
|
<source path="io/anuke/mindustry" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.enemies" />
|
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.Maps" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.Maps" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.EnemySpawn" />
|
|
||||||
</module>
|
</module>
|
||||||
@@ -5,9 +5,9 @@ import com.badlogic.gdx.ai.pfa.PathSmoother;
|
|||||||
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
|
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.world.SpawnPoint;
|
import io.anuke.mindustry.world.SpawnPoint;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
@@ -28,25 +28,27 @@ public class Pathfind{
|
|||||||
findNode(enemy);
|
findNode(enemy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enemy.path == null){
|
if(enemy.node == -2){
|
||||||
return vector.set(enemy.x, enemy.y);
|
|
||||||
}else if(enemy.node == -2){
|
|
||||||
enemy.node = -1;
|
enemy.node = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile[] path = enemy.path;
|
if(enemy.node < 0 || Vars.control.getSpawnPoints().get(enemy.lane).pathTiles == null){
|
||||||
|
return vector.set(enemy.x, enemy.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tile[] path = Vars.control.getSpawnPoints().get(enemy.lane).pathTiles;
|
||||||
|
|
||||||
if(enemy.idletime > Enemy.maxIdle){
|
if(enemy.idletime > EnemyType.maxIdle){
|
||||||
//TODO reverse
|
//TODO reverse
|
||||||
Tile target = path[enemy.node];
|
Tile target = path[enemy.node];
|
||||||
if(Vars.world.raycastWorld(enemy.x, enemy.y, target.worldx(), target.worldy()) != null){
|
if(Vars.world.raycastWorld(enemy.x, enemy.y, target.worldx(), target.worldy()) != null) {
|
||||||
if(enemy.node > 1)
|
if (enemy.node > 1)
|
||||||
enemy.node = enemy.node - 1;
|
enemy.node = enemy.node - 1;
|
||||||
enemy.idletime = 0;
|
enemy.idletime = 0;
|
||||||
}else{
|
|
||||||
//must be blocked by a playermade block, do nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//else, must be blocked by a playermade block, do nothing
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-1 is only possible here if both pathfindings failed, which should NOT happen
|
//-1 is only possible here if both pathfindings failed, which should NOT happen
|
||||||
@@ -157,22 +159,24 @@ public class Pathfind{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
enemy.path = Vars.control.getSpawnPoints().get(enemy.lane).pathTiles;
|
Tile[] path = Vars.control.getSpawnPoints().get(enemy.lane).pathTiles;
|
||||||
|
|
||||||
int closest = findClosest(enemy.path, enemy.x, enemy.y);
|
int closest = findClosest(path, enemy.x, enemy.y);
|
||||||
|
|
||||||
closest = Mathf.clamp(closest, 1, enemy.path.length-1);
|
closest = Mathf.clamp(closest, 1, path.length-1);
|
||||||
if(closest == -1){
|
if(closest == -1){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile end = enemy.path[closest];
|
|
||||||
enemy.node = closest;
|
enemy.node = closest;
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
//Tile end = path[closest];
|
||||||
//if the enemy can't get to this node, teleport to it
|
//if the enemy can't get to this node, teleport to it
|
||||||
if(enemy.node < enemy.path.length - 2 && Vars.world.raycastWorld(enemy.x, enemy.y, end.worldx(), end.worldy()) != null){
|
//if(enemy.node < path.length - 2 && Vars.world.raycastWorld(enemy.x, enemy.y, end.worldx(), end.worldy()) != null){
|
||||||
// Timers.run(Mathf.random(20f), () -> enemy.set(end.worldx(), end.worldy()));
|
// Timers.run(Mathf.random(20f), () -> enemy.set(end.worldx(), end.worldy()));
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int findClosest(Tile[] tiles, float x, float y){
|
private static int findClosest(Tile[] tiles, float x, float y){
|
||||||
|
|||||||
@@ -5,15 +5,13 @@ import com.badlogic.gdx.Gdx;
|
|||||||
import com.badlogic.gdx.Input.Buttons;
|
import com.badlogic.gdx.Input.Buttons;
|
||||||
import com.badlogic.gdx.Input.Keys;
|
import com.badlogic.gdx.Input.Keys;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
|
||||||
import io.anuke.mindustry.Mindustry;
|
import io.anuke.mindustry.Mindustry;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.*;
|
import io.anuke.mindustry.entities.*;
|
||||||
import io.anuke.mindustry.entities.effect.Shield;
|
import io.anuke.mindustry.entities.effect.Shield;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.entities.enemies.FortressEnemy;
|
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||||
import io.anuke.mindustry.entities.enemies.HealerEnemy;
|
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
import io.anuke.mindustry.input.AndroidInput;
|
import io.anuke.mindustry.input.AndroidInput;
|
||||||
import io.anuke.mindustry.input.DesktopInput;
|
import io.anuke.mindustry.input.DesktopInput;
|
||||||
@@ -356,21 +354,17 @@ public class Control extends Module{
|
|||||||
float range = 12f;
|
float range = 12f;
|
||||||
|
|
||||||
Timers.run(index*5f, ()->{
|
Timers.run(index*5f, ()->{
|
||||||
try{
|
|
||||||
Enemy enemy = ClassReflection.newInstance(spawn.type);
|
|
||||||
enemy.set(tile.worldx() + Mathf.range(range), tile.worldy() + Mathf.range(range));
|
|
||||||
enemy.lane = fl;
|
|
||||||
enemy.tier = spawn.tier(wave, fl);
|
|
||||||
enemy.add();
|
|
||||||
|
|
||||||
Effects.effect(Fx.spawn, enemy);
|
Enemy enemy = new Enemy(spawn.type);
|
||||||
|
enemy.set(tile.worldx() + Mathf.range(range), tile.worldy() + Mathf.range(range));
|
||||||
|
enemy.lane = fl;
|
||||||
|
enemy.tier = spawn.tier(wave, fl);
|
||||||
|
enemy.add();
|
||||||
|
|
||||||
Vars.netServer.handleEnemySpawn(enemy);
|
Effects.effect(Fx.spawn, enemy);
|
||||||
|
Vars.netServer.handleEnemySpawn(enemy);
|
||||||
|
|
||||||
enemies ++;
|
enemies ++;
|
||||||
}catch (Exception e){
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -601,10 +595,10 @@ public class Control extends Module{
|
|||||||
|
|
||||||
if(Inputs.keyTap(Keys.Y)){
|
if(Inputs.keyTap(Keys.Y)){
|
||||||
if(Inputs.keyDown(Keys.SHIFT_LEFT)){
|
if(Inputs.keyDown(Keys.SHIFT_LEFT)){
|
||||||
new HealerEnemy().set(player.x, player.y).add();
|
new Enemy(EnemyTypes.healer).set(player.x, player.y).add();
|
||||||
}else{
|
}else{
|
||||||
float px = player.x, py = player.y;
|
float px = player.x, py = player.y;
|
||||||
Timers.run(30f, ()-> new FortressEnemy().set(px, py).add());
|
Timers.run(30f, ()-> new Enemy(EnemyTypes.fortress).set(px, py).add());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.anuke.mindustry.entities;
|
package io.anuke.mindustry.entities;
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ public class EnemySpawn{
|
|||||||
private static float[] scalings = {4f, 2.5f, 1.5f};
|
private static float[] scalings = {4f, 2.5f, 1.5f};
|
||||||
|
|
||||||
/**The enemy type spawned*/
|
/**The enemy type spawned*/
|
||||||
public final Class<? extends Enemy> type;
|
public final EnemyType type;
|
||||||
/**When this spawns should end*/
|
/**When this spawns should end*/
|
||||||
protected int before = Integer.MAX_VALUE;
|
protected int before = Integer.MAX_VALUE;
|
||||||
/**When this spawns should start*/
|
/**When this spawns should start*/
|
||||||
@@ -29,7 +29,7 @@ public class EnemySpawn{
|
|||||||
/**Amount of enemies spawned initially, with no scaling*/
|
/**Amount of enemies spawned initially, with no scaling*/
|
||||||
protected int amount = 1;
|
protected int amount = 1;
|
||||||
|
|
||||||
public EnemySpawn(Class<? extends Enemy> type){
|
public EnemySpawn(EnemyType type){
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,10 +39,10 @@ public class EnemySpawn{
|
|||||||
}
|
}
|
||||||
float scaling = this.scaling * scalings[(Settings.getInt("difficulty"))];
|
float scaling = this.scaling * scalings[(Settings.getInt("difficulty"))];
|
||||||
|
|
||||||
return Math.min(amount-1 + 1 * Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max);
|
return Math.min(amount-1 + Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int tier(int wave, int lane){
|
public int tier(int wave, int lane){
|
||||||
return Mathf.clamp(tier + (wave-after)/tierscale, 1, Enemy.maxtier);
|
return Mathf.clamp(tier + (wave-after)/tierscale, 1, EnemyType.maxtier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
package io.anuke.mindustry.entities;
|
package io.anuke.mindustry.entities;
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.enemies.*;
|
|
||||||
|
|
||||||
public class WaveCreator{
|
public class WaveCreator{
|
||||||
|
|
||||||
public static Array<EnemySpawn> getSpawns(){
|
public static Array<EnemySpawn> getSpawns(){
|
||||||
//TODO
|
|
||||||
//Gdx.app.exit();
|
|
||||||
return Array.with(
|
return Array.with(
|
||||||
new EnemySpawn(Enemy.class){{
|
new EnemySpawn(EnemyTypes.standard){{
|
||||||
scaling = 1;
|
scaling = 1;
|
||||||
before = 3;
|
before = 3;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(FastEnemy.class){{
|
new EnemySpawn(EnemyTypes.fast){{
|
||||||
scaling = 1;
|
scaling = 1;
|
||||||
after = 3;
|
after = 3;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
@@ -24,7 +20,7 @@ public class WaveCreator{
|
|||||||
tierscaleback = 0;
|
tierscaleback = 0;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(BlastEnemy.class){{
|
new EnemySpawn(EnemyTypes.blast){{
|
||||||
after = 4;
|
after = 4;
|
||||||
amount = 3;
|
amount = 3;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
@@ -32,56 +28,56 @@ public class WaveCreator{
|
|||||||
tierscaleback = 0;
|
tierscaleback = 0;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(TankEnemy.class){{
|
new EnemySpawn(EnemyTypes.tank){{
|
||||||
after = 5;
|
after = 5;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 2;
|
scaling = 2;
|
||||||
amount = 2;
|
amount = 2;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(RapidEnemy.class){{
|
new EnemySpawn(EnemyTypes.rapid){{
|
||||||
after = 7;
|
after = 7;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 2;
|
scaling = 2;
|
||||||
amount = 3;
|
amount = 3;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(HealerEnemy.class){{
|
new EnemySpawn(EnemyTypes.healer){{
|
||||||
after = 5;
|
after = 5;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 1;
|
scaling = 1;
|
||||||
amount = 1;
|
amount = 1;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(Enemy.class){{
|
new EnemySpawn(EnemyTypes.standard){{
|
||||||
scaling = 3;
|
scaling = 3;
|
||||||
after = 8;
|
after = 8;
|
||||||
spacing = 4;
|
spacing = 4;
|
||||||
tier = 2;
|
tier = 2;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(TitanEnemy.class){{
|
new EnemySpawn(EnemyTypes.titan){{
|
||||||
after = 6;
|
after = 6;
|
||||||
amount = 2;
|
amount = 2;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 3;
|
scaling = 3;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(FlamerEnemy.class){{
|
new EnemySpawn(EnemyTypes.flamer){{
|
||||||
after = 12;
|
after = 12;
|
||||||
amount = 3;
|
amount = 3;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 3;
|
scaling = 3;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(EmpEnemy.class){{
|
new EnemySpawn(EnemyTypes.emp){{
|
||||||
after = 15;
|
after = 15;
|
||||||
amount = 1;
|
amount = 1;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 2;
|
scaling = 2;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(BlastEnemy.class){{
|
new EnemySpawn(EnemyTypes.blast){{
|
||||||
after = 4 + 5 + 5;
|
after = 4 + 5 + 5;
|
||||||
amount = 3;
|
amount = 3;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
@@ -89,14 +85,14 @@ public class WaveCreator{
|
|||||||
tierscaleback = 0;
|
tierscaleback = 0;
|
||||||
}},
|
}},
|
||||||
//boss wave
|
//boss wave
|
||||||
new EnemySpawn(FortressEnemy.class){{
|
new EnemySpawn(EnemyTypes.fortress){{
|
||||||
after = 16;
|
after = 16;
|
||||||
amount = 1;
|
amount = 1;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 1;
|
scaling = 1;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(TitanEnemy.class){{
|
new EnemySpawn(EnemyTypes.titan){{
|
||||||
after = 16;
|
after = 16;
|
||||||
amount = 1;
|
amount = 1;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
@@ -104,7 +100,7 @@ public class WaveCreator{
|
|||||||
tierscaleback = 0;
|
tierscaleback = 0;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(HealerEnemy.class){{
|
new EnemySpawn(EnemyTypes.healer){{
|
||||||
after = 16;
|
after = 16;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 2;
|
scaling = 2;
|
||||||
@@ -113,14 +109,14 @@ public class WaveCreator{
|
|||||||
//end boss wave
|
//end boss wave
|
||||||
|
|
||||||
//enchanced boss wave
|
//enchanced boss wave
|
||||||
new EnemySpawn(MortarEnemy.class){{
|
new EnemySpawn(EnemyTypes.mortar){{
|
||||||
after = 16 + 5;
|
after = 16 + 5;
|
||||||
amount = 1;
|
amount = 1;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
scaling = 3;
|
scaling = 3;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
new EnemySpawn(EmpEnemy.class){{
|
new EnemySpawn(EnemyTypes.emp){{
|
||||||
after = 16 + 5;
|
after = 16 + 5;
|
||||||
amount = 1;
|
amount = 1;
|
||||||
spacing = 5;
|
spacing = 5;
|
||||||
@@ -130,70 +126,6 @@ public class WaveCreator{
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Array<EnemySpawn> getSpawnsOld(){
|
|
||||||
return Array.with(
|
|
||||||
new EnemySpawn(Enemy.class){{
|
|
||||||
scaling = 2;
|
|
||||||
before = 4;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(Enemy.class){{
|
|
||||||
scaling = 3;
|
|
||||||
tierscaleback = 3;
|
|
||||||
spacing = 2;
|
|
||||||
after = 4;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(TitanEnemy.class){{
|
|
||||||
after = 5;
|
|
||||||
spacing = 2;
|
|
||||||
scaling = 5;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(FortressEnemy.class){{
|
|
||||||
after = 12;
|
|
||||||
spacing = 5;
|
|
||||||
scaling = 7;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(HealerEnemy.class){{
|
|
||||||
scaling = 3;
|
|
||||||
spacing = 2;
|
|
||||||
after = 8;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(FastEnemy.class){{
|
|
||||||
after = 2;
|
|
||||||
scaling = 3;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(FlamerEnemy.class){{
|
|
||||||
after = 14;
|
|
||||||
spacing = 6;
|
|
||||||
scaling = 3;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(BlastEnemy.class){{
|
|
||||||
after = 12;
|
|
||||||
spacing = 2;
|
|
||||||
scaling = 3;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(RapidEnemy.class){{
|
|
||||||
after = 7;
|
|
||||||
spacing = 3;
|
|
||||||
scaling = 3;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(EmpEnemy.class){{
|
|
||||||
after = 19;
|
|
||||||
spacing = 3;
|
|
||||||
scaling = 5;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(TankEnemy.class){{
|
|
||||||
after = 4;
|
|
||||||
spacing = 2;
|
|
||||||
scaling = 3;
|
|
||||||
}},
|
|
||||||
new EnemySpawn(MortarEnemy.class){{
|
|
||||||
after = 20;
|
|
||||||
spacing = 3;
|
|
||||||
scaling = 5;
|
|
||||||
}}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void testWaves(int from, int to){
|
public static void testWaves(int from, int to){
|
||||||
Array<EnemySpawn> spawns = getSpawns();
|
Array<EnemySpawn> spawns = getSpawns();
|
||||||
for(int i = from; i <= to; i ++){
|
for(int i = from; i <= to; i ++){
|
||||||
@@ -205,7 +137,7 @@ public class WaveCreator{
|
|||||||
total += a;
|
total += a;
|
||||||
|
|
||||||
if(a > 0){
|
if(a > 0){
|
||||||
System.out.print(a+"x" + ClassReflection.getSimpleName(spawn.type) + "-" + t + " ");
|
System.out.print(a+"x" + spawn.type.name + "-" + t + " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.print(" (" + total + ")");
|
System.out.print(" (" + total + ")");
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.math.Vector2;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.entities.Bullet;
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
public class BlastEnemy extends Enemy{
|
|
||||||
|
|
||||||
public BlastEnemy() {
|
|
||||||
maxhealth = 30;
|
|
||||||
speed = 0.7f;
|
|
||||||
bullet = null;
|
|
||||||
turretrotatespeed = 0f;
|
|
||||||
mass = 0.8f;
|
|
||||||
stopNearCore = false;
|
|
||||||
|
|
||||||
heal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void move(){
|
|
||||||
super.move();
|
|
||||||
float range = 10f;
|
|
||||||
Vector2 offset = Tmp.v3.setZero();
|
|
||||||
if(target instanceof TileEntity){
|
|
||||||
TileEntity e = (TileEntity)target;
|
|
||||||
range = (e.tile.block().width * Vars.tilesize) /2f + 8f;
|
|
||||||
offset.set(e.tile.block().getPlaceOffset());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(target != null && target.distanceTo(this.x - offset.x, this.y - offset.y) < range){
|
|
||||||
explode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDeath(){
|
|
||||||
super.onDeath();
|
|
||||||
explode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void explode(){
|
|
||||||
Bullet b = new Bullet(BulletType.blast, this, x, y, 0).add();
|
|
||||||
b.damage = BulletType.blast.damage + (tier-1) * 40;
|
|
||||||
damage(999);
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
|
||||||
|
|
||||||
public class EmpEnemy extends Enemy{
|
|
||||||
|
|
||||||
public EmpEnemy() {
|
|
||||||
|
|
||||||
speed = 0.3f;
|
|
||||||
reload = 70;
|
|
||||||
maxhealth = 210;
|
|
||||||
range = 80f;
|
|
||||||
bullet = BulletType.emp;
|
|
||||||
turretrotatespeed = 0.1f;
|
|
||||||
|
|
||||||
heal();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,209 +1,57 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
package io.anuke.mindustry.entities.enemies;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.Bullet;
|
import io.anuke.mindustry.entities.Bullet;
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
|
||||||
import io.anuke.mindustry.graphics.Shaders;
|
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Syncable;
|
import io.anuke.mindustry.net.Syncable;
|
||||||
import io.anuke.mindustry.world.Tile;
|
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
|
||||||
import io.anuke.ucore.core.Draw;
|
|
||||||
import io.anuke.ucore.core.Effects;
|
|
||||||
import io.anuke.ucore.core.Graphics;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.entities.DestructibleEntity;
|
import io.anuke.ucore.entities.DestructibleEntity;
|
||||||
import io.anuke.ucore.entities.Entities;
|
|
||||||
import io.anuke.ucore.entities.Entity;
|
import io.anuke.ucore.entities.Entity;
|
||||||
import io.anuke.ucore.entities.SolidEntity;
|
import io.anuke.ucore.entities.SolidEntity;
|
||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
import io.anuke.ucore.util.Timer;
|
import io.anuke.ucore.util.Timer;
|
||||||
import io.anuke.ucore.util.Tmp;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
|
||||||
|
|
||||||
public class Enemy extends DestructibleEntity implements Syncable{
|
public class Enemy extends DestructibleEntity implements Syncable{
|
||||||
public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") };
|
protected Interpolator<Enemy> inter = new Interpolator<>(SyncType.enemy);
|
||||||
public final static int maxtier = 4;
|
|
||||||
public final static float maxIdle = 60*1.5f;
|
|
||||||
public final static float maxIdleLife = 60f*13f; //13 seconds idle = death
|
|
||||||
|
|
||||||
protected int timeid;
|
public final EnemyType type;
|
||||||
protected Timer timer = new Timer(5);
|
|
||||||
protected float speed = 0.4f;
|
|
||||||
protected float reload = 32;
|
|
||||||
protected float range = 60;
|
|
||||||
protected float length = 4;
|
|
||||||
protected float rotatespeed = 0.1f;
|
|
||||||
protected float turretrotatespeed = 0.2f;
|
|
||||||
protected boolean alwaysRotate = false;
|
|
||||||
protected BulletType bullet = BulletType.small;
|
|
||||||
protected String shootsound = "enemyshoot";
|
|
||||||
protected int damage;
|
|
||||||
protected Enemy spawner;
|
|
||||||
protected int spawned = 0;
|
|
||||||
protected boolean targetCore = false;
|
|
||||||
protected boolean stopNearCore = true;
|
|
||||||
protected float mass = 1f;
|
|
||||||
protected String className;
|
|
||||||
|
|
||||||
protected Interpolator<Enemy> inter = new Interpolator(SyncType.enemy);
|
|
||||||
|
|
||||||
|
public Timer timer = new Timer(5);
|
||||||
public float idletime = 0f;
|
public float idletime = 0f;
|
||||||
public int lane;
|
public int lane;
|
||||||
public int node = -1;
|
public int node = -1;
|
||||||
public Tile[] path;
|
|
||||||
|
public Enemy spawner;
|
||||||
|
public int spawned;
|
||||||
|
|
||||||
public float angle;
|
public float angle;
|
||||||
public float xvelocity, yvelocity;
|
public Vector2 velocity = new Vector2();
|
||||||
public Entity target;
|
public Entity target;
|
||||||
public int tier = 1;
|
public int tier = 1;
|
||||||
|
|
||||||
protected final int timerTarget = timeid ++;
|
public Enemy(EnemyType type){
|
||||||
protected final int timerReload = timeid ++;
|
this.type = type;
|
||||||
|
|
||||||
public Enemy() {
|
|
||||||
hitbox.setSize(5f);
|
|
||||||
hitboxTile.setSize(4f);
|
|
||||||
|
|
||||||
maxhealth = 60;
|
|
||||||
heal();
|
|
||||||
|
|
||||||
className = ClassReflection.getSimpleName(getClass()).toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Interpolator<Enemy> getInterpolator() {
|
|
||||||
return inter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float drawSize(){
|
|
||||||
return 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
void move(){
|
|
||||||
if(Net.client() && Net.active()){
|
|
||||||
inter.update(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tile core = Vars.control.getCore();
|
|
||||||
|
|
||||||
if(idletime > maxIdleLife){
|
|
||||||
onDeath();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean nearCore = distanceTo(core.worldx(), core.worldy()) <= range - 18f && stopNearCore;
|
|
||||||
Vector2 vec;
|
|
||||||
|
|
||||||
if(nearCore){
|
|
||||||
vec = Tmp.v1.setZero();
|
|
||||||
if(targetCore) target = core.entity;
|
|
||||||
}else{
|
|
||||||
vec = Vars.world.pathfinder().find(this);
|
|
||||||
vec.sub(x, y).limit(speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 shift = Tmp.v3.setZero();
|
|
||||||
float shiftRange = hitbox.width + 2f;
|
|
||||||
float avoidRange = shiftRange + 4f;
|
|
||||||
float attractRange = avoidRange + 7f;
|
|
||||||
float avoidSpeed = this.speed/2.7f;
|
|
||||||
|
|
||||||
Entities.getNearby(Vars.control.enemyGroup, x, y, range, other -> {
|
|
||||||
Enemy enemy = (Enemy)other;
|
|
||||||
if(other == this) return;
|
|
||||||
float dst = other.distanceTo(this);
|
|
||||||
|
|
||||||
if(dst < shiftRange){
|
|
||||||
float scl = Mathf.clamp(1.4f - dst / shiftRange) * enemy.mass * 1f/mass;
|
|
||||||
shift.add((x - other.x) * scl, (y - other.y) * scl);
|
|
||||||
}else if(dst < avoidRange){
|
|
||||||
Tmp.v2.set((x - other.x), (y - other.y)).setLength(avoidSpeed);
|
|
||||||
shift.add(Tmp.v2.scl(1.1f));
|
|
||||||
}else if(dst < attractRange && !nearCore){
|
|
||||||
Tmp.v2.set((x - other.x), (y - other.y)).setLength(avoidSpeed);
|
|
||||||
shift.add(Tmp.v2.scl(-1));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
shift.limit(1f);
|
|
||||||
vec.add(shift.scl(0.5f));
|
|
||||||
|
|
||||||
move(vec.x * Timers.delta(), vec.y * Timers.delta());
|
|
||||||
|
|
||||||
updateTargeting(nearCore);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateTargeting(boolean nearCore){
|
|
||||||
if(target != null && target instanceof TileEntity && ((TileEntity)target).dead){
|
|
||||||
target = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(timer.get(timerTarget, 15) && !nearCore){
|
|
||||||
target = Vars.world.findTileTarget(x, y, null, range, false);
|
|
||||||
|
|
||||||
//no tile found
|
|
||||||
if(target == null){
|
|
||||||
target = Entities.getClosest(Vars.control.playerGroup, x, y, range, e -> true);
|
|
||||||
}
|
|
||||||
}else if(nearCore){
|
|
||||||
target = Vars.control.getCore().entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(target != null && bullet != null){
|
|
||||||
updateShooting();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateShooting(){
|
|
||||||
if(timer.get(timerReload, reload * Vars.multiplier)){
|
|
||||||
shoot(bullet);
|
|
||||||
if(shootsound != null) Effects.sound(shootsound, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void shoot(BulletType bullet){
|
|
||||||
shoot(bullet, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shoot(BulletType bullet, float rotation){
|
|
||||||
|
|
||||||
if(!(Net.active() && Net.client())) {
|
|
||||||
Angles.translation(angle + rotation, length);
|
|
||||||
Bullet out = new Bullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation).add();
|
|
||||||
out.damage = (int) (damage * Vars.multiplier);
|
|
||||||
onShoot(bullet, rotation);
|
|
||||||
|
|
||||||
if(Net.active() && Net.server()){
|
|
||||||
Vars.netServer.handleBullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation, (short) (damage * Vars.multiplier));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void onShoot(BulletType type, float rotation){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void added(){
|
public void update(){
|
||||||
if(bullet != null){
|
type.update(this);
|
||||||
damage = (int) (bullet.damage * (1 + (tier - 1) * 1f));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
maxhealth *= tier;
|
@Override
|
||||||
speed += 0.04f * tier /*+ Mathf.range(0.1f)*/;
|
public void draw(){
|
||||||
reload /= Math.max(tier / 1.5f, 1f);
|
type.draw(this);
|
||||||
range += tier * 5;
|
}
|
||||||
speed = Math.max(speed, 0.07f);
|
|
||||||
|
|
||||||
heal();
|
@Override
|
||||||
|
public void drawOver(){
|
||||||
|
type.drawOver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float drawSize(){
|
||||||
|
return 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -213,90 +61,48 @@ public class Enemy extends DestructibleEntity implements Syncable{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath(){
|
public void onDeath(){
|
||||||
Effects.effect(Fx.explosion, this);
|
type.onDeath(this);
|
||||||
Effects.shake(3f, 4f, this);
|
|
||||||
Effects.sound("bang2", this);
|
|
||||||
remove();
|
|
||||||
dead = true;
|
|
||||||
|
|
||||||
if(Net.active() && Net.server()){
|
|
||||||
Vars.netServer.handleEnemyDeath(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed(){
|
public void removed(){
|
||||||
if(!dead){
|
type.removed(this);
|
||||||
|
|
||||||
if(spawner != null){
|
|
||||||
spawner.spawned --;
|
|
||||||
}else{
|
|
||||||
Vars.control.enemyDeath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void added(){
|
||||||
float lastx = x, lasty = y;
|
hitbox.setSize(type.hitsize);
|
||||||
|
hitboxTile.setSize(type.hitsizeTile);
|
||||||
|
maxhealth = type.health * tier;
|
||||||
|
|
||||||
move();
|
heal();
|
||||||
|
|
||||||
xvelocity = (x - lastx) / Timers.delta();
|
|
||||||
yvelocity = (y - lasty) / Timers.delta();
|
|
||||||
|
|
||||||
float minv = 0.07f;
|
|
||||||
|
|
||||||
if(Vector2.dst(xvelocity, yvelocity, 0, 0) < minv && node > 0 && target == null){
|
|
||||||
idletime += Timers.delta();
|
|
||||||
}else{
|
|
||||||
idletime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tile tile = world.tileWorld(x, y);
|
|
||||||
if(tile != null && tile.floor().liquid && tile.block() == Blocks.air){
|
|
||||||
damage(health+1); //drown
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Float.isNaN(angle)){
|
|
||||||
angle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(target == null || alwaysRotate){
|
|
||||||
angle = Mathf.slerp(angle, 180f+Mathf.atan2(xvelocity, yvelocity), rotatespeed * Timers.delta());
|
|
||||||
}else{
|
|
||||||
angle = Mathf.slerp(angle, angleTo(target), turretrotatespeed * Timers.delta());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(){
|
|
||||||
String region = className + "-t" + Mathf.clamp(tier, 1, 3);
|
|
||||||
|
|
||||||
Shaders.outline.color.set(tierColors[tier - 1]);
|
|
||||||
Shaders.outline.region = Draw.region(region);
|
|
||||||
|
|
||||||
Shaders.outline.apply();
|
|
||||||
|
|
||||||
Draw.rect(region, x, y, this.angle - 90);
|
|
||||||
|
|
||||||
if(Vars.showPaths){
|
|
||||||
Draw.color(Color.PURPLE);
|
|
||||||
Draw.line(x, y, x + xvelocity*10f, y + yvelocity*10f);
|
|
||||||
|
|
||||||
Draw.color(Color.BLACK, Color.WHITE, idletime / maxIdleLife);
|
|
||||||
Draw.square(x, y, 7f);
|
|
||||||
|
|
||||||
Draw.color();
|
|
||||||
}
|
|
||||||
|
|
||||||
Draw.color();
|
|
||||||
|
|
||||||
Graphics.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Enemy add(){
|
public Enemy add(){
|
||||||
return add(Vars.control.enemyGroup);
|
return add(Vars.control.enemyGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Interpolator<Enemy> getInterpolator() {
|
||||||
|
return inter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shoot(BulletType bullet){
|
||||||
|
shoot(bullet, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shoot(BulletType bullet, float rotation){
|
||||||
|
|
||||||
|
if(!(Net.active() && Net.client())) {
|
||||||
|
Angles.translation(angle + rotation, type.length);
|
||||||
|
Bullet out = new Bullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation).add();
|
||||||
|
out.damage = (int) ((bullet.damage * (1 + (tier - 1) * 1f)) * Vars.multiplier);
|
||||||
|
type.onShoot(this, bullet, rotation);
|
||||||
|
|
||||||
|
if(Net.active() && Net.server()){
|
||||||
|
Vars.netServer.handleBullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation, (short)out.damage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
230
core/src/io/anuke/mindustry/entities/enemies/EnemyType.java
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
|
import io.anuke.mindustry.graphics.Shaders;
|
||||||
|
import io.anuke.mindustry.net.Net;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
|
import io.anuke.ucore.core.Draw;
|
||||||
|
import io.anuke.ucore.core.Effects;
|
||||||
|
import io.anuke.ucore.core.Graphics;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.entities.Entities;
|
||||||
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
import io.anuke.ucore.util.Tmp;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
|
public class EnemyType {
|
||||||
|
|
||||||
|
//TODO documentation, comments
|
||||||
|
private static byte lastid = 0;
|
||||||
|
private static Array<EnemyType> types = new Array<>();
|
||||||
|
|
||||||
|
public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") };
|
||||||
|
public final static int maxtier = 4;
|
||||||
|
public final static float maxIdle = 60*1.5f;
|
||||||
|
public final static float maxIdleLife = 60f*13f; //13 seconds idle = death
|
||||||
|
|
||||||
|
public final String name;
|
||||||
|
public final byte id;
|
||||||
|
|
||||||
|
protected int timeid;
|
||||||
|
protected int health = 60;
|
||||||
|
protected float hitsize = 5f;
|
||||||
|
protected float hitsizeTile = 4f;
|
||||||
|
protected float speed = 0.4f;
|
||||||
|
protected float reload = 32;
|
||||||
|
protected float range = 60;
|
||||||
|
protected float length = 4;
|
||||||
|
protected float rotatespeed = 0.1f;
|
||||||
|
protected float turretrotatespeed = 0.2f;
|
||||||
|
protected boolean alwaysRotate = false;
|
||||||
|
protected BulletType bullet = BulletType.small;
|
||||||
|
protected String shootsound = "enemyshoot";
|
||||||
|
protected boolean targetCore = false;
|
||||||
|
protected boolean stopNearCore = true;
|
||||||
|
protected float mass = 1f;
|
||||||
|
|
||||||
|
protected final int timerTarget = timeid ++;
|
||||||
|
protected final int timerReload = timeid ++;
|
||||||
|
|
||||||
|
public EnemyType(String name){
|
||||||
|
this.id = lastid++;
|
||||||
|
this.name = name;
|
||||||
|
types.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Enemy enemy){
|
||||||
|
String region = name + "-t" + Mathf.clamp(enemy.tier, 1, 3);
|
||||||
|
|
||||||
|
Shaders.outline.color.set(tierColors[enemy.tier - 1]);
|
||||||
|
Shaders.outline.region = Draw.region(region);
|
||||||
|
|
||||||
|
Shaders.outline.apply();
|
||||||
|
|
||||||
|
Draw.rect(region, enemy.x, enemy.y, enemy.angle - 90);
|
||||||
|
Draw.color();
|
||||||
|
|
||||||
|
Graphics.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawOver(Enemy enemy){ }
|
||||||
|
|
||||||
|
public void update(Enemy enemy){
|
||||||
|
float lastx = enemy.x, lasty = enemy.y;
|
||||||
|
|
||||||
|
move(enemy);
|
||||||
|
|
||||||
|
enemy.velocity.set(enemy.x - lastx, enemy.y - lasty).scl(1f / Timers.delta());
|
||||||
|
|
||||||
|
float minv = 0.07f;
|
||||||
|
|
||||||
|
if(enemy.velocity.len() < minv && enemy.node > 0 && enemy.target == null){
|
||||||
|
enemy.idletime += Timers.delta();
|
||||||
|
}else{
|
||||||
|
enemy.idletime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tile tile = world.tileWorld(enemy.x, enemy.y);
|
||||||
|
if(tile != null && tile.floor().liquid && tile.block() == Blocks.air){
|
||||||
|
enemy.damage(enemy.health+1); //drown
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Float.isNaN(enemy.angle)){
|
||||||
|
enemy.angle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enemy.target == null || alwaysRotate){
|
||||||
|
enemy.angle = Mathf.slerp(enemy.angle, 180f + enemy.velocity.angle(), rotatespeed * Timers.delta());
|
||||||
|
}else{
|
||||||
|
enemy.angle = Mathf.slerp(enemy.angle, enemy.angleTo(enemy.target), turretrotatespeed * Timers.delta());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void move(Enemy enemy){
|
||||||
|
float speed = this.speed + 0.04f * enemy.tier;
|
||||||
|
float range = this.range + enemy.tier * 5;
|
||||||
|
|
||||||
|
if(Net.client() && Net.active()){
|
||||||
|
enemy.inter.update(enemy); //TODO? better structure for interpolation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tile core = Vars.control.getCore();
|
||||||
|
|
||||||
|
if(enemy.idletime > maxIdleLife){
|
||||||
|
enemy.onDeath();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean nearCore = enemy.distanceTo(core.worldx(), core.worldy()) <= range - 18f && stopNearCore;
|
||||||
|
Vector2 vec;
|
||||||
|
|
||||||
|
if(nearCore){
|
||||||
|
vec = Tmp.v1.setZero();
|
||||||
|
if(targetCore) enemy.target = core.entity;
|
||||||
|
}else{
|
||||||
|
vec = Vars.world.pathfinder().find(enemy);
|
||||||
|
vec.sub(enemy.x, enemy.y).limit(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 shift = Tmp.v3.setZero();
|
||||||
|
float shiftRange = enemy.hitbox.width + 2f;
|
||||||
|
float avoidRange = shiftRange + 4f;
|
||||||
|
float attractRange = avoidRange + 7f;
|
||||||
|
float avoidSpeed = this.speed/2.7f;
|
||||||
|
|
||||||
|
Entities.getNearby(Vars.control.enemyGroup, enemy.x, enemy.y, range, en -> {
|
||||||
|
Enemy other = (Enemy)en;
|
||||||
|
if(other == enemy) return;
|
||||||
|
float dst = other.distanceTo(enemy);
|
||||||
|
|
||||||
|
if(dst < shiftRange){
|
||||||
|
float scl = Mathf.clamp(1.4f - dst / shiftRange) * mass * 1f/mass;
|
||||||
|
shift.add((enemy.x - other.x) * scl, (enemy.y - other.y) * scl);
|
||||||
|
}else if(dst < avoidRange){
|
||||||
|
Tmp.v2.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed);
|
||||||
|
shift.add(Tmp.v2.scl(1.1f));
|
||||||
|
}else if(dst < attractRange && !nearCore){
|
||||||
|
Tmp.v2.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed);
|
||||||
|
shift.add(Tmp.v2.scl(-1));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
shift.limit(1f);
|
||||||
|
vec.add(shift.scl(0.5f));
|
||||||
|
|
||||||
|
enemy.move(vec.x * Timers.delta(), vec.y * Timers.delta());
|
||||||
|
|
||||||
|
updateTargeting(enemy, nearCore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTargeting(Enemy enemy, boolean nearCore){
|
||||||
|
if(enemy.target != null && enemy.target instanceof TileEntity && ((TileEntity)enemy.target).dead){
|
||||||
|
enemy.target = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enemy.timer.get(timerTarget, 15) && !nearCore){
|
||||||
|
enemy.target = Vars.world.findTileTarget(enemy.x, enemy.y, null, range, false);
|
||||||
|
|
||||||
|
//no tile found
|
||||||
|
if(enemy.target == null){
|
||||||
|
enemy.target = Entities.getClosest(Vars.control.playerGroup, enemy.x, enemy.y, range, e -> true);
|
||||||
|
}
|
||||||
|
}else if(nearCore){
|
||||||
|
enemy.target = Vars.control.getCore().entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enemy.target != null && bullet != null){
|
||||||
|
updateShooting(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateShooting(Enemy enemy){
|
||||||
|
float reload = this.reload / Math.max(enemy.tier / 1.5f, 1f);
|
||||||
|
|
||||||
|
if(enemy.timer.get(timerReload, reload * Vars.multiplier)){
|
||||||
|
shoot(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shoot(Enemy enemy){
|
||||||
|
enemy.shoot(bullet);
|
||||||
|
if(shootsound != null) Effects.sound(shootsound, enemy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onShoot(Enemy enemy, BulletType type, float rotation){}
|
||||||
|
|
||||||
|
public void onDeath(Enemy enemy){
|
||||||
|
Effects.effect(Fx.explosion, enemy);
|
||||||
|
Effects.shake(3f, 4f, enemy);
|
||||||
|
Effects.sound("bang2", enemy);
|
||||||
|
enemy.remove();
|
||||||
|
enemy.dead = true;
|
||||||
|
|
||||||
|
if(Net.active() && Net.server()){
|
||||||
|
Vars.netServer.handleEnemyDeath(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removed(Enemy enemy){
|
||||||
|
if(!enemy.dead){
|
||||||
|
if(enemy.spawner != null){
|
||||||
|
enemy.spawner.spawned --;
|
||||||
|
}else{
|
||||||
|
Vars.control.enemyDeath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EnemyType getByID(byte id){
|
||||||
|
return types.get(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
core/src/io/anuke/mindustry/entities/enemies/EnemyTypes.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.BlastEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.EmpEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.FastEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.FlamerEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.FortressEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.HealerEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.MortarEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.RapidEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.*;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.TankEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.TargetEnemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.types.TitanEnemy;
|
||||||
|
|
||||||
|
public class EnemyTypes {
|
||||||
|
public static final EnemyType
|
||||||
|
|
||||||
|
standard = new StandardEnemy(),
|
||||||
|
fast = new FastEnemy(),
|
||||||
|
rapid = new RapidEnemy(),
|
||||||
|
flamer = new FlamerEnemy(),
|
||||||
|
tank = new TankEnemy(),
|
||||||
|
blast = new BlastEnemy(),
|
||||||
|
mortar = new MortarEnemy(),
|
||||||
|
healer = new HealerEnemy(),
|
||||||
|
titan = new TitanEnemy(),
|
||||||
|
emp = new EmpEnemy(),
|
||||||
|
fortress = new FortressEnemy(),
|
||||||
|
target = new TargetEnemy();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
public class FastEnemy extends Enemy{
|
|
||||||
|
|
||||||
public FastEnemy() {
|
|
||||||
|
|
||||||
speed = 0.73f;
|
|
||||||
reload = 25;
|
|
||||||
mass = 0.2f;
|
|
||||||
|
|
||||||
maxhealth = 40;
|
|
||||||
heal();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
|
||||||
import io.anuke.ucore.core.Effects;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.util.Angles;
|
|
||||||
|
|
||||||
public class FortressEnemy extends Enemy{
|
|
||||||
static int maxSpawn = 6;
|
|
||||||
|
|
||||||
float spawnTime = 190;
|
|
||||||
boolean deployed;
|
|
||||||
|
|
||||||
public FortressEnemy() {
|
|
||||||
|
|
||||||
speed = 0.25f;
|
|
||||||
reload = 90;
|
|
||||||
maxhealth = 700;
|
|
||||||
range = 70f;
|
|
||||||
bullet = BulletType.yellowshell;
|
|
||||||
hitbox.setSize(10f);
|
|
||||||
turretrotatespeed = rotatespeed = 0.08f;
|
|
||||||
length = 7f;
|
|
||||||
mass = 7f;
|
|
||||||
|
|
||||||
heal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void move(){
|
|
||||||
super.move();
|
|
||||||
|
|
||||||
if(deployed){
|
|
||||||
|
|
||||||
if(Timers.get(this, "spawn", spawnTime) && spawned < maxSpawn){
|
|
||||||
Angles.translation(angle, 20f);
|
|
||||||
|
|
||||||
FastEnemy enemy = new FastEnemy();
|
|
||||||
enemy.lane = lane;
|
|
||||||
enemy.tier = this.tier;
|
|
||||||
enemy.spawner = this;
|
|
||||||
enemy.set(x + Angles.x(), y + Angles.y());
|
|
||||||
Effects.effect(Fx.spawn, enemy);
|
|
||||||
enemy.add();
|
|
||||||
spawned ++;
|
|
||||||
}
|
|
||||||
}else if(distanceTo(Vars.control.getCore().worldx(),
|
|
||||||
Vars.control.getCore().worldy()) <= 90f){
|
|
||||||
deployed = true;
|
|
||||||
speed = 0.001f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void onShoot(BulletType type, float rotation){
|
|
||||||
Effects.effect(Fx.largeCannonShot, x + Angles.x(), y + Angles.y(), angle);
|
|
||||||
Effects.shake(3f, 3f, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.entities.Bullet;
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
|
||||||
import io.anuke.mindustry.graphics.Shaders;
|
|
||||||
import io.anuke.ucore.core.*;
|
|
||||||
import io.anuke.ucore.entities.Entities;
|
|
||||||
import io.anuke.ucore.graphics.Hue;
|
|
||||||
import io.anuke.ucore.util.Angles;
|
|
||||||
|
|
||||||
public class HealerEnemy extends Enemy{
|
|
||||||
|
|
||||||
public HealerEnemy() {
|
|
||||||
|
|
||||||
speed = 0.25f;
|
|
||||||
reload = 10;
|
|
||||||
maxhealth = 200;
|
|
||||||
bullet = BulletType.shot;
|
|
||||||
range = 40f;
|
|
||||||
alwaysRotate = false;
|
|
||||||
targetCore = false;
|
|
||||||
stopNearCore = true;
|
|
||||||
mass = 1.1f;
|
|
||||||
|
|
||||||
heal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void move(){
|
|
||||||
super.move();
|
|
||||||
|
|
||||||
if(idletime > 60f*3){ //explode after 3 seconds of stillness
|
|
||||||
explode();
|
|
||||||
Effects.effect(Fx.shellexplosion, this);
|
|
||||||
Effects.effect(Fx.shellsmoke, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void updateTargeting(boolean nearCore){
|
|
||||||
if(timer.get(timerTarget, 15)){
|
|
||||||
target = Entities.getClosest(Vars.control.enemyGroup,
|
|
||||||
x, y, range, e -> e instanceof Enemy && e != this && ((Enemy)e).healthfrac() < 1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(target != null){
|
|
||||||
updateShooting();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void updateShooting(){
|
|
||||||
Enemy enemy = (Enemy)target;
|
|
||||||
|
|
||||||
if(enemy.health < enemy.maxhealth && Timers.get(this, "heal", reload)){
|
|
||||||
enemy.health ++;
|
|
||||||
idletime = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drawOver(){
|
|
||||||
super.drawOver();
|
|
||||||
Enemy enemy = (Enemy)target;
|
|
||||||
|
|
||||||
if(enemy == null) return;
|
|
||||||
|
|
||||||
Angles.translation(this.angleTo(enemy), 5f);
|
|
||||||
|
|
||||||
Graphics.shader();
|
|
||||||
if(enemy != null && enemy.health < enemy.maxhealth){
|
|
||||||
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f));
|
|
||||||
Draw.alpha(0.9f);
|
|
||||||
Draw.laser("laser", "laserend", x + Angles.x(), y + Angles.y(), enemy.x - Angles.x()/1.5f, enemy.y - Angles.y()/1.5f);
|
|
||||||
Draw.color();
|
|
||||||
}
|
|
||||||
Graphics.shader(Shaders.outline);
|
|
||||||
}
|
|
||||||
|
|
||||||
void explode(){
|
|
||||||
Bullet b = new Bullet(BulletType.blast, this, x, y, 0).add();
|
|
||||||
b.damage = BulletType.blast.damage + (tier-1) * 30;
|
|
||||||
damage(999);
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
|
||||||
|
|
||||||
public class RapidEnemy extends Enemy{
|
|
||||||
|
|
||||||
public RapidEnemy() {
|
|
||||||
|
|
||||||
reload = 8;
|
|
||||||
bullet = BulletType.purple;
|
|
||||||
rotatespeed = 0.08f;
|
|
||||||
maxhealth = 260;
|
|
||||||
speed = 0.33f;
|
|
||||||
heal();
|
|
||||||
hitbox.setSize(8f);
|
|
||||||
mass = 3f;
|
|
||||||
|
|
||||||
range = 70;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.entities.Bullet;
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
|
||||||
import io.anuke.ucore.util.Angles;
|
|
||||||
|
|
||||||
public class TankEnemy extends Enemy{
|
|
||||||
|
|
||||||
public TankEnemy() {
|
|
||||||
|
|
||||||
maxhealth = 350;
|
|
||||||
speed = 0.24f;
|
|
||||||
reload = 90f;
|
|
||||||
rotatespeed = 0.06f;
|
|
||||||
bullet = BulletType.small;
|
|
||||||
length = 3f;
|
|
||||||
mass = 1.4f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shoot(){
|
|
||||||
Angles.translation(angle, 8f);
|
|
||||||
|
|
||||||
Angles.shotgun(3, 8f, angle, f->{
|
|
||||||
Bullet out = new Bullet(bullet, this, x+vector.x, y+vector.y, f).add();
|
|
||||||
out.damage = (int)(damage*Vars.multiplier);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
|
||||||
import io.anuke.ucore.core.Draw;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
|
|
||||||
public class TargetEnemy extends Enemy{
|
|
||||||
|
|
||||||
public TargetEnemy(){
|
|
||||||
speed = 0f;
|
|
||||||
maxhealth = 25;
|
|
||||||
shootsound = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void move(){
|
|
||||||
speed = 0f;
|
|
||||||
super.move();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void shoot(BulletType bullet){
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removed(){
|
|
||||||
//don't call enemy death since this is only a target
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(){
|
|
||||||
super.draw();
|
|
||||||
|
|
||||||
Draw.color(Color.YELLOW);
|
|
||||||
|
|
||||||
if(Vars.control.getTutorial().showTarget()){
|
|
||||||
Draw.spikes(x, y, 11f + Mathf.sin(Timers.time(), 7f, 1f), 4f, 8, Timers.time());
|
|
||||||
}
|
|
||||||
|
|
||||||
Draw.color();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDeath(){
|
|
||||||
super.onDeath();
|
|
||||||
Timers.run(100f, ()->{
|
|
||||||
new TargetEnemy().set(x, y).add();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
|
|
||||||
public class TestEnemy extends Enemy{
|
|
||||||
boolean dir = false;
|
|
||||||
|
|
||||||
public TestEnemy() {
|
|
||||||
maxhealth = 99999;
|
|
||||||
heal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void move(){
|
|
||||||
if(Timers.get(this, "switch", 300)){
|
|
||||||
dir = !dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
move(dir ? -0.3f * Timers.delta() : 0.3f * Timers.delta(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.util.Angles;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
|
|
||||||
public class TitanEnemy extends Enemy{
|
|
||||||
|
|
||||||
public TitanEnemy() {
|
|
||||||
|
|
||||||
speed = 0.26f;
|
|
||||||
reload = 30;
|
|
||||||
maxhealth = 430;
|
|
||||||
range = 60f;
|
|
||||||
bullet = BulletType.small;
|
|
||||||
hitbox.setSize(7f);
|
|
||||||
mass = 4f;
|
|
||||||
|
|
||||||
heal();
|
|
||||||
|
|
||||||
Timers.reset(this, "salvo", 0);
|
|
||||||
Timers.reset(this, "shotgun", 0);
|
|
||||||
Timers.reset(this, "circle", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void updateShooting(){
|
|
||||||
Timers.get(this, "salvo", 240);
|
|
||||||
|
|
||||||
if(Timers.getTime(this, "salvo") < 60){
|
|
||||||
if(Timers.get(this, "salvoShoot", 6)){
|
|
||||||
shoot(BulletType.flame, Mathf.range(20f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Timers.get(this, "shotgun", 80)){
|
|
||||||
Angles.shotgun(5, 10f, 0f, f->{
|
|
||||||
shoot(BulletType.smallSlow, f);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Timers.get(this, "circle", 200)){
|
|
||||||
Angles.circle(8, f->{
|
|
||||||
shoot(BulletType.smallSlow, f);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.enemies.flying;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
|
||||||
|
|
||||||
public class FlyingEnemy extends Enemy{
|
|
||||||
|
|
||||||
public FlyingEnemy() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.entities.Bullet;
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
import io.anuke.ucore.util.Tmp;
|
||||||
|
|
||||||
|
public class BlastEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public BlastEnemy() {
|
||||||
|
super("blastenemy");
|
||||||
|
health = 30;
|
||||||
|
speed = 0.7f;
|
||||||
|
bullet = null;
|
||||||
|
turretrotatespeed = 0f;
|
||||||
|
mass = 0.8f;
|
||||||
|
stopNearCore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(Enemy enemy){
|
||||||
|
super.move(enemy);
|
||||||
|
|
||||||
|
float range = 10f;
|
||||||
|
Vector2 offset = Tmp.v3.setZero();
|
||||||
|
|
||||||
|
if(enemy.target instanceof TileEntity){
|
||||||
|
TileEntity e = (TileEntity)enemy.target;
|
||||||
|
range = (e.tile.block().width * Vars.tilesize) /2f + 8f;
|
||||||
|
offset.set(e.tile.block().getPlaceOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enemy.target != null && enemy.target.distanceTo(enemy.x - offset.x, enemy.y - offset.y) < range){
|
||||||
|
explode(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeath(Enemy enemy){
|
||||||
|
super.onDeath(enemy);
|
||||||
|
explode(enemy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void explode(Enemy enemy){
|
||||||
|
Bullet b = new Bullet(BulletType.blast, enemy, enemy.x, enemy.y, 0).add();
|
||||||
|
b.damage = BulletType.blast.damage + (enemy.tier-1) * 40;
|
||||||
|
enemy.damage(999);
|
||||||
|
enemy.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
|
||||||
|
public class EmpEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public EmpEnemy() {
|
||||||
|
super("empenemy");
|
||||||
|
|
||||||
|
speed = 0.3f;
|
||||||
|
reload = 70;
|
||||||
|
health = 210;
|
||||||
|
range = 80f;
|
||||||
|
bullet = BulletType.emp;
|
||||||
|
turretrotatespeed = 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
|
||||||
|
public class FastEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public FastEnemy() {
|
||||||
|
super("fastenemy");
|
||||||
|
|
||||||
|
speed = 0.73f;
|
||||||
|
reload = 25;
|
||||||
|
mass = 0.2f;
|
||||||
|
|
||||||
|
health = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,22 +1,20 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
|
||||||
public class FlamerEnemy extends Enemy{
|
public class FlamerEnemy extends EnemyType {
|
||||||
|
|
||||||
public FlamerEnemy() {
|
public FlamerEnemy() {
|
||||||
|
super("flamerenemy");
|
||||||
|
|
||||||
speed = 0.35f;
|
speed = 0.35f;
|
||||||
|
health = 150;
|
||||||
maxhealth = 150;
|
|
||||||
reload = 6;
|
reload = 6;
|
||||||
bullet = BulletType.flameshot;
|
bullet = BulletType.flameshot;
|
||||||
shootsound = "flame";
|
shootsound = "flame";
|
||||||
mass = 1.5f;
|
mass = 1.5f;
|
||||||
|
|
||||||
range = 40;
|
range = 40;
|
||||||
|
|
||||||
heal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||||
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
|
import io.anuke.ucore.core.Effects;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.util.Angles;
|
||||||
|
|
||||||
|
public class FortressEnemy extends EnemyType {
|
||||||
|
final int maxSpawn = 6;
|
||||||
|
final float spawnTime = 190;
|
||||||
|
|
||||||
|
public FortressEnemy() {
|
||||||
|
super("fortressenemy");
|
||||||
|
|
||||||
|
speed = 0.25f;
|
||||||
|
reload = 90;
|
||||||
|
health = 700;
|
||||||
|
range = 70f;
|
||||||
|
bullet = BulletType.yellowshell;
|
||||||
|
hitsize = 10f;
|
||||||
|
turretrotatespeed = rotatespeed = 0.08f;
|
||||||
|
length = 7f;
|
||||||
|
mass = 7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(Enemy enemy){
|
||||||
|
if(enemy.distanceTo(Vars.control.getCore().worldx(),
|
||||||
|
Vars.control.getCore().worldy()) <= 90f){
|
||||||
|
|
||||||
|
if(Timers.get(this, "spawn", spawnTime) && enemy.spawned < maxSpawn){
|
||||||
|
Angles.translation(enemy.angle, 20f);
|
||||||
|
|
||||||
|
Enemy s = new Enemy(EnemyTypes.fast); //TODO assign type!
|
||||||
|
s.lane = enemy.lane;
|
||||||
|
s.tier = enemy.tier;
|
||||||
|
s.spawner = enemy;
|
||||||
|
s.set(enemy.x + Angles.x(), enemy.y + Angles.y());
|
||||||
|
s.add();
|
||||||
|
|
||||||
|
Effects.effect(Fx.spawn, enemy);
|
||||||
|
enemy.spawned ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}else {
|
||||||
|
super.move(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void onShoot(Enemy enemy, BulletType type, float rotation){
|
||||||
|
Effects.effect(Fx.largeCannonShot, enemy.x + Angles.x(), enemy.y + Angles.y(), enemy.angle);
|
||||||
|
Effects.shake(3f, 3f, enemy);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.entities.Bullet;
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
import io.anuke.mindustry.graphics.Fx;
|
||||||
|
import io.anuke.mindustry.graphics.Shaders;
|
||||||
|
import io.anuke.ucore.core.*;
|
||||||
|
import io.anuke.ucore.entities.Entities;
|
||||||
|
import io.anuke.ucore.graphics.Hue;
|
||||||
|
import io.anuke.ucore.util.Angles;
|
||||||
|
|
||||||
|
public class HealerEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public HealerEnemy() {
|
||||||
|
super("healerenemy");
|
||||||
|
|
||||||
|
speed = 0.25f;
|
||||||
|
reload = 10;
|
||||||
|
health = 200;
|
||||||
|
bullet = BulletType.shot;
|
||||||
|
range = 40f;
|
||||||
|
alwaysRotate = false;
|
||||||
|
targetCore = false;
|
||||||
|
stopNearCore = true;
|
||||||
|
mass = 1.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(Enemy enemy){
|
||||||
|
super.move(enemy);
|
||||||
|
|
||||||
|
if(enemy.idletime > 60f*3){ //explode after 3 seconds of stillness
|
||||||
|
explode(enemy);
|
||||||
|
Effects.effect(Fx.shellexplosion, enemy);
|
||||||
|
Effects.effect(Fx.shellsmoke, enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTargeting(Enemy enemy, boolean nearCore){
|
||||||
|
if(enemy.timer.get(timerTarget, 15)){
|
||||||
|
enemy.target = Entities.getClosest(Vars.control.enemyGroup,
|
||||||
|
enemy.x, enemy.y, range, e -> e instanceof Enemy && e != enemy && ((Enemy)e).healthfrac() < 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enemy.target != null){
|
||||||
|
updateShooting(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateShooting(Enemy enemy){
|
||||||
|
Enemy target = (Enemy)enemy.target;
|
||||||
|
|
||||||
|
if(target.health < target.maxhealth && enemy.timer.get(timerReload, reload)){
|
||||||
|
target.health ++;
|
||||||
|
enemy.idletime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawOver(Enemy enemy){
|
||||||
|
Enemy target = (Enemy)enemy.target;
|
||||||
|
|
||||||
|
if(target == null) return;
|
||||||
|
|
||||||
|
Angles.translation(enemy.angleTo(target), 5f);
|
||||||
|
|
||||||
|
Graphics.shader();
|
||||||
|
if(target.health < target.maxhealth){
|
||||||
|
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f));
|
||||||
|
Draw.alpha(0.9f);
|
||||||
|
Draw.laser("laser", "laserend", enemy.x + Angles.x(), enemy.y + Angles.y(), target.x - Angles.x()/1.5f, target.y - Angles.y()/1.5f);
|
||||||
|
Draw.color();
|
||||||
|
}
|
||||||
|
Graphics.shader(Shaders.outline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void explode(Enemy enemy){
|
||||||
|
Bullet b = new Bullet(BulletType.blast, enemy, enemy.x, enemy.y, 0).add();
|
||||||
|
b.damage = BulletType.blast.damage + (enemy.tier-1) * 30;
|
||||||
|
enemy.damage(999);
|
||||||
|
enemy.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
|
||||||
public class MortarEnemy extends Enemy{
|
public class MortarEnemy extends EnemyType {
|
||||||
|
|
||||||
public MortarEnemy() {
|
public MortarEnemy() {
|
||||||
|
super("mortarenemy");
|
||||||
|
|
||||||
maxhealth = 200;
|
health = 200;
|
||||||
speed = 0.25f;
|
speed = 0.25f;
|
||||||
reload = 100f;
|
reload = 100f;
|
||||||
bullet = BulletType.shell;
|
bullet = BulletType.shell;
|
||||||
@@ -14,8 +16,6 @@ public class MortarEnemy extends Enemy{
|
|||||||
rotatespeed = 0.05f;
|
rotatespeed = 0.05f;
|
||||||
range = 120f;
|
range = 120f;
|
||||||
mass = 1.2f;
|
mass = 1.2f;
|
||||||
|
|
||||||
heal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
|
||||||
|
public class RapidEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public RapidEnemy() {
|
||||||
|
super("rapidenemy");
|
||||||
|
|
||||||
|
reload = 8;
|
||||||
|
bullet = BulletType.purple;
|
||||||
|
rotatespeed = 0.08f;
|
||||||
|
health = 260;
|
||||||
|
speed = 0.33f;
|
||||||
|
hitsize = 8f;
|
||||||
|
mass = 3f;
|
||||||
|
range = 70;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
|
||||||
|
public class StandardEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public StandardEnemy(){
|
||||||
|
super("standardenemy");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
import io.anuke.ucore.util.Angles;
|
||||||
|
|
||||||
|
public class TankEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public TankEnemy() {
|
||||||
|
super("tankenemy");
|
||||||
|
|
||||||
|
health = 350;
|
||||||
|
speed = 0.24f;
|
||||||
|
reload = 90f;
|
||||||
|
rotatespeed = 0.06f;
|
||||||
|
bullet = BulletType.small;
|
||||||
|
length = 3f;
|
||||||
|
mass = 1.4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shoot(Enemy enemy){
|
||||||
|
super.shoot(enemy);
|
||||||
|
|
||||||
|
Angles.translation(enemy.angle, 8f);
|
||||||
|
|
||||||
|
Angles.shotgun(3, 8f, enemy.angle, f -> {
|
||||||
|
enemy.shoot(bullet, f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||||
|
import io.anuke.ucore.core.Draw;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
|
public class TargetEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public TargetEnemy(){
|
||||||
|
super("targetenemy");
|
||||||
|
|
||||||
|
speed = 0f;
|
||||||
|
health = 25;
|
||||||
|
shootsound = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(Enemy enemy){
|
||||||
|
super.move(enemy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shoot(Enemy enemy){
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removed(Enemy enemy){
|
||||||
|
//don't call enemy death since this is only a target
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Enemy enemy){
|
||||||
|
super.draw(enemy);
|
||||||
|
|
||||||
|
Draw.color(Color.YELLOW);
|
||||||
|
|
||||||
|
if(Vars.control.getTutorial().showTarget()){
|
||||||
|
Draw.spikes(enemy.x, enemy.y, 11f + Mathf.sin(Timers.time(), 7f, 1f), 4f, 8, Timers.time());
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.color();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeath(Enemy enemy){
|
||||||
|
super.onDeath(enemy);
|
||||||
|
Timers.run(100f, ()->{
|
||||||
|
new Enemy(EnemyTypes.target).set(enemy.x, enemy.y).add();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.util.Angles;
|
||||||
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
|
public class TitanEnemy extends EnemyType {
|
||||||
|
|
||||||
|
public TitanEnemy() {
|
||||||
|
super("titanenemy");
|
||||||
|
|
||||||
|
speed = 0.26f;
|
||||||
|
reload = 30;
|
||||||
|
health = 430;
|
||||||
|
range = 60f;
|
||||||
|
bullet = BulletType.small;
|
||||||
|
hitsize = 7f;
|
||||||
|
mass = 4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateShooting(Enemy enemy){
|
||||||
|
Timers.get(enemy, "salvo", 240);
|
||||||
|
|
||||||
|
if(Timers.getTime(enemy, "salvo") < 60){
|
||||||
|
if(Timers.get(enemy, "salvoShoot", 6)){
|
||||||
|
enemy.shoot(BulletType.flame, Mathf.range(20f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Timers.get(enemy, "shotgun", 80)){
|
||||||
|
Angles.shotgun(5, 10f, 0f, f->{
|
||||||
|
enemy.shoot(BulletType.smallSlow, f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Timers.get(enemy, "circle", 200)){
|
||||||
|
Angles.circle(8, f->{
|
||||||
|
enemy.shoot(BulletType.smallSlow, f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.GameMode;
|
import io.anuke.mindustry.world.GameMode;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
@@ -16,9 +18,6 @@ import io.anuke.ucore.entities.Entities;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.io.SaveFileVersion.enemyIDs;
|
|
||||||
import static io.anuke.mindustry.io.SaveFileVersion.idEnemies;
|
|
||||||
|
|
||||||
public class NetworkIO {
|
public class NetworkIO {
|
||||||
private static final int fileVersionID = 13;
|
private static final int fileVersionID = 13;
|
||||||
|
|
||||||
@@ -45,28 +44,20 @@ public class NetworkIO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--ENEMIES--
|
//--ENEMIES--
|
||||||
|
Array<Enemy> enemies = Vars.control.enemyGroup.all();
|
||||||
|
|
||||||
int totalEnemies = 0;
|
stream.writeInt(enemies.size); //enemy amount
|
||||||
|
|
||||||
for(Enemy entity : Vars.control.enemyGroup.all()){
|
for(int i = 0; i < enemies.size; i ++){
|
||||||
if(idEnemies.containsKey(entity.getClass())){
|
Enemy enemy = enemies.get(i);
|
||||||
totalEnemies ++;
|
stream.writeInt(enemy.id);
|
||||||
}
|
stream.writeByte(enemy.type.id); //type
|
||||||
}
|
stream.writeByte(enemy.lane); //lane
|
||||||
|
stream.writeFloat(enemy.x); //x
|
||||||
stream.writeInt(totalEnemies); //enemy amount
|
stream.writeFloat(enemy.y); //y
|
||||||
|
stream.writeByte(enemy.tier); //tier
|
||||||
for(Enemy enemy : Vars.control.enemyGroup.all()){
|
stream.writeShort(enemy.health); //health
|
||||||
if(idEnemies.containsKey(enemy.getClass())){
|
stream.writeShort(enemy.node); //current node
|
||||||
stream.writeInt(enemy.id);
|
|
||||||
stream.writeByte(idEnemies.get(enemy.getClass())); //type
|
|
||||||
stream.writeByte(enemy.lane); //lane
|
|
||||||
stream.writeFloat(enemy.x); //x
|
|
||||||
stream.writeFloat(enemy.y); //y
|
|
||||||
stream.writeByte(enemy.tier); //tier
|
|
||||||
stream.writeShort(enemy.health); //health
|
|
||||||
stream.writeShort(enemy.node); //current node
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--MAP DATA--
|
//--MAP DATA--
|
||||||
@@ -210,19 +201,15 @@ public class NetworkIO {
|
|||||||
short health = stream.readShort();
|
short health = stream.readShort();
|
||||||
short node = stream.readShort();
|
short node = stream.readShort();
|
||||||
|
|
||||||
try{
|
Enemy enemy = new Enemy(EnemyType.getByID(type));
|
||||||
Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type));
|
enemy.id = id;
|
||||||
enemy.id = id;
|
enemy.lane = lane;
|
||||||
enemy.lane = lane;
|
enemy.health = health;
|
||||||
enemy.health = health;
|
enemy.x = x;
|
||||||
enemy.x = x;
|
enemy.y = y;
|
||||||
enemy.y = y;
|
enemy.tier = tier;
|
||||||
enemy.tier = tier;
|
enemy.node = node;
|
||||||
enemy.node = node;
|
enemy.add(Vars.control.enemyGroup);
|
||||||
enemy.add(Vars.control.enemyGroup);
|
|
||||||
}catch (Exception e){
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vars.control.setWaveData(enemies, wave, wavetime);
|
Vars.control.setWaveData(enemies, wave, wavetime);
|
||||||
|
|||||||
@@ -1,34 +1,10 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
|
||||||
import io.anuke.mindustry.entities.enemies.*;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public abstract class SaveFileVersion {
|
public abstract class SaveFileVersion {
|
||||||
public static final Array<Class<? extends Enemy>> enemyIDs = Array.with(
|
|
||||||
Enemy.class,
|
|
||||||
FastEnemy.class,
|
|
||||||
RapidEnemy.class,
|
|
||||||
FlamerEnemy.class,
|
|
||||||
TankEnemy.class,
|
|
||||||
BlastEnemy.class,
|
|
||||||
MortarEnemy.class,
|
|
||||||
TestEnemy.class,
|
|
||||||
HealerEnemy.class,
|
|
||||||
TitanEnemy.class,
|
|
||||||
EmpEnemy.class
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final ObjectMap<Class<? extends Enemy>, Byte> idEnemies = new ObjectMap<Class<? extends Enemy>, Byte>(){{
|
|
||||||
for(int i = 0; i < enemyIDs.size; i ++){
|
|
||||||
put(enemyIDs.get(i), (byte)i);
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
public final int version;
|
public final int version;
|
||||||
|
|
||||||
public SaveFileVersion(int version){
|
public SaveFileVersion(int version){
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package io.anuke.mindustry.io.versions;
|
|||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.mindustry.io.SaveFileVersion;
|
import io.anuke.mindustry.io.SaveFileVersion;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
@@ -101,7 +101,7 @@ public class Save12 extends SaveFileVersion {
|
|||||||
int health = stream.readInt();
|
int health = stream.readInt();
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type));
|
Enemy enemy = new Enemy(EnemyType.getByID(type));
|
||||||
enemy.lane = lane;
|
enemy.lane = lane;
|
||||||
enemy.health = health;
|
enemy.health = health;
|
||||||
enemy.x = x;
|
enemy.x = x;
|
||||||
@@ -219,29 +219,18 @@ public class Save12 extends SaveFileVersion {
|
|||||||
|
|
||||||
//--ENEMIES--
|
//--ENEMIES--
|
||||||
|
|
||||||
int totalEnemies = 0;
|
|
||||||
|
|
||||||
Array<Enemy> enemies = Vars.control.enemyGroup.all();
|
Array<Enemy> enemies = Vars.control.enemyGroup.all();
|
||||||
|
|
||||||
for(int i = 0; i < enemies.size; i ++){
|
stream.writeInt(enemies.size); //enemy amount
|
||||||
Enemy enemy = enemies.get(i);
|
|
||||||
if(idEnemies.containsKey(enemy.getClass())){
|
|
||||||
totalEnemies ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.writeInt(totalEnemies); //enemy amount
|
|
||||||
|
|
||||||
for(int i = 0; i < enemies.size; i ++){
|
for(int i = 0; i < enemies.size; i ++){
|
||||||
Enemy enemy = enemies.get(i);
|
Enemy enemy = enemies.get(i);
|
||||||
if(idEnemies.containsKey(enemy.getClass())){
|
stream.writeByte(enemy.type.id); //type
|
||||||
stream.writeByte(idEnemies.get(enemy.getClass())); //type
|
stream.writeByte(enemy.lane); //lane
|
||||||
stream.writeByte(enemy.lane); //lane
|
stream.writeFloat(enemy.x); //x
|
||||||
stream.writeFloat(enemy.x); //x
|
stream.writeFloat(enemy.y); //y
|
||||||
stream.writeFloat(enemy.y); //y
|
stream.writeByte(enemy.tier); //tier
|
||||||
stream.writeByte(enemy.tier); //tier
|
stream.writeInt(enemy.health); //health
|
||||||
stream.writeInt(enemy.health); //health
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--MAP DATA--
|
//--MAP DATA--
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package io.anuke.mindustry.io.versions;
|
|||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.mindustry.io.SaveFileVersion;
|
import io.anuke.mindustry.io.SaveFileVersion;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
@@ -101,7 +101,7 @@ public class Save13 extends SaveFileVersion {
|
|||||||
int health = stream.readShort();
|
int health = stream.readShort();
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type));
|
Enemy enemy = new Enemy(EnemyType.getByID(type));
|
||||||
enemy.lane = lane;
|
enemy.lane = lane;
|
||||||
enemy.health = health;
|
enemy.health = health;
|
||||||
enemy.x = x;
|
enemy.x = x;
|
||||||
@@ -228,30 +228,18 @@ public class Save13 extends SaveFileVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--ENEMIES--
|
//--ENEMIES--
|
||||||
|
|
||||||
int totalEnemies = 0;
|
|
||||||
|
|
||||||
Array<Enemy> enemies = Vars.control.enemyGroup.all();
|
Array<Enemy> enemies = Vars.control.enemyGroup.all();
|
||||||
|
|
||||||
for(int i = 0; i < enemies.size; i ++){
|
stream.writeInt(enemies.size); //enemy amount
|
||||||
Enemy enemy = enemies.get(i);
|
|
||||||
if(idEnemies.containsKey(enemy.getClass())){
|
|
||||||
totalEnemies ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.writeInt(totalEnemies); //enemy amount
|
|
||||||
|
|
||||||
for(int i = 0; i < enemies.size; i ++){
|
for(int i = 0; i < enemies.size; i ++){
|
||||||
Enemy enemy = enemies.get(i);
|
Enemy enemy = enemies.get(i);
|
||||||
if(idEnemies.containsKey(enemy.getClass())){
|
stream.writeByte(enemy.type.id); //type
|
||||||
stream.writeByte(idEnemies.get(enemy.getClass())); //type
|
stream.writeByte(enemy.lane); //lane
|
||||||
stream.writeByte(enemy.lane); //lane
|
stream.writeFloat(enemy.x); //x
|
||||||
stream.writeFloat(enemy.x); //x
|
stream.writeFloat(enemy.y); //y
|
||||||
stream.writeFloat(enemy.y); //y
|
stream.writeByte(enemy.tier); //tier
|
||||||
stream.writeByte(enemy.tier); //tier
|
stream.writeShort(enemy.health); //health
|
||||||
stream.writeShort(enemy.health); //health
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--MAP DATA--
|
//--MAP DATA--
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package io.anuke.mindustry.io.versions;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.IntMap;
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||||
import io.anuke.mindustry.io.SaveFileVersion;
|
import io.anuke.mindustry.io.SaveFileVersion;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
@@ -119,7 +119,7 @@ public class Save14 extends SaveFileVersion{
|
|||||||
int health = stream.readShort();
|
int health = stream.readShort();
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type));
|
Enemy enemy = new Enemy(EnemyType.getByID(type));
|
||||||
enemy.lane = lane;
|
enemy.lane = lane;
|
||||||
enemy.health = health;
|
enemy.health = health;
|
||||||
enemy.x = x;
|
enemy.x = x;
|
||||||
@@ -257,29 +257,18 @@ public class Save14 extends SaveFileVersion{
|
|||||||
|
|
||||||
//--ENEMIES--
|
//--ENEMIES--
|
||||||
|
|
||||||
int totalEnemies = 0;
|
|
||||||
|
|
||||||
Array<Enemy> enemies = Vars.control.enemyGroup.all();
|
Array<Enemy> enemies = Vars.control.enemyGroup.all();
|
||||||
|
|
||||||
for(int i = 0; i < enemies.size; i ++){
|
stream.writeInt(enemies.size); //enemy amount
|
||||||
Enemy enemy = enemies.get(i);
|
|
||||||
if(idEnemies.containsKey(enemy.getClass())){
|
|
||||||
totalEnemies ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.writeInt(totalEnemies); //enemy amount
|
|
||||||
|
|
||||||
for(int i = 0; i < enemies.size; i ++){
|
for(int i = 0; i < enemies.size; i ++){
|
||||||
Enemy enemy = enemies.get(i);
|
Enemy enemy = enemies.get(i);
|
||||||
if(idEnemies.containsKey(enemy.getClass())){
|
stream.writeByte(enemy.type.id); //type
|
||||||
stream.writeByte(idEnemies.get(enemy.getClass())); //type
|
stream.writeByte(enemy.lane); //lane
|
||||||
stream.writeByte(enemy.lane); //lane
|
stream.writeFloat(enemy.x); //x
|
||||||
stream.writeFloat(enemy.x); //x
|
stream.writeFloat(enemy.y); //y
|
||||||
stream.writeFloat(enemy.y); //y
|
stream.writeByte(enemy.tier); //tier
|
||||||
stream.writeByte(enemy.tier); //tier
|
stream.writeShort(enemy.health); //health
|
||||||
stream.writeShort(enemy.health); //health
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--MAP DATA--
|
//--MAP DATA--
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package io.anuke.mindustry.net;
|
|||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.entities.enemies.*;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.net.Packets.*;
|
import io.anuke.mindustry.net.Packets.*;
|
||||||
import io.anuke.mindustry.net.Streamable.StreamBegin;
|
import io.anuke.mindustry.net.Streamable.StreamBegin;
|
||||||
import io.anuke.mindustry.net.Streamable.StreamChunk;
|
import io.anuke.mindustry.net.Streamable.StreamChunk;
|
||||||
@@ -50,17 +50,7 @@ public class Registrator {
|
|||||||
Player.class,
|
Player.class,
|
||||||
Mech.class,
|
Mech.class,
|
||||||
|
|
||||||
Enemy.class,
|
Enemy.class
|
||||||
FastEnemy.class,
|
|
||||||
RapidEnemy.class,
|
|
||||||
FlamerEnemy.class,
|
|
||||||
TankEnemy.class,
|
|
||||||
BlastEnemy.class,
|
|
||||||
MortarEnemy.class,
|
|
||||||
TestEnemy.class,
|
|
||||||
HealerEnemy.class,
|
|
||||||
TitanEnemy.class,
|
|
||||||
EmpEnemy.class
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,10 +117,6 @@ public class BlockLoader {
|
|||||||
//add any new block sections here
|
//add any new block sections here
|
||||||
};
|
};
|
||||||
|
|
||||||
for(Block block : Block.getAllBlocks()){
|
|
||||||
UCore.log("\""+block.name+"\"", block.id, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
for(String string : defaultMap.keys()){
|
for(String string : defaultMap.keys()){
|
||||||
Block block = Block.getByName(string);
|
Block block = Block.getByName(string);
|
||||||
blockmap.put(defaultMap.get(string, -1), block);
|
blockmap.put(defaultMap.get(string, -1), block);
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.graphics.Pixmap;
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
import com.badlogic.gdx.utils.IntMap;
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState;
|
import io.anuke.mindustry.core.GameState;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.enemies.TargetEnemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
|
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||||
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
import io.anuke.mindustry.world.ColorMapper.BlockPair;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.mindustry.world.blocks.SpecialBlocks;
|
import io.anuke.mindustry.world.blocks.SpecialBlocks;
|
||||||
@@ -77,7 +77,7 @@ public class Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(color == Hue.rgb(Color.PURPLE)){
|
if(color == Hue.rgb(Color.PURPLE)){
|
||||||
if(!Vars.android) new TargetEnemy().set(x * Vars.tilesize, y * Vars.tilesize).add();
|
if(!Vars.android) new Enemy(EnemyTypes.target).set(x * Vars.tilesize, y * Vars.tilesize).add();
|
||||||
floor = Blocks.stone;
|
floor = Blocks.stone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ public class Turret extends Block{
|
|||||||
if(entity.target != null){
|
if(entity.target != null){
|
||||||
|
|
||||||
float targetRot = Angles.predictAngle(tile.worldx(), tile.worldy(),
|
float targetRot = Angles.predictAngle(tile.worldx(), tile.worldy(),
|
||||||
entity.target.x, entity.target.y, entity.target.xvelocity, entity.target.yvelocity, bullet.speed);
|
entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, bullet.speed);
|
||||||
|
|
||||||
if(Float.isNaN(entity.rotation)){
|
if(Float.isNaN(entity.rotation)){
|
||||||
entity.rotation = 0;
|
entity.rotation = 0;
|
||||||
@@ -192,17 +192,17 @@ public class Turret extends Block{
|
|||||||
float hittime = dst / bullet.speed;
|
float hittime = dst / bullet.speed;
|
||||||
|
|
||||||
float angle = Angles.predictAngle(tile.worldx(), tile.worldy(),
|
float angle = Angles.predictAngle(tile.worldx(), tile.worldy(),
|
||||||
entity.target.x, entity.target.y, entity.target.xvelocity, entity.target.yvelocity, bullet.speed);
|
entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, bullet.speed);
|
||||||
|
|
||||||
float predictX = entity.target.x + entity.target.xvelocity * hittime,
|
float predictX = entity.target.x + entity.target.velocity.x * hittime,
|
||||||
predictY = entity.target.y + entity.target.yvelocity * hittime;
|
predictY = entity.target.y + entity.target.velocity.y * hittime;
|
||||||
|
|
||||||
Draw.color(Color.GREEN);
|
Draw.color(Color.GREEN);
|
||||||
Draw.line(tile.worldx(), tile.worldy(), entity.target.x, entity.target.y);
|
Draw.line(tile.worldx(), tile.worldy(), entity.target.x, entity.target.y);
|
||||||
|
|
||||||
Draw.color(Color.RED);
|
Draw.color(Color.RED);
|
||||||
Draw.line(tile.worldx(), tile.worldy(), entity.target.x + entity.target.xvelocity * hittime,
|
Draw.line(tile.worldx(), tile.worldy(), entity.target.x + entity.target.velocity.x * hittime,
|
||||||
entity.target.y + entity.target.yvelocity * hittime);
|
entity.target.y + entity.target.velocity.y * hittime);
|
||||||
|
|
||||||
Draw.color(Color.PURPLE);
|
Draw.color(Color.PURPLE);
|
||||||
Draw.thick(2f);
|
Draw.thick(2f);
|
||||||
|
|||||||