diff --git a/android/build.gradle b/android/build.gradle index 24ce776494..2c3912aeba 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.0' } } diff --git a/core/assets-raw/sprites/blocks/environment/craters1.png b/core/assets-raw/sprites/blocks/environment/craters1.png new file mode 100644 index 0000000000..b2aa5461bc Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/craters1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/craters2.png b/core/assets-raw/sprites/blocks/environment/craters2.png new file mode 100644 index 0000000000..6286436fd2 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/craters2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/craters3.png b/core/assets-raw/sprites/blocks/environment/craters3.png new file mode 100644 index 0000000000..4b1dc35be7 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/craters3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/rock1.png b/core/assets-raw/sprites/blocks/environment/rock1.png index 5af09f9483..d1e645a279 100644 Binary files a/core/assets-raw/sprites/blocks/environment/rock1.png and b/core/assets-raw/sprites/blocks/environment/rock1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/rock2.png b/core/assets-raw/sprites/blocks/environment/rock2.png index 1b1c8cf620..f696f51f77 100644 Binary files a/core/assets-raw/sprites/blocks/environment/rock2.png and b/core/assets-raw/sprites/blocks/environment/rock2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/rocks-medium1.png b/core/assets-raw/sprites/blocks/environment/rocks-medium1.png deleted file mode 100644 index 66025d7a45..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/rocks-medium1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/rocks-medium2.png b/core/assets-raw/sprites/blocks/environment/rocks-medium2.png deleted file mode 100644 index 8db32cb047..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/rocks-medium2.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/rocks-small1.png b/core/assets-raw/sprites/blocks/environment/rocks-small1.png deleted file mode 100644 index 7afb6018a5..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/rocks-small1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/rocks-small2.png b/core/assets-raw/sprites/blocks/environment/rocks-small2.png deleted file mode 100644 index dfff2c648b..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/rocks-small2.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/rocks-small3.png b/core/assets-raw/sprites/blocks/environment/rocks-small3.png deleted file mode 100644 index cdbc897501..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/rocks-small3.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/rocks1.png b/core/assets-raw/sprites/blocks/environment/rocks1.png new file mode 100644 index 0000000000..01d5f670b5 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/rocks1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/rocks2.png b/core/assets-raw/sprites/blocks/environment/rocks2.png new file mode 100644 index 0000000000..44c4928519 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/rocks2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/scrap1.png b/core/assets-raw/sprites/blocks/environment/scrap1.png new file mode 100644 index 0000000000..c509773e5b Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/scrap1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/scrap2.png b/core/assets-raw/sprites/blocks/environment/scrap2.png new file mode 100644 index 0000000000..567a887bf7 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/scrap2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/scrap3.png b/core/assets-raw/sprites/blocks/environment/scrap3.png new file mode 100644 index 0000000000..f491b722e8 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/scrap3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stone1.png b/core/assets-raw/sprites/blocks/environment/stone1.png index c6a2777a84..8664e25bbc 100644 Binary files a/core/assets-raw/sprites/blocks/environment/stone1.png and b/core/assets-raw/sprites/blocks/environment/stone1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stone2.png b/core/assets-raw/sprites/blocks/environment/stone2.png index 1f65657224..f938a042f5 100644 Binary files a/core/assets-raw/sprites/blocks/environment/stone2.png and b/core/assets-raw/sprites/blocks/environment/stone2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stone3.png b/core/assets-raw/sprites/blocks/environment/stone3.png index b3b7d0833f..ad8c8c1501 100644 Binary files a/core/assets-raw/sprites/blocks/environment/stone3.png and b/core/assets-raw/sprites/blocks/environment/stone3.png differ diff --git a/core/assets-raw/sprites/blocks/extra/block-border.png b/core/assets-raw/sprites/blocks/extra/block-border.png index 58c5afd372..84969075fb 100644 Binary files a/core/assets-raw/sprites/blocks/extra/block-border.png and b/core/assets-raw/sprites/blocks/extra/block-border.png differ diff --git a/core/assets-raw/sprites/blocks/extra/block-elevation.png b/core/assets-raw/sprites/blocks/extra/block-elevation.png deleted file mode 100644 index 6f47e65204..0000000000 Binary files a/core/assets-raw/sprites/blocks/extra/block-elevation.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/extra/block-slope.png b/core/assets-raw/sprites/blocks/extra/block-slope.png deleted file mode 100644 index c37587f765..0000000000 Binary files a/core/assets-raw/sprites/blocks/extra/block-slope.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/extra/border.png b/core/assets-raw/sprites/blocks/extra/border.png deleted file mode 100644 index 6d848e1b72..0000000000 Binary files a/core/assets-raw/sprites/blocks/extra/border.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/extra/cross-1.png b/core/assets-raw/sprites/blocks/extra/cross-1.png deleted file mode 100644 index 1c3aa8ae22..0000000000 Binary files a/core/assets-raw/sprites/blocks/extra/cross-1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/extra/cross-2.png b/core/assets-raw/sprites/blocks/extra/cross-2.png deleted file mode 100644 index 3aa3ceb32b..0000000000 Binary files a/core/assets-raw/sprites/blocks/extra/cross-2.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/extra/cross-3.png b/core/assets-raw/sprites/blocks/extra/cross-3.png deleted file mode 100644 index 9aacfbb93d..0000000000 Binary files a/core/assets-raw/sprites/blocks/extra/cross-3.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/extra/cross-4.png b/core/assets-raw/sprites/blocks/extra/cross-4.png deleted file mode 100644 index a1247aeafb..0000000000 Binary files a/core/assets-raw/sprites/blocks/extra/cross-4.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/extra/place-arrow.png b/core/assets-raw/sprites/blocks/extra/place-arrow.png index 84f4b22895..3e0ca09fa2 100644 Binary files a/core/assets-raw/sprites/blocks/extra/place-arrow.png and b/core/assets-raw/sprites/blocks/extra/place-arrow.png differ diff --git a/core/assets-raw/sprites/blocks/extra/ripples.png b/core/assets-raw/sprites/blocks/extra/ripples.png deleted file mode 100644 index d416708543..0000000000 Binary files a/core/assets-raw/sprites/blocks/extra/ripples.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/production/silicon-smelter.png b/core/assets-raw/sprites/blocks/production/silicon-smelter.png index cb4d3c93d3..8bfea1e265 100644 Binary files a/core/assets-raw/sprites/blocks/production/silicon-smelter.png and b/core/assets-raw/sprites/blocks/production/silicon-smelter.png differ diff --git a/core/assets-raw/sprites/blocks/units/fortress-factory.png b/core/assets-raw/sprites/blocks/units/fortress-factory.png index 716fd0a9cf..79572e2bdd 100644 Binary files a/core/assets-raw/sprites/blocks/units/fortress-factory.png and b/core/assets-raw/sprites/blocks/units/fortress-factory.png differ diff --git a/core/assets-raw/sprites/blocks/units/repair-point.png b/core/assets-raw/sprites/blocks/units/repair-point.png index 8357f55dd6..41c5134409 100644 Binary files a/core/assets-raw/sprites/blocks/units/repair-point.png and b/core/assets-raw/sprites/blocks/units/repair-point.png differ diff --git a/core/assets-raw/sprites/blocks/walls/deflector-wall-large.png b/core/assets-raw/sprites/blocks/walls/deflector-wall-large.png deleted file mode 100644 index abbce58e93..0000000000 Binary files a/core/assets-raw/sprites/blocks/walls/deflector-wall-large.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/walls/deflector-wall.png b/core/assets-raw/sprites/blocks/walls/deflector-wall.png deleted file mode 100644 index 4e234bd1d0..0000000000 Binary files a/core/assets-raw/sprites/blocks/walls/deflector-wall.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/walls/dense-alloy-wall-large.png b/core/assets-raw/sprites/blocks/walls/dense-alloy-wall-large.png deleted file mode 100644 index 3db17bbac3..0000000000 Binary files a/core/assets-raw/sprites/blocks/walls/dense-alloy-wall-large.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/walls/dense-alloy-wall.png b/core/assets-raw/sprites/blocks/walls/dense-alloy-wall.png deleted file mode 100644 index a725f20c37..0000000000 Binary files a/core/assets-raw/sprites/blocks/walls/dense-alloy-wall.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/walls/titanium-wall-large.png b/core/assets-raw/sprites/blocks/walls/titanium-wall-large.png new file mode 100644 index 0000000000..996af7f52d Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/titanium-wall-large.png differ diff --git a/core/assets-raw/sprites/blocks/walls/titanium-wall.png b/core/assets-raw/sprites/blocks/walls/titanium-wall.png new file mode 100644 index 0000000000..f778c11fdb Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/titanium-wall.png differ diff --git a/core/assets-raw/sprites/items/item-bioglass.png b/core/assets-raw/sprites/items/item-bioglass.png deleted file mode 100644 index bc8eeda9a5..0000000000 Binary files a/core/assets-raw/sprites/items/item-bioglass.png and /dev/null differ diff --git a/core/assets-raw/sprites/items/item-dense-alloy.png b/core/assets-raw/sprites/items/item-dense-alloy.png deleted file mode 100644 index 84831fe96c..0000000000 Binary files a/core/assets-raw/sprites/items/item-dense-alloy.png and /dev/null differ diff --git a/core/assets-raw/sprites/items/item-metaglass.png b/core/assets-raw/sprites/items/item-metaglass.png new file mode 100644 index 0000000000..538acab631 Binary files /dev/null and b/core/assets-raw/sprites/items/item-metaglass.png differ diff --git a/core/assets-raw/sprites/items/item-scrap.png b/core/assets-raw/sprites/items/item-scrap.png new file mode 100644 index 0000000000..a19374afad Binary files /dev/null and b/core/assets-raw/sprites/items/item-scrap.png differ diff --git a/core/assets-raw/sprites/items/liquid-slag.png b/core/assets-raw/sprites/items/liquid-slag.png index aea23bb0b3..af8efaf9ef 100644 Binary files a/core/assets-raw/sprites/items/liquid-slag.png and b/core/assets-raw/sprites/items/liquid-slag.png differ diff --git a/core/assets-raw/sprites/ui/bar-top.9.png b/core/assets-raw/sprites/ui/bar-top.9.png new file mode 100644 index 0000000000..e06822ecf0 Binary files /dev/null and b/core/assets-raw/sprites/ui/bar-top.9.png differ diff --git a/core/assets-raw/sprites/ui/bar.9.png b/core/assets-raw/sprites/ui/bar.9.png new file mode 100644 index 0000000000..1bf63c7bdf Binary files /dev/null and b/core/assets-raw/sprites/ui/bar.9.png differ diff --git a/core/assets-raw/sprites/ui/content-background-locked.9.png b/core/assets-raw/sprites/ui/content-background-locked.9.png new file mode 100644 index 0000000000..8b3ac94f48 Binary files /dev/null and b/core/assets-raw/sprites/ui/content-background-locked.9.png differ diff --git a/core/assets-raw/sprites/ui/content-background-over.9.png b/core/assets-raw/sprites/ui/content-background-over.9.png new file mode 100644 index 0000000000..8993b24afa Binary files /dev/null and b/core/assets-raw/sprites/ui/content-background-over.9.png differ diff --git a/core/assets-raw/sprites/ui/content-background.9.png b/core/assets-raw/sprites/ui/content-background.9.png new file mode 100644 index 0000000000..4f2012fce3 Binary files /dev/null and b/core/assets-raw/sprites/ui/content-background.9.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-cancel-2.png b/core/assets-raw/sprites/ui/icons/icon-cancel-2.png new file mode 100644 index 0000000000..c653c00af4 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-cancel-2.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-check-2.png b/core/assets-raw/sprites/ui/icons/icon-check-2.png new file mode 100644 index 0000000000..e123e30478 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-check-2.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-info.png b/core/assets-raw/sprites/ui/icons/icon-info.png index d3af92f26d..ac482f4194 100644 Binary files a/core/assets-raw/sprites/ui/icons/icon-info.png and b/core/assets-raw/sprites/ui/icons/icon-info.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-nullitem.png b/core/assets-raw/sprites/ui/icons/icon-nullitem.png deleted file mode 100644 index 1897820730..0000000000 Binary files a/core/assets-raw/sprites/ui/icons/icon-nullitem.png and /dev/null differ diff --git a/core/assets-raw/sprites/ui/icons/icon-spray.png b/core/assets-raw/sprites/ui/icons/icon-spray.png new file mode 100644 index 0000000000..9370d5751b Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-spray.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-tree-locked.png b/core/assets-raw/sprites/ui/icons/icon-tree-locked.png new file mode 100644 index 0000000000..d6a6462d1c Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-tree-locked.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-tree.png b/core/assets-raw/sprites/ui/icons/icon-tree.png new file mode 100644 index 0000000000..6e28a70c13 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-tree.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-zone-locked.png b/core/assets-raw/sprites/ui/icons/icon-zone-locked.png new file mode 100644 index 0000000000..207c41c463 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-zone-locked.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-zone.png b/core/assets-raw/sprites/ui/icons/icon-zone.png new file mode 100644 index 0000000000..af66d61ea6 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-zone.png differ diff --git a/core/assets-raw/sprites/ui/slider-knob-down.png b/core/assets-raw/sprites/ui/slider-knob-down.png index efb573acb3..1c44f1497d 100644 Binary files a/core/assets-raw/sprites/ui/slider-knob-down.png and b/core/assets-raw/sprites/ui/slider-knob-down.png differ diff --git a/core/assets-raw/sprites/ui/slider-knob-over.png b/core/assets-raw/sprites/ui/slider-knob-over.png index a8936dca95..f32d6c3975 100644 Binary files a/core/assets-raw/sprites/ui/slider-knob-over.png and b/core/assets-raw/sprites/ui/slider-knob-over.png differ diff --git a/core/assets-raw/sprites/ui/slider-knob.png b/core/assets-raw/sprites/ui/slider-knob.png index 700f69c594..b9059692ca 100644 Binary files a/core/assets-raw/sprites/ui/slider-knob.png and b/core/assets-raw/sprites/ui/slider-knob.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 13e3407d0d..05e2b4525b 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -14,10 +14,16 @@ screenshot = Screenshot saved to {0} gameover = Game Over gameover.pvp = The[accent] {0}[] team is victorious! highscore = [accent]New highscore! -wave.lasted = You lasted until wave [accent]{0}[]. -level.highscore = High Score: [accent]{0} -level.delete.title = Confirm Delete + +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: + map.delete = Are you sure you want to delete the map "[accent]{0}[]"? +level.highscore = High Score: [accent]{0} level.select = Level Select level.mode = Gamemode: construction.desktop = To deselect a block or stop building, [accent]use space[]. @@ -27,7 +33,7 @@ deconstruction.title = Block Deconstruction Guide deconstruction = You've just selected [accent]block deconstruction mode[].\n\nTo begin breaking, simply tap a block near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin de-constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Remove blocks in an area[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel deconstruction or selection[] by pressing the X at the bottom left. showagain = Don't show again next session coreattack = < Core is under attack! > -unlocks = Unlocks +database = Core Database savegame = Save Game loadgame = Load Game joingame = Join Game @@ -43,8 +49,12 @@ about.button = About name = Name: noname = Pick a[accent] player name[] first. filename = File Name: -unlocked = New Block Unlocked! -unlocked.plural = New Blocks Unlocked! +unlocked = New content unlocked! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} players online players.single = {0} player online server.closing = [accent]Closing server... @@ -138,6 +148,7 @@ save.wave = Wave {0} save.difficulty = Difficulty: {0} save.date = Last Saved: {0} save.playtime = Playtime: {0} +warning = Warning. confirm = Confirm delete = Delete ok = OK @@ -229,6 +240,16 @@ editor = Editor mapeditor = Map Editor donate = Donate +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +zone.unlocked = [LIGHT_GRAY]{0} unlocked. + connectfail = [crimson]Failed to connect to server:\n\n[accent]{0} error.unreachable = Server unreachable.\nIs the address spelled correctly? error.invalidaddress = Invalid address. @@ -239,7 +260,18 @@ error.mapnotfound = Map file not found! error.io = Network I/O error. error.any = Unknown network error. -zone.wasteland.name = Wasteland +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Language settings.reset = Reset to Defaults @@ -392,7 +424,7 @@ mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Items content.liquid.name = Liquids content.unit.name = Units -content.recipe.name = Blocks +content.block.name = Blocks content.mech.name = Mechs item.copper.name = Copper item.copper.description = A useful structure material. Used extensively in all types of blocks. @@ -421,8 +453,10 @@ item.blast-compound.name = Blast Compound item.blast-compound.description = A volatile compound used in bombs and explosives. While it can burned as fuel, this is not advised. item.pyratite.name = Pyratite item.pyratite.description = An extremely flammable substance used in incendiary weapons. -item.bioglass.name = Bioglass +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Water liquid.lava.name = Lava liquid.oil.name = Oil @@ -675,7 +709,7 @@ block.cyclone.description = A large rapid fire turret. block.fuse.description = A large turret which shoots powerful short-range beams. block.spectre.description = A large turret which shoots two powerful bullets at once. block.meltdown.description = A large turret which shoots powerful long-range beams. -block.conveyor.description = Basic item transport block. Moved items forward and automatically deposits them into turrets or crafters. Rotatable. +block.conveyor.description = Basic item transport block. Moves items forward and automatically deposits them into turrets or crafters. Rotatable. block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors. block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles. block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations. diff --git a/core/assets/maps/craters.mmap b/core/assets/maps/craters.mmap new file mode 100644 index 0000000000..b07cbda03e Binary files /dev/null and b/core/assets/maps/craters.mmap differ diff --git a/core/assets/maps/groundZero.mmap b/core/assets/maps/groundZero.mmap new file mode 100644 index 0000000000..ff8b5a9b56 Binary files /dev/null and b/core/assets/maps/groundZero.mmap differ diff --git a/core/assets/maps/sandbox.mmap b/core/assets/maps/sandbox.mmap deleted file mode 100644 index 14e89ed3b7..0000000000 Binary files a/core/assets/maps/sandbox.mmap and /dev/null differ diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 95564f474b..49843cb01e 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -4,1875 +4,2274 @@ size: 2048,2048 format: RGBA8888 filter: Nearest,Nearest repeat: none -force-projector-top +force-projector rotate: false - xy: 261, 753 + xy: 457, 1439 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 +force-projector-top + rotate: false + xy: 359, 1243 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +mend-projector + rotate: false + xy: 653, 1645 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 mend-projector-top rotate: false - xy: 851, 1719 + xy: 785, 1777 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +overdrive-projector + rotate: false + xy: 653, 1579 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 overdrive-projector-top rotate: false - xy: 917, 1785 + xy: 785, 1711 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 +shock-mine + rotate: false + xy: 915, 615 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 bridge-conveyor rotate: false - xy: 1043, 1396 + xy: 1858, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conveyor-bridge rotate: false - xy: 1053, 1362 + xy: 1157, 1211 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conveyor-end rotate: false - xy: 1049, 1561 + xy: 1191, 1211 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conveyor-0-0 + rotate: false + xy: 745, 621 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-0-1 rotate: false - xy: 1409, 1729 + xy: 707, 579 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-0-2 rotate: false - xy: 1443, 1767 + xy: 1041, 1215 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-0-3 rotate: false - xy: 1477, 1767 + xy: 1041, 1181 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-1-0 rotate: false - xy: 1443, 1733 + xy: 779, 291 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-1-1 rotate: false - xy: 1511, 1767 + xy: 779, 257 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-1-2 rotate: false - xy: 1477, 1733 + xy: 779, 223 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-1-3 rotate: false - xy: 1545, 1767 + xy: 779, 189 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-2-0 rotate: false - xy: 1511, 1733 + xy: 779, 155 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-2-1 rotate: false - xy: 1579, 1767 + xy: 779, 121 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-2-2 rotate: false - xy: 1545, 1733 + xy: 779, 87 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-2-3 rotate: false - xy: 1613, 1767 + xy: 779, 53 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-3-0 rotate: false - xy: 1579, 1733 + xy: 1225, 1245 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-3-1 rotate: false - xy: 1647, 1767 + xy: 1225, 1211 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-3-2 rotate: false - xy: 1613, 1733 + xy: 1259, 1257 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-3-3 rotate: false - xy: 1681, 1767 + xy: 1259, 1223 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-4-0 rotate: false - xy: 1647, 1733 + xy: 1293, 1257 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-4-1 rotate: false - xy: 1715, 1767 + xy: 1293, 1223 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-4-2 rotate: false - xy: 1681, 1733 + xy: 1327, 1257 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-4-3 rotate: false - xy: 1749, 1767 + xy: 1327, 1223 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium-conveyor-0-0 + rotate: false + xy: 1047, 946 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-0-1 rotate: false - xy: 1087, 1391 + xy: 1051, 912 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-0-2 rotate: false - xy: 1087, 1357 + xy: 1051, 878 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-0-3 rotate: false - xy: 1121, 1391 + xy: 1051, 844 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-1-0 rotate: false - xy: 1121, 1357 + xy: 1051, 810 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-1-1 rotate: false - xy: 687, 373 + xy: 1051, 776 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-1-2 rotate: false - xy: 687, 339 + xy: 1051, 742 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-1-3 rotate: false - xy: 721, 381 + xy: 1051, 708 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-2-0 rotate: false - xy: 721, 347 + xy: 1051, 674 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-2-1 rotate: false - xy: 755, 381 + xy: 1051, 640 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-2-2 rotate: false - xy: 789, 382 + xy: 1051, 606 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-2-3 rotate: false - xy: 823, 383 + xy: 1051, 572 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-3-0 rotate: false - xy: 755, 347 + xy: 1051, 538 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-3-1 rotate: false - xy: 789, 348 + xy: 1051, 504 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-3-2 rotate: false - xy: 823, 349 + xy: 813, 507 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-3-3 rotate: false - xy: 705, 305 + xy: 847, 507 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-4-0 rotate: false - xy: 705, 271 + xy: 881, 504 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-4-1 rotate: false - xy: 705, 237 + xy: 915, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-4-2 rotate: false - xy: 705, 203 + xy: 949, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-4-3 rotate: false - xy: 705, 169 + xy: 983, 479 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +distributor + rotate: false + xy: 858, 1843 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 junction rotate: false - xy: 263, 118 + xy: 1445, 1354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -mass-driver-turret - rotate: false - xy: 261, 459 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -phase-conveyor-arrow - rotate: false - xy: 1861, 1665 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-conveyor-bridge - rotate: false - xy: 1895, 1665 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-conveyor-end - rotate: false - xy: 1929, 1681 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -warp-gate - rotate: false - xy: 555, 1243 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -warp-gate-top - rotate: false - xy: 555, 1145 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -blast-drill - rotate: false - xy: 131, 50 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -blast-drill-rim - rotate: false - xy: 261, 1733 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -blast-drill-rotator - rotate: false - xy: 261, 1635 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -blast-drill-top - rotate: false - xy: 359, 1733 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -laser-drill - rotate: false - xy: 719, 1653 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -laser-drill-rotator - rotate: false - xy: 785, 1719 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -laser-drill-top - rotate: false - xy: 851, 1785 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -mechanical-drill - rotate: false - xy: 653, 1521 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -mechanical-drill-rotator - rotate: false - xy: 719, 1587 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -mechanical-drill-top - rotate: false - xy: 785, 1653 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -oil-extractor - rotate: false - xy: 359, 557 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -oil-extractor-liquid - rotate: false - xy: 457, 655 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -oil-extractor-rotator - rotate: false - xy: 359, 459 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -oil-extractor-top - rotate: false - xy: 457, 557 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -plasma-drill - rotate: false - xy: 131, 1368 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -plasma-drill-rim - rotate: false - xy: 131, 1238 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -plasma-drill-rotator - rotate: false - xy: 131, 1108 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -plasma-drill-top - rotate: false - xy: 131, 978 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -pneumatic-drill - rotate: false - xy: 653, 1389 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -pneumatic-drill-rotator - rotate: false - xy: 719, 1455 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -pneumatic-drill-top - rotate: false - xy: 785, 1521 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -water-extractor - rotate: false - xy: 1049, 1653 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -water-extractor-liquid - rotate: false - xy: 1115, 1719 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -water-extractor-rotator - rotate: false - xy: 1181, 1785 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -water-extractor-top - rotate: false - xy: 653, 1191 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -blackrock1 - rotate: false - xy: 279, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-blackrock - rotate: false - xy: 279, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone1 - rotate: false - xy: 279, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-blackstone - rotate: false - xy: 279, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone2 - rotate: false - xy: 313, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone3 - rotate: false - xy: 279, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstoneedge - rotate: false - xy: 1667, 1801 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -coal1 - rotate: false - xy: 1048, 1527 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -coal2 - rotate: false - xy: 1141, 1559 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -coal3 - rotate: false - xy: 1239, 1751 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -copper1 - rotate: false - xy: 1715, 1733 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -copper2 - rotate: false - xy: 1783, 1767 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -copper3 - rotate: false - xy: 1749, 1733 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirt2 - rotate: false - xy: 1885, 1733 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirt3 - rotate: false - xy: 1919, 1733 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirtedge - rotate: false - xy: 629, 891 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -generic-cliff-edge - rotate: false - xy: 1351, 1691 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ice-cliff-edge - rotate: false - xy: 1351, 1691 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -generic-cliff-edge-1 - rotate: false - xy: 1385, 1695 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ice-cliff-edge-1 - rotate: false - xy: 1385, 1695 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -generic-cliff-edge-2 - rotate: false - xy: 1419, 1695 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ice-cliff-edge-2 - rotate: false - xy: 1419, 1695 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -generic-cliff-side - rotate: false - xy: 1453, 1699 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ice-cliff-side - rotate: false - xy: 1453, 1699 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grass2 - rotate: false - xy: 1487, 1699 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grass3 - rotate: false - xy: 1521, 1699 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grassedge - rotate: false - xy: 629, 691 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ice2 - rotate: false - xy: 1725, 1699 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ice3 - rotate: false - xy: 1759, 1699 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -iceedge - rotate: false - xy: 621, 591 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -icerock2 - rotate: false - xy: 1793, 1699 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -lava - rotate: false - xy: 263, 84 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -lavaedge - rotate: false - xy: 679, 1091 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -lead1 - rotate: false - xy: 331, 323 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -lead2 - rotate: false - xy: 297, 289 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -lead3 - rotate: false - xy: 365, 323 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor2 - rotate: false - xy: 297, 187 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor3 - rotate: false - xy: 331, 221 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor4 - rotate: false - xy: 365, 255 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor5 - rotate: false - xy: 399, 289 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor6 - rotate: false - xy: 467, 323 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalflooredge - rotate: false - xy: 679, 891 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -rock2 - rotate: false - xy: 619, 339 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rocks-medium2 - rotate: false - xy: 653, 373 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rocks-small2 - rotate: false - xy: 653, 339 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rocks-small3 - rotate: false - xy: 637, 305 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sand2 - rotate: false - xy: 637, 237 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sand3 - rotate: false - xy: 637, 203 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sandedge - rotate: false - xy: 679, 841 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -snow2 - rotate: false - xy: 671, 67 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -snow3 - rotate: false - xy: 671, 33 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -snowedge - rotate: false - xy: 679, 741 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -spaceedge - rotate: false - xy: 679, 691 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -stone-cliff-edge - rotate: false - xy: 1861, 1631 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -stone-cliff-edge-1 - rotate: false - xy: 1895, 1631 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -stone-cliff-edge-2 - rotate: false - xy: 1929, 1613 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -stone-cliff-side - rotate: false - xy: 1963, 1613 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -stone2 - rotate: false - xy: 1793, 1631 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -stone3 - rotate: false - xy: 1827, 1631 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -stoneedge - rotate: false - xy: 671, 591 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -taredge - rotate: false - xy: 671, 491 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -thorium1 - rotate: false - xy: 1082, 1527 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -thorium2 - rotate: false - xy: 1109, 1493 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -thorium3 - rotate: false - xy: 1075, 1459 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -titanium1 - rotate: false - xy: 1109, 1459 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -titanium2 - rotate: false - xy: 1077, 1425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -titanium3 - rotate: false - xy: 1111, 1425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -water-cliff-edge - rotate: false - xy: 705, 101 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -water-cliff-edge-1 - rotate: false - xy: 705, 67 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -water-cliff-edge-2 - rotate: false - xy: 705, 33 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -water-cliff-side - rotate: false - xy: 739, 313 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -wateredge - rotate: false - xy: 729, 991 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -block-border - rotate: false - xy: 381, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-elevation - rotate: false - xy: 415, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-middle - rotate: false - xy: 2014, 1923 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -pump-liquid - rotate: false - xy: 2014, 1923 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-slope - rotate: false - xy: 2014, 1889 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -border - rotate: false - xy: 917, 1363 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-liquid - rotate: false - xy: 2014, 1855 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -cross-1 - rotate: false - xy: 1817, 1767 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -cross-2 - rotate: false - xy: 1320, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -cross-3 - rotate: false - xy: 359, 949 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -cross-4 - rotate: false - xy: 1, 978 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -place-arrow - rotate: false - xy: 1963, 1681 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ripples - rotate: false - xy: 729, 949 - size: 40, 40 - orig: 40, 40 - offset: 0, 0 - index: -1 -rubble-1-0 - rotate: false - xy: 983, 1719 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -rubble-1-1 - rotate: false - xy: 1049, 1785 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -rubble-2-0 - rotate: false - xy: 653, 1323 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -rubble-2-1 - rotate: false - xy: 719, 1389 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -rubble-3-0 - rotate: false - xy: 555, 1635 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -rubble-3-1 - rotate: false - xy: 555, 1635 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -bridge-conduit-arrow - rotate: false - xy: 951, 1362 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -bridge-conveyor-arrow - rotate: false - xy: 951, 1362 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -bridge-conduit-bridge - rotate: false - xy: 985, 1362 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -bridge-conduit-end - rotate: false - xy: 1019, 1362 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-bottom - rotate: false - xy: 877, 1229 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-bottom-0 - rotate: false - xy: 771, 923 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-bottom-1 - rotate: false - xy: 767, 889 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-bottom-2 - rotate: false - xy: 767, 855 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-bottom-3 - rotate: false - xy: 767, 821 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-bottom-4 - rotate: false - xy: 767, 787 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-bottom-5 - rotate: false - xy: 767, 753 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-bottom-6 - rotate: false - xy: 767, 719 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-top-0 - rotate: false - xy: 2001, 1821 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-top-1 - rotate: false - xy: 2001, 1787 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-top-2 - rotate: false - xy: 1273, 1725 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-top-3 - rotate: false - xy: 1307, 1725 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-top-4 - rotate: false - xy: 1341, 1725 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-top-5 - rotate: false - xy: 1375, 1729 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-top-6 - rotate: false - xy: 1409, 1763 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -liquid-router-bottom - rotate: false - xy: 399, 323 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -liquid-router-liquid - rotate: false - xy: 297, 221 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -liquid-router-top - rotate: false - xy: 331, 255 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -liquid-tank-bottom - rotate: false - xy: 261, 557 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -liquid-tank-liquid +mass-driver rotate: false xy: 359, 655 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -liquid-tank-top +mass-driver-turret rotate: false - xy: 457, 753 + xy: 457, 655 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -phase-conduit-arrow +overflow-gate rotate: false - xy: 1759, 1665 + xy: 1993, 1048 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -phase-conduit-bridge +phase-conveyor rotate: false - xy: 1793, 1665 + xy: 945, 1023 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -phase-conduit-end +phase-conveyor-arrow rotate: false - xy: 1827, 1665 + xy: 945, 989 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -pulse-conduit-top-0 +phase-conveyor-bridge rotate: false - xy: 1997, 1647 + xy: 945, 955 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -pulse-conduit-top-1 +phase-conveyor-end rotate: false - xy: 801, 889 + xy: 945, 921 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -pulse-conduit-top-2 +router rotate: false - xy: 801, 855 + xy: 881, 742 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -pulse-conduit-top-3 +sorter rotate: false - xy: 801, 821 + xy: 813, 575 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -pulse-conduit-top-4 +warp-gate rotate: false - xy: 801, 787 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -pulse-conduit-top-5 - rotate: false - xy: 801, 753 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -pulse-conduit-top-6 - rotate: false - xy: 801, 719 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -alpha-mech-pad - rotate: false - xy: 555, 569 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-alpha-mech-pad - rotate: false - xy: 555, 569 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -battery - rotate: false - xy: 245, 356 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-battery - rotate: false - xy: 245, 356 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -battery-large - rotate: false - xy: 131, 148 + xy: 539, 459 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -block-icon-battery-large +warp-gate-top rotate: false - xy: 131, 148 + xy: 539, 361 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -combustion-generator-top +blast-drill rotate: false - xy: 1273, 1759 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -fusion-reactor - rotate: false - xy: 1, 848 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -fusion-reactor-bottom - rotate: false - xy: 1, 718 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -fusion-reactor-light - rotate: false - xy: 1, 588 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -fusion-reactor-plasma-0 - rotate: false - xy: 1, 458 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -fusion-reactor-plasma-1 - rotate: false - xy: 1, 328 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -fusion-reactor-plasma-2 - rotate: false - xy: 1, 198 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -fusion-reactor-plasma-3 - rotate: false - xy: 1, 68 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -fusion-reactor-top - rotate: false - xy: 464, 1831 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -power-node - rotate: false - xy: 1997, 1681 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -power-node-large - rotate: false - xy: 851, 1587 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -powerinfinite - rotate: false - xy: 1929, 1647 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -powervoid - rotate: false - xy: 1963, 1647 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rtg-generator-top - rotate: false - xy: 637, 271 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -thorium-reactor-center - rotate: false - xy: 555, 1537 + xy: 261, 1635 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -thorium-reactor-lights - rotate: false - xy: 555, 1439 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -turbine-generator-top - rotate: false - xy: 851, 1455 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -alloy-smelter - rotate: false - xy: 131, 246 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-alloy-smelter - rotate: false - xy: 131, 246 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -alloy-smelter-top - rotate: false - xy: 555, 635 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -arc-smelter - rotate: false - xy: 555, 503 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -arc-smelter-top - rotate: false - xy: 668, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -silicon-smelter-top - rotate: false - xy: 668, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -biomattercompressor - rotate: false - xy: 734, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -biomattercompressor-frame0 - rotate: false - xy: 800, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -biomattercompressor-frame1 - rotate: false - xy: 866, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -biomattercompressor-frame2 - rotate: false - xy: 932, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -biomattercompressor-liquid - rotate: false - xy: 998, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -biomattercompressor-top - rotate: false - xy: 1064, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -blast-mixer - rotate: false - xy: 1130, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-blast-mixer - rotate: false - xy: 1130, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -centrifuge - rotate: false - xy: 1122, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -centrifuge-liquid - rotate: false - xy: 1188, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -cryofluidmixer-bottom - rotate: false - xy: 1386, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -cryofluidmixer-liquid - rotate: false - xy: 1452, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -cryofluidmixer-top - rotate: false - xy: 1518, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -cultivator - rotate: false - xy: 1584, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -cultivator-middle - rotate: false - xy: 1650, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -cultivator-top - rotate: false - xy: 1716, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -lavasmelter - rotate: false - xy: 297, 323 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -oilrefinery - rotate: false - xy: 433, 289 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-weaver - rotate: false - xy: 785, 1587 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -phase-weaver-bottom - rotate: false - xy: 851, 1653 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -phase-weaver-weave - rotate: false - xy: 917, 1719 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -plastanium-compressor-top - rotate: false - xy: 983, 1785 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -pulverizer - rotate: false - xy: 621, 407 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -pulverizer-rotator - rotate: false - xy: 655, 407 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -separator-liquid - rotate: false - xy: 671, 169 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -smelter - rotate: false - xy: 671, 101 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -solidifer - rotate: false - xy: 1589, 1631 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -core-open - rotate: false - xy: 457, 1145 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -core-top - rotate: false - xy: 261, 851 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -sortedunloader - rotate: false - xy: 1623, 1631 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-1 - rotate: false - xy: 381, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-1-top - rotate: false - xy: 347, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-2 - rotate: false - xy: 1196, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-2-top - rotate: false - xy: 1262, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-3 +blast-drill-rim rotate: false xy: 261, 1537 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -block-3-top +blast-drill-rotator rotate: false xy: 359, 1635 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 +blast-drill-top + rotate: false + xy: 457, 1733 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +laser-drill + rotate: false + xy: 1716, 1851 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +laser-drill-rotator + rotate: false + xy: 1848, 1851 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +laser-drill-top + rotate: false + xy: 1914, 1851 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +mechanical-drill + rotate: false + xy: 1980, 1851 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +mechanical-drill-rotator + rotate: false + xy: 653, 1711 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +mechanical-drill-top + rotate: false + xy: 719, 1777 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +oil-extractor + rotate: false + xy: 261, 557 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +oil-extractor-liquid + rotate: false + xy: 457, 557 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +oil-extractor-rotator + rotate: false + xy: 245, 459 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +oil-extractor-top + rotate: false + xy: 245, 361 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +plasma-drill + rotate: false + xy: 1, 68 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +plasma-drill-rim + rotate: false + xy: 131, 1628 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +plasma-drill-rotator + rotate: false + xy: 131, 1498 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +plasma-drill-top + rotate: false + xy: 131, 1368 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +pneumatic-drill + rotate: false + xy: 653, 1381 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +pneumatic-drill-rotator + rotate: false + xy: 785, 1513 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +pneumatic-drill-top + rotate: false + xy: 851, 1579 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +water-extractor + rotate: false + xy: 917, 1249 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +water-extractor-liquid + rotate: false + xy: 1049, 1381 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +water-extractor-rotator + rotate: false + xy: 1115, 1447 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +water-extractor-top + rotate: false + xy: 653, 919 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +blackrock1 + rotate: false + xy: 1620, 1388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blackstone1 + rotate: false + xy: 1688, 1388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blackstone2 + rotate: false + xy: 1722, 1388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blackstone3 + rotate: false + xy: 1173, 1313 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blackstoneedge + rotate: false + xy: 329, 311 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +coal1 + rotate: false + xy: 1241, 1291 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +coal2 + rotate: false + xy: 1275, 1291 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +coal3 + rotate: false + xy: 1309, 1291 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +copper1 + rotate: false + xy: 1293, 1189 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +copper2 + rotate: false + xy: 1327, 1189 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +copper3 + rotate: false + xy: 785, 959 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +craters1 + rotate: false + xy: 1892, 1379 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +craters2 + rotate: false + xy: 1926, 1379 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +craters3 + rotate: false + xy: 1960, 1379 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +deepwater + rotate: false + xy: 307, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +deepwater-icon-full + rotate: false + xy: 307, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +deepwater-icon-medium + rotate: false + xy: 307, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +dirt1 + rotate: false + xy: 375, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +dirt2 + rotate: false + xy: 409, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +dirt3 + rotate: false + xy: 443, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +dirtedge + rotate: false + xy: 579, 161 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +generic-cliff-edge + rotate: false + xy: 328, 9 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +generic-cliff-edge-1 + rotate: false + xy: 362, 9 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +generic-cliff-edge-2 + rotate: false + xy: 396, 9 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +generic-cliff-side + rotate: false + xy: 430, 9 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +grass1 + rotate: false + xy: 532, 9 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +grass2 + rotate: false + xy: 566, 9 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +grass3 + rotate: false + xy: 600, 41 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +grassedge + rotate: false + xy: 679, 275 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ice1 + rotate: false + xy: 736, 41 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice2 + rotate: false + xy: 600, 7 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice3 + rotate: false + xy: 634, 7 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +iceedge + rotate: false + xy: 629, 125 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +icerock1 + rotate: false + xy: 702, 7 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +icerock2 + rotate: false + xy: 736, 7 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lava + rotate: false + xy: 1513, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lavaedge + rotate: false + xy: 1388, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +lead1 + rotate: false + xy: 1547, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lead2 + rotate: false + xy: 1581, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lead3 + rotate: false + xy: 1581, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalfloor1 + rotate: false + xy: 1955, 1277 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalfloor2 + rotate: false + xy: 1989, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalfloor3 + rotate: false + xy: 1989, 1252 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalfloor4 + rotate: false + xy: 1361, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalfloor5 + rotate: false + xy: 1361, 1252 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalfloor6 + rotate: false + xy: 1361, 1218 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalflooredge + rotate: false + xy: 1181, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rock1 + rotate: false + xy: 1531, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rock2 + rotate: false + xy: 1581, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rocks1 + rotate: false + xy: 881, 878 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rocks2 + rotate: false + xy: 881, 844 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand1 + rotate: false + xy: 915, 887 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand2 + rotate: false + xy: 915, 853 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand3 + rotate: false + xy: 949, 887 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sandedge + rotate: false + xy: 1681, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +scrap1 + rotate: false + xy: 915, 751 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap2 + rotate: false + xy: 949, 785 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap3 + rotate: false + xy: 915, 717 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +shrub + rotate: false + xy: 983, 887 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snow1 + rotate: false + xy: 983, 785 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snow2 + rotate: false + xy: 983, 751 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snow3 + rotate: false + xy: 983, 717 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snowedge + rotate: false + xy: 1681, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +space + rotate: false + xy: 881, 572 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +space-icon-full + rotate: false + xy: 881, 572 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +space-icon-medium + rotate: false + xy: 881, 572 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +spaceedge + rotate: false + xy: 1631, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stone-cliff-edge + rotate: false + xy: 1013, 1082 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stone-cliff-edge-1 + rotate: false + xy: 1017, 912 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stone-cliff-edge-2 + rotate: false + xy: 1017, 878 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stone-cliff-side + rotate: false + xy: 1017, 844 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stone1 + rotate: false + xy: 1013, 1014 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stone2 + rotate: false + xy: 1013, 980 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stone3 + rotate: false + xy: 1013, 946 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stoneedge + rotate: false + xy: 1931, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +tar + rotate: false + xy: 1017, 640 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +tar-icon-full + rotate: false + xy: 1017, 640 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +tar-icon-medium + rotate: false + xy: 1017, 640 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +taredge + rotate: false + xy: 1931, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +thorium1 + rotate: false + xy: 813, 541 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thorium2 + rotate: false + xy: 847, 541 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thorium3 + rotate: false + xy: 881, 538 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium1 + rotate: false + xy: 1047, 1048 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium2 + rotate: false + xy: 1047, 1014 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium3 + rotate: false + xy: 1047, 980 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +water + rotate: false + xy: 821, 371 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +water-icon-full + rotate: false + xy: 821, 371 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +water-icon-medium + rotate: false + xy: 821, 371 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +water-cliff-edge + rotate: false + xy: 821, 337 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +water-cliff-edge-1 + rotate: false + xy: 813, 303 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +water-cliff-edge-2 + rotate: false + xy: 813, 269 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +water-cliff-side + rotate: false + xy: 813, 235 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +wateredge + rotate: false + xy: 1981, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +block-border + rotate: false + xy: 1241, 1325 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +block-middle + rotate: false + xy: 1275, 1325 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pump-liquid + rotate: false + xy: 1275, 1325 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-liquid + rotate: false + xy: 745, 893 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +place-arrow + rotate: false + xy: 441, 459 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +rubble-1-0 + rotate: false + xy: 1115, 1777 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +rubble-1-1 + rotate: false + xy: 653, 1249 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +rubble-2-0 + rotate: false + xy: 719, 1315 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +rubble-2-1 + rotate: false + xy: 785, 1381 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +rubble-3-0 + rotate: false + xy: 555, 1537 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +rubble-3-1 + rotate: false + xy: 555, 1537 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +spawn + rotate: false + xy: 915, 547 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conduit + rotate: false + xy: 1299, 1359 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conduit-arrow + rotate: false + xy: 1309, 1325 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conveyor-arrow + rotate: false + xy: 1309, 1325 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conduit-bridge + rotate: false + xy: 1756, 1379 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conduit-end + rotate: false + xy: 1790, 1379 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-bottom + rotate: false + xy: 951, 1091 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-bottom-0 + rotate: false + xy: 711, 885 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-bottom-1 + rotate: false + xy: 711, 851 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-bottom-2 + rotate: false + xy: 711, 817 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-bottom-3 + rotate: false + xy: 711, 783 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-bottom-4 + rotate: false + xy: 711, 749 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-bottom-5 + rotate: false + xy: 711, 715 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-bottom-6 + rotate: false + xy: 711, 681 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-top-0 + rotate: false + xy: 745, 859 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-top-1 + rotate: false + xy: 745, 825 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-top-2 + rotate: false + xy: 745, 791 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-top-3 + rotate: false + xy: 745, 757 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-top-4 + rotate: false + xy: 745, 723 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-top-5 + rotate: false + xy: 745, 689 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-top-6 + rotate: false + xy: 745, 655 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +liquid-junction + rotate: false + xy: 1615, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +liquid-router-bottom + rotate: false + xy: 1683, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +liquid-router-liquid + rotate: false + xy: 1717, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +liquid-router-top + rotate: false + xy: 1717, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +liquid-tank-bottom + rotate: false + xy: 457, 949 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +liquid-tank-liquid + rotate: false + xy: 359, 753 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +liquid-tank-top + rotate: false + xy: 457, 851 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +mechanical-pump + rotate: false + xy: 1887, 1311 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +phase-conduit + rotate: false + xy: 911, 1014 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +phase-conduit-arrow + rotate: false + xy: 911, 980 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +phase-conduit-bridge + rotate: false + xy: 911, 946 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +phase-conduit-end + rotate: false + xy: 911, 1048 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-top-0 + rotate: false + xy: 813, 779 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-top-1 + rotate: false + xy: 813, 745 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-top-2 + rotate: false + xy: 813, 711 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-top-3 + rotate: false + xy: 813, 677 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-top-4 + rotate: false + xy: 813, 643 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-top-5 + rotate: false + xy: 813, 609 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-top-6 + rotate: false + xy: 779, 925 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rotary-pump + rotate: false + xy: 851, 1513 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +thermal-pump + rotate: false + xy: 983, 1447 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +alpha-mech-pad + rotate: false + xy: 1252, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +dart-ship-pad + rotate: false + xy: 1980, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +delta-mech-pad + rotate: false + xy: 726, 1843 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +glaive-ship-pad + rotate: false + xy: 359, 949 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +javelin-ship-pad + rotate: false + xy: 1386, 1851 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +omega-mech-pad + rotate: false + xy: 343, 459 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +tau-mech-pad + rotate: false + xy: 719, 1183 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +trident-ship-pad + rotate: false + xy: 983, 1381 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +battery + rotate: false + xy: 1484, 1388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +battery-large + rotate: false + xy: 131, 66 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +combustion-generator + rotate: false + xy: 1995, 1388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +combustion-generator-top + rotate: false + xy: 843, 1017 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +fusion-reactor + rotate: false + xy: 1, 1498 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +fusion-reactor-bottom + rotate: false + xy: 334, 1831 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +fusion-reactor-light + rotate: false + xy: 1, 1238 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +fusion-reactor-plasma-0 + rotate: false + xy: 1, 1108 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +fusion-reactor-plasma-1 + rotate: false + xy: 1, 978 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +fusion-reactor-plasma-2 + rotate: false + xy: 1, 848 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +fusion-reactor-plasma-3 + rotate: false + xy: 1, 718 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +fusion-reactor-top + rotate: false + xy: 1, 588 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +power-node + rotate: false + xy: 779, 785 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-node-large + rotate: false + xy: 917, 1645 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +power-source + rotate: false + xy: 779, 683 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-void + rotate: false + xy: 779, 615 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +powerinfinite + rotate: false + xy: 813, 881 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +powervoid + rotate: false + xy: 813, 847 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rtg-generator + rotate: false + xy: 983, 1645 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +rtg-generator-top + rotate: false + xy: 881, 640 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +solar-panel + rotate: false + xy: 983, 649 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +solar-panel-large + rotate: false + xy: 555, 1439 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +thermal-generator + rotate: false + xy: 851, 1315 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +thorium-reactor + rotate: false + xy: 555, 1243 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +thorium-reactor-center + rotate: false + xy: 555, 1145 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +thorium-reactor-lights + rotate: false + xy: 555, 949 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +turbine-generator + rotate: false + xy: 1115, 1513 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +turbine-generator-top + rotate: false + xy: 719, 1051 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +alloy-smelter + rotate: false + xy: 131, 262 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +alloy-smelter-top + rotate: false + xy: 1186, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +arc-smelter + rotate: false + xy: 1384, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +arc-smelter-top + rotate: false + xy: 1450, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +silicon-smelter-top + rotate: false + xy: 1450, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +biomattercompressor + rotate: false + xy: 1516, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +biomattercompressor-frame0 + rotate: false + xy: 1582, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +biomattercompressor-frame1 + rotate: false + xy: 1648, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +biomattercompressor-frame2 + rotate: false + xy: 1714, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +biomattercompressor-liquid + rotate: false + xy: 1846, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +biomattercompressor-top + rotate: false + xy: 1912, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +blast-mixer + rotate: false + xy: 1978, 1983 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +centrifuge + rotate: false + xy: 726, 1909 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +centrifuge-liquid + rotate: false + xy: 792, 1909 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +cryofluidmixer-bottom + rotate: false + xy: 1188, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +cryofluidmixer-liquid + rotate: false + xy: 1320, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +cryofluidmixer-top + rotate: false + xy: 1386, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +cultivator + rotate: false + xy: 1452, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +cultivator-middle + rotate: false + xy: 1584, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +cultivator-top + rotate: false + xy: 1650, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +incinerator + rotate: false + xy: 1075, 1197 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +item-source + rotate: false + xy: 1279, 1121 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +item-void + rotate: false + xy: 1377, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lavasmelter + rotate: false + xy: 1547, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +liquid-source + rotate: false + xy: 1785, 1345 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +melter + rotate: false + xy: 1853, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +oilrefinery + rotate: false + xy: 1395, 1218 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +phase-weaver + rotate: false + xy: 917, 1777 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +phase-weaver-bottom + rotate: false + xy: 653, 1447 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +phase-weaver-weave + rotate: false + xy: 785, 1579 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +plastanium-compressor + rotate: false + xy: 851, 1645 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +plastanium-compressor-top + rotate: false + xy: 983, 1777 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +pulverizer + rotate: false + xy: 847, 915 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulverizer-rotator + rotate: false + xy: 847, 847 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pyratite-mixer + rotate: false + xy: 1049, 1777 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +separator + rotate: false + xy: 949, 717 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +separator-liquid + rotate: false + xy: 949, 683 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +silicon-smelter + rotate: false + xy: 653, 1183 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +smelter + rotate: false + xy: 983, 819 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +solidifer + rotate: false + xy: 949, 581 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +container + rotate: false + xy: 924, 1909 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +core + rotate: false + xy: 457, 1635 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +core-open + rotate: false + xy: 359, 1439 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +core-top + rotate: false + xy: 457, 1537 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +launch-pad + rotate: false + xy: 261, 753 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +sortedunloader + rotate: false + xy: 983, 581 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +unloader + rotate: false + xy: 787, 371 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +vault + rotate: false + xy: 555, 655 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +block-1 + rotate: false + xy: 1199, 1279 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +block-1-top + rotate: false + xy: 1191, 1245 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +block-2 + rotate: false + xy: 594, 1870 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +block-2-top + rotate: false + xy: 660, 1909 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +block-3 + rotate: false + xy: 261, 1439 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +block-3-top + rotate: false + xy: 359, 1537 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 block-4 rotate: false xy: 1, 1628 @@ -1889,84 +2288,84 @@ block-4-top index: -1 arc rotate: false - xy: 245, 424 + xy: 1382, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 arc-heat rotate: false - xy: 245, 390 + xy: 1416, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 cyclone rotate: false - xy: 457, 1047 + xy: 261, 1243 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 duo rotate: false - xy: 1283, 1691 + xy: 362, 43 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fuse rotate: false - xy: 359, 753 + xy: 261, 949 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 hail rotate: false - xy: 1691, 1699 + xy: 668, 41 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 hail-heat rotate: false - xy: 87, 26 + xy: 1223, 1359 size: 40, 40 orig: 40, 40 offset: 0, 0 index: -1 lancer rotate: false - xy: 785, 1785 + xy: 1518, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 lancer-heat rotate: false - xy: 653, 1587 + xy: 1584, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 meltdown rotate: false - xy: 131, 1628 + xy: 1, 458 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 meltdown-heat rotate: false - xy: 131, 1498 + xy: 1, 328 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 ripple rotate: false - xy: 457, 459 + xy: 441, 361 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -1980,294 +2379,392 @@ ripple-heat index: -1 salvo rotate: false - xy: 785, 1455 + xy: 851, 1447 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 salvo-heat rotate: false - xy: 851, 1521 + xy: 917, 1513 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 salvo-panel-left rotate: false - xy: 917, 1587 + xy: 1049, 1645 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 salvo-panel-right rotate: false - xy: 983, 1653 + xy: 1115, 1711 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 scatter rotate: false - xy: 637, 33 + xy: 949, 853 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 scorch rotate: false - xy: 671, 305 + xy: 915, 785 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 scorch-shoot rotate: false - xy: 671, 271 + xy: 949, 819 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 spectre rotate: false - xy: 131, 458 + xy: 131, 718 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 swarmer rotate: false - xy: 653, 1257 + xy: 1115, 1645 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wave rotate: false - xy: 719, 1257 + xy: 719, 985 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wave-liquid rotate: false - xy: 785, 1323 + xy: 851, 1117 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 command-center rotate: false - xy: 1254, 1851 + xy: 858, 1909 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +dagger-factory + rotate: false + xy: 1716, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +phantom-factory + rotate: false + xy: 1716, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +reconstructor + rotate: false + xy: 1716, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +spirit-factory + rotate: false + xy: 1716, 1917 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +wraith-factory + rotate: false + xy: 1716, 1917 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 dagger-factory-top rotate: false - xy: 1782, 1851 + xy: 1848, 1917 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 dagger-factory-top-open rotate: false - xy: 1848, 1851 + xy: 1914, 1917 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 fortress-factory rotate: false - xy: 359, 851 + xy: 457, 1341 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 fortress-factory-top rotate: false - xy: 457, 949 + xy: 359, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory-top rotate: false - xy: 457, 949 + xy: 359, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 titan-factory-top rotate: false - xy: 457, 949 + xy: 359, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 fortress-factory-top-open rotate: false - xy: 261, 655 + xy: 457, 1243 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory-top-open rotate: false - xy: 261, 655 + xy: 457, 1243 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 titan-factory-top-open rotate: false - xy: 261, 655 + xy: 457, 1243 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory rotate: false - xy: 457, 851 + xy: 457, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 phantom-factory-top rotate: false - xy: 653, 1455 + xy: 653, 1513 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 phantom-factory-top-open rotate: false - xy: 719, 1521 + xy: 719, 1579 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 reconstructor-open rotate: false - xy: 917, 1653 + xy: 785, 1447 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 +repair-point + rotate: false + xy: 847, 745 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 repair-point-turret rotate: false - xy: 619, 373 + xy: 847, 677 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 revenant-factory rotate: false - xy: 131, 848 + xy: 131, 1238 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 revenant-factory-top rotate: false - xy: 131, 718 + xy: 131, 978 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 revenant-factory-top-open rotate: false - xy: 131, 588 + xy: 131, 848 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 spirit-factory-top rotate: false - xy: 1049, 1719 + xy: 851, 1381 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 spirit-factory-top-open rotate: false - xy: 1115, 1785 + xy: 917, 1447 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 titan-factory rotate: false - xy: 555, 1341 + xy: 555, 851 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 wraith-factory-top rotate: false - xy: 851, 1389 + xy: 983, 1249 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wraith-factory-top-open rotate: false - xy: 917, 1455 + xy: 1049, 1315 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -deflector-wall +copper-wall rotate: false - xy: 1851, 1733 + xy: 877, 957 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -deflector-wall-large +copper-wall-large rotate: false - xy: 1914, 1851 + xy: 1056, 1909 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -dense-alloy-wall +door rotate: false - xy: 1919, 1767 + xy: 545, 77 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -dense-alloy-wall-large +door-large rotate: false - xy: 653, 1785 + xy: 990, 1843 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 door-large-open rotate: false - xy: 653, 1719 + xy: 1122, 1843 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 door-open rotate: false - xy: 1249, 1691 + xy: 328, 43 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +phase-wall + rotate: false + xy: 979, 1023 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +phase-wall-large + rotate: false + xy: 785, 1645 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +surge-wall + rotate: false + xy: 1017, 776 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +surge-wall-large + rotate: false + xy: 983, 1513 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +thorium-wall + rotate: false + xy: 949, 513 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thorium-wall-large + rotate: false + xy: 1115, 1579 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +titanium-wall + rotate: false + xy: 1051, 470 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium-wall-large + rotate: false + xy: 851, 1249 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 beam rotate: false - xy: 1173, 1669 + xy: 2038, 1801 size: 4, 48 orig: 4, 48 offset: 0, 0 index: -1 beam-end rotate: false - xy: 555, 1071 + xy: 668, 1975 size: 72, 72 orig: 72, 72 offset: 0, 0 @@ -2281,2842 +2778,5817 @@ bullet index: -1 bullet-back rotate: false - xy: 1363, 1797 + xy: 653, 575 size: 52, 52 orig: 52, 52 offset: 0, 0 index: -1 casing rotate: false - xy: 2039, 1727 + xy: 1133, 1145 size: 8, 16 orig: 8, 16 offset: 0, 0 index: -1 command-attack rotate: false - xy: 1307, 1759 + xy: 843, 983 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 command-idle rotate: false - xy: 1341, 1759 + xy: 877, 1025 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 command-patrol rotate: false - xy: 1375, 1763 + xy: 877, 991 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 command-retreat rotate: false - xy: 785, 1231 + xy: 917, 1091 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 enemyarrow rotate: false - xy: 767, 689 + xy: 464, 47 size: 32, 28 orig: 32, 28 offset: 0, 0 index: -1 error rotate: false - xy: 629, 841 + xy: 703, 525 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 laser rotate: false - xy: 909, 1339 + xy: 1155, 679 size: 4, 48 orig: 4, 48 offset: 0, 0 index: -1 laser-end rotate: false - xy: 555, 923 + xy: 816, 1975 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 laserfull rotate: false - xy: 555, 849 + xy: 890, 1975 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 minelaser rotate: false - xy: 777, 1207 + xy: 2043, 1218 size: 4, 48 orig: 4, 48 offset: 0, 0 index: -1 minelaser-end rotate: false - xy: 555, 775 + xy: 964, 1975 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 missile rotate: false - xy: 721, 650 + xy: 1767, 1413 size: 36, 36 orig: 36, 36 offset: 0, 0 index: -1 missile-back rotate: false - xy: 721, 612 + xy: 1805, 1413 size: 36, 36 orig: 36, 36 offset: 0, 0 index: -1 scale_marker rotate: false - xy: 654, 1864 + xy: 1101, 1251 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 scorch1 rotate: false - xy: 770, 211 + xy: 1081, 993 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 scorch2 rotate: false - xy: 769, 91 + xy: 1111, 1027 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 scorch3 rotate: false - xy: 1175, 1559 + xy: 1141, 1041 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 scorch4 rotate: false - xy: 1205, 1559 + xy: 1171, 1041 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 scorch5 rotate: false - xy: 1235, 1559 + xy: 1201, 1041 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 shell rotate: false - xy: 721, 545 + xy: 1919, 1413 size: 36, 36 orig: 36, 36 offset: 0, 0 index: -1 shell-back rotate: false - xy: 721, 507 + xy: 1957, 1413 size: 36, 36 orig: 36, 36 offset: 0, 0 index: -1 shot rotate: false - xy: 671, 135 + xy: 949, 615 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 transfer rotate: false - xy: 799, 143 + xy: 1231, 1081 size: 4, 48 orig: 4, 48 offset: 0, 0 index: -1 transfer-arrow rotate: false - xy: 705, 135 + xy: 787, 439 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 transfer-end rotate: false - xy: 555, 701 + xy: 1038, 1975 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 -blackstone-cliff-edge +alloy-smelter-icon-full rotate: false - xy: 313, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone-cliff-edge-1 - rotate: false - xy: 347, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone-cliff-edge-2 - rotate: false - xy: 313, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone-cliff-side - rotate: false - xy: 347, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-arc - rotate: false - xy: 381, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-biomattercompressor - rotate: false - xy: 1328, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-blast-drill - rotate: false - xy: 457, 1733 + xy: 131, 164 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -block-icon-bridge-conduit +alloy-smelter-icon-large rotate: false - xy: 415, 391 + xy: 210, 16 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +alloy-smelter-icon-medium + rotate: false + xy: 1265, 1359 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -bridge-conduit +alloy-smelter-icon-small rotate: false - xy: 415, 391 - size: 32, 32 - orig: 32, 32 + xy: 1075, 1231 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 -block-icon-bridge-conveyor +alpha-mech-pad-icon-full rotate: false - xy: 449, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-combustion-generator - rotate: false - xy: 415, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -combustion-generator - rotate: false - xy: 415, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-conduit - rotate: false - xy: 449, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-container - rotate: false - xy: 1394, 1983 + xy: 1318, 1983 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -container +alpha-mech-pad-icon-large rotate: false - xy: 1394, 1983 - size: 64, 64 - orig: 64, 64 + xy: 1115, 1281 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -block-icon-conveyor +alpha-mech-pad-icon-medium rotate: false - xy: 483, 425 + xy: 1348, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -conveyor-0-0 +alpha-mech-pad-icon-small rotate: false - xy: 483, 425 + xy: 2023, 1294 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +arc-icon-full + rotate: false + xy: 1450, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -block-icon-copper-wall +arc-icon-medium rotate: false - xy: 449, 357 + xy: 1450, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -copper-wall - rotate: false - xy: 449, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-copper-wall-large - rotate: false - xy: 1460, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -copper-wall-large - rotate: false - xy: 1460, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-core - rotate: false - xy: 261, 1439 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -core - rotate: false - xy: 261, 1439 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-cryofluidmixer - rotate: false - xy: 1526, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-cultivator - rotate: false - xy: 1592, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-cyclone - rotate: false - xy: 359, 1537 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-dagger-factory - rotate: false - xy: 1658, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-dart-ship-pad - rotate: false - xy: 1724, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -dart-ship-pad - rotate: false - xy: 1724, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-deepwater - rotate: false - xy: 483, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -deepwater - rotate: false - xy: 483, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-delta-mech-pad - rotate: false - xy: 1790, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -delta-mech-pad - rotate: false - xy: 1790, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-dirt - rotate: false - xy: 517, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirt1 - rotate: false - xy: 517, 425 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-distributor - rotate: false - xy: 1856, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -distributor - rotate: false - xy: 1856, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-door - rotate: false - xy: 483, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -door - rotate: false - xy: 483, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-door-large - rotate: false - xy: 1922, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -door-large - rotate: false - xy: 1922, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-duo - rotate: false - xy: 517, 391 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-force-projector - rotate: false - xy: 457, 1635 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -force-projector - rotate: false - xy: 457, 1635 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-fortress-factory - rotate: false - xy: 261, 1341 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-fuse - rotate: false - xy: 359, 1439 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-fusion-reactor - rotate: false - xy: 1, 1498 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -block-icon-ghoul-factory - rotate: false - xy: 457, 1537 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-glaive-ship-pad - rotate: false - xy: 261, 1243 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -glaive-ship-pad - rotate: false - xy: 261, 1243 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-grass - rotate: false - xy: 517, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grass1 - rotate: false - xy: 517, 357 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-hail - rotate: false - xy: 551, 403 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-ice - rotate: false - xy: 551, 369 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ice1 - rotate: false - xy: 551, 369 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-icerock - rotate: false - xy: 585, 403 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -icerock1 - rotate: false - xy: 585, 403 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-incinerator - rotate: false - xy: 585, 369 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -incinerator - rotate: false - xy: 585, 369 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-item-source - rotate: false - xy: 753, 1165 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -item-source - rotate: false - xy: 753, 1165 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-item-void +arc-icon-large rotate: false xy: 229, 310 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +arc-icon-small + rotate: false + xy: 2023, 1268 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +battery-icon-full + rotate: false + xy: 1518, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -item-void +battery-icon-medium rotate: false - xy: 229, 310 + xy: 1518, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -block-icon-javelin-ship-pad +battery-icon-large rotate: false - xy: 555, 437 + xy: 229, 210 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +battery-icon-small + rotate: false + xy: 855, 481 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +battery-large-icon-full + rotate: false + xy: 261, 1733 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +battery-large-icon-large + rotate: false + xy: 229, 160 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +battery-large-icon-medium + rotate: false + xy: 1552, 1388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +battery-large-icon-small + rotate: false + xy: 779, 589 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +biomattercompressor-icon-full + rotate: false + xy: 1780, 1983 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -javelin-ship-pad +biomattercompressor-icon-large rotate: false - xy: 555, 437 - size: 64, 64 - orig: 64, 64 + xy: 229, 110 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -block-icon-junction +biomattercompressor-icon-medium rotate: false - xy: 229, 276 + xy: 1586, 1388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -block-icon-lancer +biomattercompressor-icon-small + rotate: false + xy: 787, 563 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +blackrock-icon-full + rotate: false + xy: 1654, 1388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blackrock-icon-medium + rotate: false + xy: 1654, 1388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blackrock-icon-large + rotate: false + xy: 279, 311 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +blackrock-icon-small + rotate: false + xy: 787, 537 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +blackstone-icon-full + rotate: false + xy: 1165, 1279 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blackstone-icon-medium + rotate: false + xy: 1165, 1279 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blackstone-icon-large + rotate: false + xy: 279, 261 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +blackstone-icon-small + rotate: false + xy: 787, 511 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +blast-drill-icon-full + rotate: false + xy: 359, 1733 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +blast-drill-icon-large + rotate: false + xy: 279, 211 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +blast-drill-icon-medium + rotate: false + xy: 1157, 1245 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blast-drill-icon-small + rotate: false + xy: 1085, 866 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +blast-mixer-icon-full rotate: false xy: 594, 1936 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -block-icon-laser-drill +blast-mixer-icon-large rotate: false - xy: 594, 1870 + xy: 329, 261 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +blast-mixer-icon-medium + rotate: false + xy: 1207, 1313 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +blast-mixer-icon-small + rotate: false + xy: 855, 455 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +bridge-conduit-icon-full + rotate: false + xy: 1824, 1379 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conduit-icon-medium + rotate: false + xy: 1824, 1379 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conduit-icon-large + rotate: false + xy: 329, 211 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +bridge-conduit-icon-small + rotate: false + xy: 881, 478 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +bridge-conveyor-icon-full + rotate: false + xy: 260, 32 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conveyor-icon-medium + rotate: false + xy: 260, 32 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +bridge-conveyor-icon-large + rotate: false + xy: 379, 261 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +bridge-conveyor-icon-small + rotate: false + xy: 753, 527 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +combustion-generator-icon-full + rotate: false + xy: 1858, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +combustion-generator-icon-medium + rotate: false + xy: 1858, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +combustion-generator-icon-large + rotate: false + xy: 279, 111 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +combustion-generator-icon-small + rotate: false + xy: 855, 429 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +conduit-icon-full + rotate: false + xy: 711, 647 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-icon-medium + rotate: false + xy: 711, 647 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conduit-icon-large + rotate: false + xy: 329, 161 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +conduit-icon-small + rotate: false + xy: 881, 452 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +container-icon-full + rotate: false + xy: 990, 1909 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -block-icon-launch-pad +container-icon-large rotate: false - xy: 359, 1341 + xy: 379, 211 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +container-icon-medium + rotate: false + xy: 711, 613 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +container-icon-small + rotate: false + xy: 1085, 814 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +conveyor-icon-full + rotate: false + xy: 1259, 1189 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conveyor-icon-medium + rotate: false + xy: 1259, 1189 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +conveyor-icon-large + rotate: false + xy: 429, 261 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +conveyor-icon-small + rotate: false + xy: 855, 403 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +copper-wall-icon-full + rotate: false + xy: 745, 587 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +copper-wall-icon-medium + rotate: false + xy: 745, 587 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +copper-wall-icon-large + rotate: false + xy: 479, 311 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +copper-wall-icon-small + rotate: false + xy: 881, 426 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +copper-wall-large-icon-full + rotate: false + xy: 1122, 1909 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +copper-wall-large-icon-large + rotate: false + xy: 329, 111 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +copper-wall-large-icon-medium + rotate: false + xy: 753, 553 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +copper-wall-large-icon-small + rotate: false + xy: 1085, 788 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +core-icon-full + rotate: false + xy: 261, 1341 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -launch-pad +core-icon-large rotate: false - xy: 359, 1341 - size: 96, 96 - orig: 96, 96 + xy: 379, 161 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -block-icon-liquid-junction +core-icon-medium rotate: false - xy: 229, 242 + xy: 975, 1149 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -liquid-junction +core-icon-small rotate: false - xy: 229, 242 + xy: 855, 377 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +craters-icon-full + rotate: false + xy: 1892, 1345 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -block-icon-liquid-router +craters-icon-medium rotate: false - xy: 229, 208 + xy: 1892, 1345 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -block-icon-liquid-source +craters-icon-large rotate: false - xy: 229, 174 - size: 32, 32 - orig: 32, 32 + xy: 429, 211 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -liquid-source +craters-icon-small rotate: false - xy: 229, 174 - size: 32, 32 - orig: 32, 32 + xy: 881, 400 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 -block-icon-liquid-tank - rotate: false - xy: 457, 1439 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-mass-driver - rotate: false - xy: 261, 1145 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -mass-driver - rotate: false - xy: 261, 1145 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-mechanical-drill - rotate: false - xy: 660, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-mechanical-pump - rotate: false - xy: 229, 140 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -mechanical-pump - rotate: false - xy: 229, 140 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-meltdown - rotate: false - xy: 334, 1831 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -block-icon-melter - rotate: false - xy: 229, 106 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -melter - rotate: false - xy: 229, 106 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-mend-projector - rotate: false - xy: 726, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -mend-projector - rotate: false - xy: 726, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-metalfloor - rotate: false - xy: 229, 72 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor1 - rotate: false - xy: 229, 72 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-oil-extractor - rotate: false - xy: 359, 1243 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-omega-mech-pad - rotate: false - xy: 457, 1341 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -omega-mech-pad - rotate: false - xy: 457, 1341 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-overdrive-projector - rotate: false - xy: 792, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -overdrive-projector - rotate: false - xy: 792, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-overflow-gate - rotate: false - xy: 1967, 1817 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -overflow-gate - rotate: false - xy: 1967, 1817 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-phantom-factory - rotate: false - xy: 858, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-phase-conduit - rotate: false - xy: 1967, 1783 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-conduit - rotate: false - xy: 1967, 1783 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-phase-conveyor - rotate: false - xy: 551, 335 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-conveyor - rotate: false - xy: 551, 335 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-phase-wall - rotate: false - xy: 585, 335 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-wall - rotate: false - xy: 585, 335 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-phase-wall-large - rotate: false - xy: 924, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -phase-wall-large - rotate: false - xy: 924, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-phase-weaver - rotate: false - xy: 990, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-plasma-drill - rotate: false - xy: 1, 1368 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -block-icon-plastanium-compressor - rotate: false - xy: 1056, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -plastanium-compressor - rotate: false - xy: 1056, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-pneumatic-drill - rotate: false - xy: 1122, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-power-node - rotate: false - xy: 983, 1430 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-power-node-large - rotate: false - xy: 1188, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-power-source - rotate: false - xy: 975, 1396 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -power-source - rotate: false - xy: 975, 1396 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-power-void - rotate: false - xy: 1017, 1430 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -power-void - rotate: false - xy: 1017, 1430 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-pulse-conduit - rotate: false - xy: 1009, 1396 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-pulverizer - rotate: false - xy: 1107, 1619 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-pyratite-mixer +cryofluidmixer-icon-full rotate: false xy: 1254, 1917 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -pyratite-mixer +cryofluidmixer-icon-large rotate: false - xy: 1254, 1917 - size: 64, 64 - orig: 64, 64 + xy: 479, 261 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -block-icon-reconstructor +cryofluidmixer-icon-medium rotate: false - xy: 1320, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -dagger-factory - rotate: false - xy: 1320, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -phantom-factory - rotate: false - xy: 1320, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -reconstructor - rotate: false - xy: 1320, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -spirit-factory - rotate: false - xy: 1320, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -wraith-factory - rotate: false - xy: 1320, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-repair-point - rotate: false - xy: 1107, 1585 + xy: 1926, 1345 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -repair-point +cryofluidmixer-icon-small rotate: false - xy: 1107, 1585 - size: 32, 32 - orig: 32, 32 + xy: 1085, 762 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 -block-icon-revenant-factory - rotate: false - xy: 1, 1238 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -block-icon-ripple - rotate: false - xy: 261, 1047 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-rock - rotate: false - xy: 1141, 1627 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rock1 - rotate: false - xy: 1141, 1627 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-rocks-medium - rotate: false - xy: 1141, 1593 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rocks-medium1 - rotate: false - xy: 1141, 1593 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-rocks-small - rotate: false - xy: 1181, 1693 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rocks-small1 - rotate: false - xy: 1181, 1693 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-rotary-pump - rotate: false - xy: 1386, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -rotary-pump - rotate: false - xy: 1386, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-router - rotate: false - xy: 1215, 1693 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -router - rotate: false - xy: 1215, 1693 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-rtg-generator - rotate: false - xy: 1452, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -rtg-generator - rotate: false - xy: 1452, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-salvo +cultivator-icon-full rotate: false xy: 1518, 1917 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -block-icon-sand +cultivator-icon-large rotate: false - xy: 843, 1289 + xy: 529, 311 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +cultivator-icon-medium + rotate: false + xy: 1960, 1345 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -sand1 +cultivator-icon-small rotate: false - xy: 843, 1289 - size: 32, 32 - orig: 32, 32 + xy: 855, 351 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 -block-icon-scorch +cyclone-icon-full rotate: false - xy: 843, 1255 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-separator - rotate: false - xy: 877, 1297 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -separator - rotate: false - xy: 877, 1297 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-shock-mine - rotate: false - xy: 877, 1263 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -shock-mine - rotate: false - xy: 877, 1263 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-shrub - rotate: false - xy: 771, 957 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -shrub - rotate: false - xy: 771, 957 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-silicon-smelter - rotate: false - xy: 1584, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -silicon-smelter - rotate: false - xy: 1584, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-snow - rotate: false - xy: 759, 654 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -snow1 - rotate: false - xy: 759, 654 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-solar-panel - rotate: false - xy: 759, 620 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -solar-panel - rotate: false - xy: 759, 620 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-solar-panel-large - rotate: false - xy: 359, 1145 + xy: 359, 1341 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -solar-panel-large +cyclone-icon-large rotate: false - xy: 359, 1145 - size: 96, 96 - orig: 96, 96 + xy: 379, 111 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -block-icon-sorter +cyclone-icon-medium rotate: false - xy: 759, 586 + xy: 1994, 1354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -sorter +cyclone-icon-small rotate: false - xy: 759, 586 - size: 32, 32 - orig: 32, 32 + xy: 881, 374 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 -block-icon-space - rotate: false - xy: 759, 552 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -space - rotate: false - xy: 759, 552 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-spawn - rotate: false - xy: 759, 518 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -spawn - rotate: false - xy: 759, 518 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-spectre - rotate: false - xy: 1, 1108 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -block-icon-spirit-factory - rotate: false - xy: 1650, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-stone - rotate: false - xy: 759, 484 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -stone1 - rotate: false - xy: 759, 484 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-surge-wall - rotate: false - xy: 759, 450 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -surge-wall - rotate: false - xy: 759, 450 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-surge-wall-large - rotate: false - xy: 1716, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -surge-wall-large - rotate: false - xy: 1716, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-swarmer +dagger-factory-icon-full rotate: false xy: 1782, 1917 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -block-icon-tar +dagger-factory-icon-large rotate: false - xy: 721, 415 + xy: 529, 261 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +dagger-factory-icon-medium + rotate: false + xy: 1994, 1320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -tar +dagger-factory-icon-small rotate: false - xy: 721, 415 + xy: 1085, 736 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +dart-ship-pad-icon-full + rotate: false + xy: 660, 1843 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +dart-ship-pad-icon-large + rotate: false + xy: 479, 161 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +dart-ship-pad-icon-medium + rotate: false + xy: 273, 76 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -block-icon-tau-mech-pad +dart-ship-pad-icon-small rotate: false - xy: 1848, 1917 + xy: 1085, 710 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +deepwater-icon-large + rotate: false + xy: 529, 211 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +deepwater-icon-small + rotate: false + xy: 1085, 684 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +delta-mech-pad-icon-full + rotate: false + xy: 792, 1843 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -tau-mech-pad +delta-mech-pad-icon-large rotate: false - xy: 1848, 1917 + xy: 579, 211 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +delta-mech-pad-icon-medium + rotate: false + xy: 341, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +delta-mech-pad-icon-small + rotate: false + xy: 1085, 658 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +dirt-icon-full + rotate: false + xy: 477, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +dirt-icon-medium + rotate: false + xy: 477, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +dirt-icon-large + rotate: false + xy: 529, 111 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +dirt-icon-small + rotate: false + xy: 1085, 632 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +distributor-icon-full + rotate: false + xy: 924, 1843 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -block-icon-thermal-generator +distributor-icon-large rotate: false - xy: 1914, 1917 + xy: 579, 111 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +distributor-icon-medium + rotate: false + xy: 511, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +distributor-icon-small + rotate: false + xy: 1085, 606 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +door-icon-full + rotate: false + xy: 579, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +door-icon-medium + rotate: false + xy: 579, 77 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +door-icon-large + rotate: false + xy: 687, 475 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +door-icon-small + rotate: false + xy: 1085, 580 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +door-large-icon-full + rotate: false + xy: 1056, 1843 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -thermal-generator +door-large-icon-large rotate: false - xy: 1914, 1917 - size: 64, 64 - orig: 64, 64 + xy: 687, 425 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -block-icon-thermal-pump +door-large-icon-medium rotate: false - xy: 660, 1851 - size: 64, 64 - orig: 64, 64 + xy: 294, 42 + size: 32, 32 + orig: 32, 32 offset: 0, 0 index: -1 -thermal-pump +door-large-icon-small rotate: false - xy: 660, 1851 - size: 64, 64 - orig: 64, 64 + xy: 1085, 554 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 -block-icon-thorium-reactor +duo-icon-full rotate: false - xy: 457, 1243 + xy: 396, 43 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +duo-icon-medium + rotate: false + xy: 396, 43 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +duo-icon-large + rotate: false + xy: 687, 375 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +duo-icon-small + rotate: false + xy: 1085, 528 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +force-projector-icon-full + rotate: false + xy: 261, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -thorium-reactor +force-projector-icon-large rotate: false - xy: 457, 1243 + xy: 737, 425 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +force-projector-icon-medium + rotate: false + xy: 498, 43 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +force-projector-icon-small + rotate: false + xy: 1085, 502 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +fortress-factory-icon-full + rotate: false + xy: 261, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -block-icon-thorium-wall +fortress-factory-icon-large rotate: false - xy: 1980, 1949 + xy: 737, 375 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +fortress-factory-icon-medium + rotate: false + xy: 532, 43 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -thorium-wall +fortress-factory-icon-small rotate: false - xy: 1980, 1949 - size: 32, 32 - orig: 32, 32 + xy: 1085, 476 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 -block-icon-thorium-wall-large - rotate: false - xy: 726, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -thorium-wall-large - rotate: false - xy: 726, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-titan-factory - rotate: false - xy: 261, 949 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-icon-titanium-conveyor - rotate: false - xy: 1980, 1915 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -titanium-conveyor-0-0 - rotate: false - xy: 1980, 1915 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-trident-ship-pad - rotate: false - xy: 792, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -trident-ship-pad - rotate: false - xy: 792, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-turbine-generator - rotate: false - xy: 858, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -turbine-generator - rotate: false - xy: 858, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-icon-unloader - rotate: false - xy: 1980, 1881 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -unloader - rotate: false - xy: 1980, 1881 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -block-icon-vault +fuse-icon-full rotate: false xy: 359, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -vault +fuse-icon-large rotate: false - xy: 359, 1047 + xy: 637, 325 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +fuse-icon-medium + rotate: false + xy: 566, 43 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +fuse-icon-small + rotate: false + xy: 1110, 963 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +fusion-reactor-icon-full + rotate: false + xy: 1, 1368 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +fusion-reactor-icon-large + rotate: false + xy: 687, 325 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +fusion-reactor-icon-medium + rotate: false + xy: 294, 8 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +fusion-reactor-icon-small + rotate: false + xy: 881, 348 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ghoul-factory-icon-full + rotate: false + xy: 261, 851 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -block-icon-water +ghoul-factory-icon-large rotate: false - xy: 2014, 1957 + xy: 737, 325 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ghoul-factory-icon-medium + rotate: false + xy: 464, 13 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -water +ghoul-factory-icon-small rotate: false - xy: 2014, 1957 + xy: 907, 453 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +glaive-ship-pad-icon-full + rotate: false + xy: 457, 1047 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +glaive-ship-pad-icon-large + rotate: false + xy: 629, 275 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +glaive-ship-pad-icon-medium + rotate: false + xy: 498, 9 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -block-icon-water-extractor +glaive-ship-pad-icon-small rotate: false - xy: 924, 1851 + xy: 933, 453 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +grass-icon-full + rotate: false + xy: 634, 41 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +grass-icon-medium + rotate: false + xy: 634, 41 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +grass-icon-large + rotate: false + xy: 629, 225 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +grass-icon-small + rotate: false + xy: 907, 427 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +hail-icon-full + rotate: false + xy: 702, 41 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +hail-icon-medium + rotate: false + xy: 702, 41 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +hail-icon-large + rotate: false + xy: 629, 175 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +hail-icon-small + rotate: false + xy: 959, 453 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ice-icon-full + rotate: false + xy: 668, 7 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice-icon-medium + rotate: false + xy: 668, 7 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice-icon-large + rotate: false + xy: 729, 275 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ice-icon-small + rotate: false + xy: 907, 401 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +icerock-icon-full + rotate: false + xy: 770, 19 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +icerock-icon-medium + rotate: false + xy: 770, 19 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +icerock-icon-large + rotate: false + xy: 679, 175 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +icerock-icon-small + rotate: false + xy: 933, 427 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +incinerator-icon-full + rotate: false + xy: 1109, 1197 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +incinerator-icon-medium + rotate: false + xy: 1109, 1197 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +incinerator-icon-large + rotate: false + xy: 679, 125 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +incinerator-icon-small + rotate: false + xy: 959, 427 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +item-source-icon-full + rotate: false + xy: 1313, 1121 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +item-source-icon-medium + rotate: false + xy: 1313, 1121 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +item-source-icon-large + rotate: false + xy: 729, 175 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +item-source-icon-small + rotate: false + xy: 907, 349 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +item-void-icon-full + rotate: false + xy: 1411, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +item-void-icon-medium + rotate: false + xy: 1411, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +item-void-icon-large + rotate: false + xy: 729, 125 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +item-void-icon-small + rotate: false + xy: 933, 375 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +javelin-ship-pad-icon-full + rotate: false + xy: 1452, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -block-icon-wave +javelin-ship-pad-icon-large rotate: false - xy: 990, 1851 + xy: 679, 75 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +javelin-ship-pad-icon-medium + rotate: false + xy: 1411, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +javelin-ship-pad-icon-small + rotate: false + xy: 959, 401 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +junction-icon-full + rotate: false + xy: 1445, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +junction-icon-medium + rotate: false + xy: 1445, 1320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +junction-icon-large + rotate: false + xy: 1188, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +junction-icon-small + rotate: false + xy: 985, 427 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +lancer-icon-full + rotate: false + xy: 1650, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -block-icon-wraith-factory +lancer-icon-large rotate: false - xy: 1056, 1851 + xy: 1238, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +lancer-icon-medium + rotate: false + xy: 1479, 1354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lancer-icon-small + rotate: false + xy: 1114, 895 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +laser-drill-icon-full + rotate: false + xy: 1782, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -deepwater-cliff-edge +laser-drill-icon-large rotate: false - xy: 1783, 1733 + xy: 1288, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +laser-drill-icon-medium + rotate: false + xy: 1479, 1320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -deepwater-cliff-edge-1 +laser-drill-icon-small rotate: false - xy: 1851, 1767 + xy: 933, 349 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +launch-pad-icon-full + rotate: false + xy: 359, 851 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +launch-pad-icon-large + rotate: false + xy: 1338, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +launch-pad-icon-medium + rotate: false + xy: 1513, 1354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -deepwater-cliff-edge-2 +launch-pad-icon-small rotate: false - xy: 1817, 1733 + xy: 959, 375 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +liquid-junction-icon-full + rotate: false + xy: 1649, 1354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -deepwater-cliff-side +liquid-junction-icon-medium rotate: false - xy: 1885, 1767 + xy: 1649, 1354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -dirt-cliff-edge +liquid-junction-icon-large rotate: false - xy: 1953, 1749 + xy: 1438, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +liquid-junction-icon-small + rotate: false + xy: 985, 401 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +liquid-router-icon-full + rotate: false + xy: 1683, 1320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -dirt-cliff-edge-1 +liquid-router-icon-medium rotate: false - xy: 1953, 1715 + xy: 1683, 1320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -dirt-cliff-edge-2 +liquid-router-icon-large rotate: false - xy: 1987, 1749 + xy: 1488, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +liquid-router-icon-small + rotate: false + xy: 959, 349 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +liquid-source-icon-full + rotate: false + xy: 1819, 1345 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -dirt-cliff-side +liquid-source-icon-medium rotate: false - xy: 1987, 1715 + xy: 1819, 1345 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -grass-cliff-edge +liquid-source-icon-large rotate: false - xy: 1555, 1699 + xy: 1538, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +liquid-source-icon-small + rotate: false + xy: 985, 375 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +liquid-tank-icon-full + rotate: false + xy: 261, 655 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +liquid-tank-icon-large + rotate: false + xy: 1588, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +liquid-tank-icon-medium + rotate: false + xy: 1751, 1311 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -grass-cliff-edge-1 +liquid-tank-icon-small rotate: false - xy: 1589, 1699 + xy: 985, 349 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +mass-driver-icon-full + rotate: false + xy: 457, 753 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +mass-driver-icon-large + rotate: false + xy: 1638, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +mass-driver-icon-medium + rotate: false + xy: 1819, 1311 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -grass-cliff-edge-2 +mass-driver-icon-small rotate: false - xy: 1623, 1699 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grass-cliff-side - rotate: false - xy: 1657, 1699 - size: 32, 32 - orig: 32, 32 + xy: 1011, 444 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 mech-icon-alpha-mech rotate: false - xy: 679, 1041 + xy: 1688, 1801 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mech-icon-dart-ship rotate: false - xy: 679, 991 + xy: 1738, 1801 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mech-icon-delta-mech rotate: false - xy: 679, 941 + xy: 1788, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +mech-icon-glaive-ship + rotate: false + xy: 653, 861 + size: 56, 56 + orig: 56, 56 + offset: 0, 0 + index: -1 +mech-icon-javelin-ship + rotate: false + xy: 1838, 1801 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mech-icon-omega-mech rotate: false - xy: 1049, 1595 + xy: 719, 927 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 mech-icon-tau-mech rotate: false - xy: 1115, 1661 + xy: 785, 993 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 mech-icon-trident-ship rotate: false - xy: 1181, 1727 + xy: 851, 1059 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 -trident-ship +mechanical-drill-icon-full rotate: false - xy: 1181, 1727 - size: 56, 56 - orig: 56, 56 + xy: 653, 1777 + size: 64, 64 + orig: 64, 64 offset: 0, 0 index: -1 -metalfloor-cliff-edge +mechanical-drill-icon-large rotate: false - xy: 297, 153 + xy: 1888, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +mechanical-drill-icon-medium + rotate: false + xy: 1853, 1320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -metalfloor-cliff-edge-1 +mechanical-drill-icon-small rotate: false - xy: 331, 187 + xy: 1011, 418 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +mechanical-pump-icon-full + rotate: false + xy: 1921, 1311 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -metalfloor-cliff-edge-2 +mechanical-pump-icon-medium rotate: false - xy: 365, 221 + xy: 1921, 1311 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -metalfloor-cliff-side +mechanical-pump-icon-large rotate: false - xy: 399, 255 + xy: 1938, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +mechanical-pump-icon-small + rotate: false + xy: 1037, 444 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +meltdown-icon-full + rotate: false + xy: 1, 198 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +meltdown-icon-large + rotate: false + xy: 1988, 1801 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +meltdown-icon-medium + rotate: false + xy: 1955, 1311 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +meltdown-icon-small + rotate: false + xy: 1011, 392 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +melter-icon-full + rotate: false + xy: 1887, 1277 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +melter-icon-medium + rotate: false + xy: 1887, 1277 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +melter-icon-large + rotate: false + xy: 1181, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +melter-icon-small + rotate: false + xy: 1037, 418 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +mend-projector-icon-full + rotate: false + xy: 719, 1711 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +mend-projector-icon-large + rotate: false + xy: 1181, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +mend-projector-icon-medium + rotate: false + xy: 1921, 1277 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +mend-projector-icon-small + rotate: false + xy: 1011, 366 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +metalfloor-icon-full + rotate: false + xy: 1395, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalfloor-icon-medium + rotate: false + xy: 1395, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metalfloor-icon-large + rotate: false + xy: 1231, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +metalfloor-icon-small + rotate: false + xy: 1037, 392 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +oil-extractor-icon-full + rotate: false + xy: 359, 557 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +oil-extractor-icon-large + rotate: false + xy: 1231, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +oil-extractor-icon-medium + rotate: false + xy: 1395, 1252 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +oil-extractor-icon-small + rotate: false + xy: 1037, 366 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +omega-mech-pad-icon-full + rotate: false + xy: 343, 361 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +omega-mech-pad-icon-large + rotate: false + xy: 1281, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +omega-mech-pad-icon-medium + rotate: false + xy: 1429, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +omega-mech-pad-icon-small + rotate: false + xy: 1063, 444 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-coal-blackstone-icon-large + rotate: false + xy: 1181, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-coal-blackstone-icon-small + rotate: false + xy: 1063, 418 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-coal-blackstone1 rotate: false - xy: 501, 323 + xy: 1429, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-blackstone2 rotate: false - xy: 297, 119 + xy: 1429, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-blackstone3 rotate: false - xy: 331, 153 + xy: 1463, 1286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-coal-blackstone-icon-full + rotate: false + xy: 1463, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-blackstone-icon-medium + rotate: false + xy: 1463, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-grass-icon-large + rotate: false + xy: 1231, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-coal-grass-icon-small + rotate: false + xy: 1063, 392 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-coal-grass1 rotate: false - xy: 365, 187 + xy: 1463, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-grass2 rotate: false - xy: 399, 221 + xy: 1463, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-grass3 rotate: false - xy: 433, 255 + xy: 1497, 1286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-coal-grass-icon-full + rotate: false + xy: 1497, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-grass-icon-medium + rotate: false + xy: 1497, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-ice-icon-large + rotate: false + xy: 1281, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-coal-ice-icon-small + rotate: false + xy: 1063, 366 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-coal-ice1 rotate: false - xy: 467, 289 + xy: 1497, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-ice2 rotate: false - xy: 297, 85 + xy: 1497, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-ice3 rotate: false - xy: 331, 119 + xy: 1531, 1286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-coal-ice-icon-full + rotate: false + xy: 1531, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-ice-icon-medium + rotate: false + xy: 1531, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-sand-icon-large + rotate: false + xy: 1331, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-coal-sand-icon-small + rotate: false + xy: 855, 325 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-coal-sand1 rotate: false - xy: 365, 153 + xy: 1531, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-sand2 rotate: false - xy: 399, 187 + xy: 1531, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-sand3 rotate: false - xy: 433, 221 + xy: 1565, 1286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-coal-sand-icon-full + rotate: false + xy: 1565, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-sand-icon-medium + rotate: false + xy: 1565, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-snow-icon-large + rotate: false + xy: 1181, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-coal-snow-icon-small + rotate: false + xy: 881, 322 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-coal-snow1 rotate: false - xy: 467, 255 + xy: 1565, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-snow2 rotate: false - xy: 501, 289 + xy: 1565, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-snow3 rotate: false - xy: 331, 85 + xy: 1599, 1286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-coal-snow-icon-full + rotate: false + xy: 1599, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-snow-icon-medium + rotate: false + xy: 1599, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-stone-icon-large + rotate: false + xy: 1231, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-coal-stone-icon-small + rotate: false + xy: 907, 323 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-coal-stone1 rotate: false - xy: 365, 119 + xy: 1599, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-stone2 rotate: false - xy: 399, 153 + xy: 1599, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-stone3 rotate: false - xy: 433, 187 + xy: 1633, 1286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-coal-stone-icon-full + rotate: false + xy: 1633, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-stone-icon-medium + rotate: false + xy: 1633, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-blackstone-icon-large + rotate: false + xy: 1281, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-copper-blackstone-icon-small + rotate: false + xy: 933, 323 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-copper-blackstone1 rotate: false - xy: 467, 221 + xy: 1633, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-blackstone2 rotate: false - xy: 501, 255 + xy: 1633, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-blackstone3 rotate: false - xy: 365, 85 + xy: 1667, 1286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-copper-blackstone-icon-full + rotate: false + xy: 1667, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-blackstone-icon-medium + rotate: false + xy: 1667, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-grass-icon-large + rotate: false + xy: 1331, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-copper-grass-icon-small + rotate: false + xy: 959, 323 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-copper-grass1 rotate: false - xy: 399, 119 + xy: 1667, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-grass2 rotate: false - xy: 433, 153 + xy: 1667, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-grass3 rotate: false - xy: 467, 187 + xy: 1701, 1286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-copper-grass-icon-full + rotate: false + xy: 1701, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-grass-icon-medium + rotate: false + xy: 1701, 1286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-ice-icon-large + rotate: false + xy: 1381, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-copper-ice-icon-small + rotate: false + xy: 985, 323 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-copper-ice1 rotate: false - xy: 501, 221 + xy: 1701, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-ice2 rotate: false - xy: 399, 85 + xy: 1701, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-ice3 rotate: false - xy: 433, 119 + xy: 1735, 1277 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-copper-ice-icon-full + rotate: false + xy: 1735, 1277 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-ice-icon-medium + rotate: false + xy: 1735, 1277 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-sand-icon-large + rotate: false + xy: 1181, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-copper-sand-icon-small + rotate: false + xy: 1011, 340 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-copper-sand1 rotate: false - xy: 467, 153 + xy: 1735, 1243 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-sand2 rotate: false - xy: 501, 187 + xy: 1769, 1277 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-sand3 rotate: false - xy: 433, 85 + xy: 1769, 1243 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-copper-sand-icon-full + rotate: false + xy: 1769, 1243 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-sand-icon-medium + rotate: false + xy: 1769, 1243 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-snow-icon-large + rotate: false + xy: 1231, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-copper-snow-icon-small + rotate: false + xy: 1037, 340 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-copper-snow1 rotate: false - xy: 467, 119 + xy: 1803, 1277 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-snow2 rotate: false - xy: 501, 153 + xy: 1803, 1243 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-snow3 rotate: false - xy: 467, 85 + xy: 1735, 1209 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-copper-snow-icon-full + rotate: false + xy: 1735, 1209 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-snow-icon-medium + rotate: false + xy: 1735, 1209 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-stone-icon-large + rotate: false + xy: 1281, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-copper-stone-icon-small + rotate: false + xy: 1063, 340 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-copper-stone1 rotate: false - xy: 501, 119 + xy: 1769, 1209 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-stone2 rotate: false - xy: 501, 85 + xy: 1803, 1209 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-stone3 rotate: false - xy: 535, 301 + xy: 1837, 1252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-copper-stone-icon-full + rotate: false + xy: 1837, 1252 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-stone-icon-medium + rotate: false + xy: 1837, 1252 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-blackstone-icon-large + rotate: false + xy: 1331, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-lead-blackstone-icon-small + rotate: false + xy: 847, 299 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-lead-blackstone1 rotate: false - xy: 535, 267 + xy: 1837, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-blackstone2 rotate: false - xy: 569, 301 + xy: 1871, 1243 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-blackstone3 rotate: false - xy: 535, 233 + xy: 1905, 1243 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-lead-blackstone-icon-full + rotate: false + xy: 1905, 1243 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-blackstone-icon-medium + rotate: false + xy: 1905, 1243 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-grass-icon-large + rotate: false + xy: 1381, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-lead-grass-icon-small + rotate: false + xy: 847, 273 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-lead-grass1 rotate: false - xy: 569, 267 + xy: 1939, 1243 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-grass2 rotate: false - xy: 535, 199 + xy: 1871, 1209 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-grass3 rotate: false - xy: 569, 233 + xy: 1905, 1209 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-lead-grass-icon-full + rotate: false + xy: 1905, 1209 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-grass-icon-medium + rotate: false + xy: 1905, 1209 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-ice-icon-large + rotate: false + xy: 1431, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-lead-ice-icon-small + rotate: false + xy: 847, 247 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-lead-ice1 rotate: false - xy: 535, 165 + xy: 1939, 1209 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-ice2 rotate: false - xy: 569, 199 + xy: 1973, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-ice3 rotate: false - xy: 535, 131 + xy: 1837, 1184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-lead-ice-icon-full + rotate: false + xy: 1837, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-ice-icon-medium + rotate: false + xy: 1837, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-sand-icon-large + rotate: false + xy: 1181, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-lead-sand-icon-small + rotate: false + xy: 847, 221 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-lead-sand1 rotate: false - xy: 569, 165 + xy: 1871, 1175 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-sand2 rotate: false - xy: 535, 97 + xy: 1905, 1175 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-sand3 rotate: false - xy: 569, 131 + xy: 1939, 1175 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-lead-sand-icon-full + rotate: false + xy: 1939, 1175 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-sand-icon-medium + rotate: false + xy: 1939, 1175 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-snow-icon-large + rotate: false + xy: 1231, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-lead-snow-icon-small + rotate: false + xy: 847, 195 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-lead-snow1 rotate: false - xy: 569, 97 + xy: 1973, 1184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-snow2 rotate: false - xy: 603, 301 + xy: 2007, 1218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-snow3 rotate: false - xy: 603, 267 + xy: 2007, 1184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-lead-snow-icon-full + rotate: false + xy: 2007, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-snow-icon-medium + rotate: false + xy: 2007, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-stone-icon-large + rotate: false + xy: 1281, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-lead-stone-icon-small + rotate: false + xy: 847, 169 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-lead-stone1 rotate: false - xy: 603, 233 + xy: 1973, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-stone2 rotate: false - xy: 603, 199 + xy: 2007, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-stone3 rotate: false - xy: 603, 165 + xy: 1381, 1184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-lead-stone-icon-full + rotate: false + xy: 1381, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-stone-icon-medium + rotate: false + xy: 1381, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-blackstone-icon-large + rotate: false + xy: 1331, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-scrap-blackstone-icon-small + rotate: false + xy: 847, 143 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-scrap-blackstone1 + rotate: false + xy: 1381, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-blackstone2 + rotate: false + xy: 1415, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-blackstone3 + rotate: false + xy: 1415, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-blackstone-icon-full + rotate: false + xy: 1415, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-blackstone-icon-medium + rotate: false + xy: 1415, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-grass-icon-large + rotate: false + xy: 1381, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-scrap-grass-icon-small + rotate: false + xy: 873, 296 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-scrap-grass1 + rotate: false + xy: 1449, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-grass2 + rotate: false + xy: 1449, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-grass3 + rotate: false + xy: 1483, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-grass-icon-full + rotate: false + xy: 1483, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-grass-icon-medium + rotate: false + xy: 1483, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-ice-icon-large + rotate: false + xy: 1431, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-scrap-ice-icon-small + rotate: false + xy: 873, 270 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-scrap-ice1 + rotate: false + xy: 1483, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-ice2 + rotate: false + xy: 1517, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-ice3 + rotate: false + xy: 1517, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-ice-icon-full + rotate: false + xy: 1517, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-ice-icon-medium + rotate: false + xy: 1517, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-sand-icon-large + rotate: false + xy: 1481, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-scrap-sand-icon-small + rotate: false + xy: 873, 244 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-scrap-sand1 + rotate: false + xy: 1551, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-sand2 + rotate: false + xy: 1551, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-sand3 + rotate: false + xy: 1585, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-sand-icon-full + rotate: false + xy: 1585, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-sand-icon-medium + rotate: false + xy: 1585, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-snow-icon-large + rotate: false + xy: 1231, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-scrap-snow-icon-small + rotate: false + xy: 873, 218 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-scrap-snow1 + rotate: false + xy: 1585, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-snow2 + rotate: false + xy: 1619, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-snow3 + rotate: false + xy: 1619, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-snow-icon-full + rotate: false + xy: 1619, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-snow-icon-medium + rotate: false + xy: 1619, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stone-icon-large + rotate: false + xy: 1281, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-scrap-stone-icon-small + rotate: false + xy: 873, 192 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-scrap-stone1 + rotate: false + xy: 1653, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stone2 + rotate: false + xy: 1653, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stone3 + rotate: false + xy: 1687, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stone-icon-full + rotate: false + xy: 1687, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stone-icon-medium + rotate: false + xy: 1687, 1184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-blackstone-icon-large + rotate: false + xy: 1331, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-thorium-blackstone-icon-small + rotate: false + xy: 873, 166 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-thorium-blackstone1 rotate: false - xy: 603, 131 + xy: 1687, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-blackstone2 rotate: false - xy: 603, 97 + xy: 1381, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-blackstone3 rotate: false - xy: 263, 50 + xy: 1415, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-thorium-blackstone-icon-full + rotate: false + xy: 1415, 1116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-blackstone-icon-medium + rotate: false + xy: 1415, 1116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-grass-icon-large + rotate: false + xy: 1381, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-thorium-grass-icon-small + rotate: false + xy: 873, 140 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-thorium-grass1 rotate: false - xy: 297, 51 + xy: 1449, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-grass2 rotate: false - xy: 331, 51 + xy: 1483, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-grass3 rotate: false - xy: 365, 51 + xy: 1517, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-thorium-grass-icon-full + rotate: false + xy: 1517, 1116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-grass-icon-medium + rotate: false + xy: 1517, 1116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-ice-icon-large + rotate: false + xy: 1431, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-thorium-ice-icon-small + rotate: false + xy: 1011, 314 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-thorium-ice1 rotate: false - xy: 399, 51 + xy: 1551, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-ice2 rotate: false - xy: 433, 51 + xy: 1585, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-ice3 rotate: false - xy: 467, 51 + xy: 1619, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-thorium-ice-icon-full + rotate: false + xy: 1619, 1116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-ice-icon-medium + rotate: false + xy: 1619, 1116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-sand-icon-large + rotate: false + xy: 1481, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-thorium-sand-icon-small + rotate: false + xy: 1037, 314 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-thorium-sand1 rotate: false - xy: 501, 51 + xy: 1653, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-sand2 rotate: false - xy: 535, 63 + xy: 1687, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-sand3 rotate: false - xy: 569, 63 + xy: 1721, 1175 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-thorium-sand-icon-full + rotate: false + xy: 1721, 1175 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-sand-icon-medium + rotate: false + xy: 1721, 1175 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-snow-icon-large + rotate: false + xy: 1531, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-thorium-snow-icon-small + rotate: false + xy: 1063, 314 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-thorium-snow1 rotate: false - xy: 603, 63 + xy: 1721, 1141 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-snow2 rotate: false - xy: 535, 29 + xy: 1755, 1175 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-snow3 rotate: false - xy: 569, 29 + xy: 1755, 1141 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-thorium-snow-icon-full + rotate: false + xy: 1755, 1141 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-snow-icon-medium + rotate: false + xy: 1755, 1141 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-stone-icon-large + rotate: false + xy: 1281, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-thorium-stone-icon-small + rotate: false + xy: 260, 6 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-thorium-stone1 rotate: false - xy: 603, 29 + xy: 1789, 1175 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-stone2 rotate: false - xy: 242, 16 + xy: 1789, 1141 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-stone3 rotate: false - xy: 276, 16 + xy: 1721, 1107 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-thorium-stone-icon-full + rotate: false + xy: 1721, 1107 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-stone-icon-medium + rotate: false + xy: 1721, 1107 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-blackstone-icon-large + rotate: false + xy: 1331, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-titanium-blackstone-icon-small + rotate: false + xy: 1089, 450 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-titanium-blackstone1 rotate: false - xy: 310, 17 + xy: 1755, 1107 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-blackstone2 rotate: false - xy: 344, 17 + xy: 1789, 1107 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-blackstone3 rotate: false - xy: 378, 17 + xy: 1823, 1150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-titanium-blackstone-icon-full + rotate: false + xy: 1823, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-blackstone-icon-medium + rotate: false + xy: 1823, 1150 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-grass-icon-large + rotate: false + xy: 1381, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-titanium-grass-icon-small + rotate: false + xy: 1089, 424 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-titanium-grass1 rotate: false - xy: 412, 17 + xy: 1823, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-grass2 rotate: false - xy: 446, 17 + xy: 1857, 1141 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-grass3 rotate: false - xy: 480, 17 + xy: 1891, 1141 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-titanium-grass-icon-full + rotate: false + xy: 1891, 1141 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-grass-icon-medium + rotate: false + xy: 1891, 1141 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-ice-icon-large + rotate: false + xy: 1431, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-titanium-ice-icon-small + rotate: false + xy: 1089, 398 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-titanium-ice1 rotate: false - xy: 755, 415 + xy: 1925, 1141 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-ice2 rotate: false - xy: 1385, 1661 + xy: 1857, 1107 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-ice3 rotate: false - xy: 1419, 1661 + xy: 1891, 1107 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-titanium-ice-icon-full + rotate: false + xy: 1891, 1107 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-ice-icon-medium + rotate: false + xy: 1891, 1107 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-sand-icon-large + rotate: false + xy: 1481, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-titanium-sand-icon-small + rotate: false + xy: 1089, 372 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-titanium-sand1 rotate: false - xy: 1453, 1665 + xy: 1925, 1107 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-sand2 rotate: false - xy: 1487, 1665 + xy: 1959, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-sand3 rotate: false - xy: 1521, 1665 + xy: 1993, 1116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-titanium-sand-icon-full + rotate: false + xy: 1993, 1116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-sand-icon-medium + rotate: false + xy: 1993, 1116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-snow-icon-large + rotate: false + xy: 1531, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-titanium-snow-icon-small + rotate: false + xy: 1089, 346 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-titanium-snow1 rotate: false - xy: 1555, 1665 + xy: 1823, 1082 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-snow2 rotate: false - xy: 1589, 1665 + xy: 1857, 1073 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-snow3 rotate: false - xy: 1623, 1665 + xy: 1891, 1073 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +ore-titanium-snow-icon-full + rotate: false + xy: 1891, 1073 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-snow-icon-medium + rotate: false + xy: 1891, 1073 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-stone-icon-large + rotate: false + xy: 1581, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-titanium-stone-icon-small + rotate: false + xy: 1089, 320 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 ore-titanium-stone1 rotate: false - xy: 1657, 1665 + xy: 1925, 1073 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-stone2 rotate: false - xy: 1691, 1665 + xy: 1959, 1082 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-stone3 rotate: false - xy: 1725, 1665 + xy: 1993, 1082 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -sand-cliff-edge +ore-titanium-stone-icon-full rotate: false - xy: 637, 169 + xy: 1993, 1082 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -sand-cliff-edge-1 +ore-titanium-stone-icon-medium rotate: false - xy: 637, 135 + xy: 1993, 1082 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -sand-cliff-edge-2 +overdrive-projector-icon-full rotate: false - xy: 637, 101 + xy: 719, 1645 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +overdrive-projector-icon-large + rotate: false + xy: 1331, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +overdrive-projector-icon-medium + rotate: false + xy: 1959, 1048 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -sand-cliff-side +overdrive-projector-icon-small rotate: false - xy: 637, 67 + xy: 1141, 1015 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +overflow-gate-icon-full + rotate: false + xy: 819, 949 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -snow-cliff-edge +overflow-gate-icon-medium rotate: false - xy: 1453, 1631 + xy: 819, 949 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -snow-cliff-edge-1 +overflow-gate-icon-large rotate: false - xy: 1487, 1631 + xy: 1381, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +overflow-gate-icon-small + rotate: false + xy: 1167, 1015 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +phantom-factory-icon-full + rotate: false + xy: 851, 1777 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +phantom-factory-icon-large + rotate: false + xy: 1431, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +phantom-factory-icon-medium + rotate: false + xy: 1009, 1147 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -snow-cliff-edge-2 +phantom-factory-icon-small rotate: false - xy: 1521, 1631 + xy: 1193, 1015 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +phase-conduit-icon-full + rotate: false + xy: 945, 1057 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -snow-cliff-side +phase-conduit-icon-medium rotate: false - xy: 1555, 1631 + xy: 945, 1057 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -space-cliff-edge +phase-conduit-icon-large rotate: false - xy: 1657, 1631 + xy: 1481, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +phase-conduit-icon-small + rotate: false + xy: 1140, 989 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +phase-conveyor-icon-full + rotate: false + xy: 979, 1057 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -space-cliff-edge-1 +phase-conveyor-icon-medium rotate: false - xy: 1691, 1631 + xy: 979, 1057 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -space-cliff-edge-2 +phase-conveyor-icon-large rotate: false - xy: 1725, 1631 + xy: 1531, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +phase-conveyor-icon-small + rotate: false + xy: 1136, 963 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +phase-wall-icon-full + rotate: false + xy: 979, 989 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -space-cliff-side +phase-wall-icon-medium rotate: false - xy: 1759, 1631 + xy: 979, 989 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -tar-cliff-edge +phase-wall-icon-large rotate: false - xy: 1997, 1613 + xy: 1581, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +phase-wall-icon-small + rotate: false + xy: 1166, 989 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +phase-wall-large-icon-full + rotate: false + xy: 851, 1711 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +phase-wall-large-icon-large + rotate: false + xy: 1631, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +phase-wall-large-icon-medium + rotate: false + xy: 979, 955 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -tar-cliff-edge-1 +phase-wall-large-icon-small rotate: false - xy: 789, 416 + xy: 1162, 963 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +phase-weaver-icon-full + rotate: false + xy: 719, 1513 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +phase-weaver-icon-large + rotate: false + xy: 1381, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +phase-weaver-icon-medium + rotate: false + xy: 979, 921 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -tar-cliff-edge-2 +phase-weaver-icon-small rotate: false - xy: 823, 417 + xy: 1140, 937 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +plasma-drill-icon-full + rotate: false + xy: 464, 1831 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +plasma-drill-icon-large + rotate: false + xy: 1431, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +plasma-drill-icon-medium + rotate: false + xy: 779, 887 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -tar-cliff-side +plasma-drill-icon-small rotate: false - xy: 1075, 1493 + xy: 1192, 989 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +plastanium-compressor-icon-full + rotate: false + xy: 917, 1711 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +plastanium-compressor-icon-large + rotate: false + xy: 1481, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +plastanium-compressor-icon-medium + rotate: false + xy: 779, 853 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +plastanium-compressor-icon-small + rotate: false + xy: 1188, 963 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +pneumatic-drill-icon-full + rotate: false + xy: 719, 1447 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +pneumatic-drill-icon-large + rotate: false + xy: 1531, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +pneumatic-drill-icon-medium + rotate: false + xy: 779, 819 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pneumatic-drill-icon-small + rotate: false + xy: 1140, 911 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +power-node-icon-full + rotate: false + xy: 779, 751 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-node-icon-medium + rotate: false + xy: 779, 751 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-node-icon-large + rotate: false + xy: 1581, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +power-node-icon-small + rotate: false + xy: 1166, 937 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +power-node-large-icon-full + rotate: false + xy: 983, 1711 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +power-node-large-icon-large + rotate: false + xy: 1631, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +power-node-large-icon-medium + rotate: false + xy: 779, 717 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-node-large-icon-small + rotate: false + xy: 1166, 911 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +power-source-icon-full + rotate: false + xy: 779, 649 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-source-icon-medium + rotate: false + xy: 779, 649 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-source-icon-large + rotate: false + xy: 1681, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +power-source-icon-small + rotate: false + xy: 1192, 937 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +power-void-icon-full + rotate: false + xy: 813, 915 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-void-icon-medium + rotate: false + xy: 813, 915 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +power-void-icon-large + rotate: false + xy: 1431, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +power-void-icon-small + rotate: false + xy: 1192, 911 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +pulse-conduit-icon-full + rotate: false + xy: 813, 813 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-icon-medium + rotate: false + xy: 813, 813 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulse-conduit-icon-large + rotate: false + xy: 1481, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +pulse-conduit-icon-small + rotate: false + xy: 1140, 885 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +pulverizer-icon-full + rotate: false + xy: 847, 881 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulverizer-icon-medium + rotate: false + xy: 847, 881 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pulverizer-icon-large + rotate: false + xy: 1531, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +pulverizer-icon-small + rotate: false + xy: 1166, 885 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +pyratite-mixer-icon-full + rotate: false + xy: 653, 1315 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +pyratite-mixer-icon-large + rotate: false + xy: 1581, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +pyratite-mixer-icon-medium + rotate: false + xy: 847, 813 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pyratite-mixer-icon-small + rotate: false + xy: 1192, 885 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +reconstructor-icon-full + rotate: false + xy: 719, 1381 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +reconstructor-icon-large + rotate: false + xy: 1631, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +reconstructor-icon-medium + rotate: false + xy: 847, 779 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +reconstructor-icon-small + rotate: false + xy: 847, 117 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +repair-point-icon-full + rotate: false + xy: 847, 711 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +repair-point-icon-medium + rotate: false + xy: 847, 711 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +repair-point-icon-large + rotate: false + xy: 1681, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +repair-point-icon-small + rotate: false + xy: 844, 91 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +revenant-factory-icon-full + rotate: false + xy: 131, 1108 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +revenant-factory-icon-large + rotate: false + xy: 1731, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +revenant-factory-icon-medium + rotate: false + xy: 847, 643 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +revenant-factory-icon-small + rotate: false + xy: 844, 65 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ripple-icon-full + rotate: false + xy: 555, 1635 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +ripple-icon-large + rotate: false + xy: 1481, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ripple-icon-medium + rotate: false + xy: 847, 609 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ripple-icon-small + rotate: false + xy: 873, 114 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +rock-icon-full + rotate: false + xy: 1631, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rock-icon-large + rotate: false + xy: 1631, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rock-icon-medium + rotate: false + xy: 881, 912 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rock-icon-small + rotate: false + xy: 870, 88 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +rocks-icon-full + rotate: false + xy: 881, 810 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rocks-icon-medium + rotate: false + xy: 881, 810 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rocks-icon-large + rotate: false + xy: 1681, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rocks-icon-small + rotate: false + xy: 870, 62 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +rotary-pump-icon-full + rotate: false + xy: 917, 1579 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +rotary-pump-icon-large + rotate: false + xy: 1731, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rotary-pump-icon-medium + rotate: false + xy: 881, 776 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rotary-pump-icon-small + rotate: false + xy: 844, 39 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +router-icon-full + rotate: false + xy: 881, 708 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +router-icon-medium + rotate: false + xy: 881, 708 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +router-icon-large + rotate: false + xy: 1781, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +router-icon-small + rotate: false + xy: 870, 36 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +rtg-generator-icon-full + rotate: false + xy: 1049, 1711 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +rtg-generator-icon-large + rotate: false + xy: 1531, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rtg-generator-icon-medium + rotate: false + xy: 881, 674 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rtg-generator-icon-small + rotate: false + xy: 838, 13 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +salvo-icon-full + rotate: false + xy: 983, 1579 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +salvo-icon-large + rotate: false + xy: 1581, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +salvo-icon-medium + rotate: false + xy: 881, 606 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +salvo-icon-small + rotate: false + xy: 864, 10 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +sand-icon-full + rotate: false + xy: 915, 819 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand-icon-medium + rotate: false + xy: 915, 819 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand-icon-large + rotate: false + xy: 1631, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +sand-icon-small + rotate: false + xy: 1114, 869 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +separator-icon-full + rotate: false + xy: 915, 649 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +separator-icon-medium + rotate: false + xy: 915, 649 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +separator-icon-large + rotate: false + xy: 1731, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +separator-icon-small + rotate: false + xy: 1111, 764 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +shock-mine-icon-full + rotate: false + xy: 949, 649 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +shock-mine-icon-medium + rotate: false + xy: 949, 649 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +shock-mine-icon-large + rotate: false + xy: 1781, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +shock-mine-icon-small + rotate: false + xy: 1111, 738 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +silicon-smelter-icon-full + rotate: false + xy: 719, 1249 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +silicon-smelter-icon-large + rotate: false + xy: 1581, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +silicon-smelter-icon-medium + rotate: false + xy: 983, 853 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +silicon-smelter-icon-small + rotate: false + xy: 1111, 712 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +snow-icon-full + rotate: false + xy: 983, 683 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snow-icon-medium + rotate: false + xy: 983, 683 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snow-icon-large + rotate: false + xy: 1631, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +snow-icon-small + rotate: false + xy: 1111, 686 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +solar-panel-icon-full + rotate: false + xy: 983, 615 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +solar-panel-icon-medium + rotate: false + xy: 983, 615 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +solar-panel-icon-large + rotate: false + xy: 1731, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +solar-panel-icon-small + rotate: false + xy: 1111, 660 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +solar-panel-large-icon-full + rotate: false + xy: 555, 1341 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +solar-panel-large-icon-large + rotate: false + xy: 1781, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +solar-panel-large-icon-medium + rotate: false + xy: 915, 581 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +solar-panel-large-icon-small + rotate: false + xy: 1111, 634 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +sorter-icon-full + rotate: false + xy: 847, 575 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sorter-icon-medium + rotate: false + xy: 847, 575 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sorter-icon-large + rotate: false + xy: 1831, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +sorter-icon-small + rotate: false + xy: 1111, 608 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +space-icon-large + rotate: false + xy: 1881, 1751 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +space-icon-small + rotate: false + xy: 1111, 582 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +spawn-icon-full + rotate: false + xy: 949, 547 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +spawn-icon-medium + rotate: false + xy: 949, 547 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +spawn-icon-large + rotate: false + xy: 1681, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +spawn-icon-small + rotate: false + xy: 1111, 556 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +spectre-icon-full + rotate: false + xy: 131, 588 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +spectre-icon-large + rotate: false + xy: 1731, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +spectre-icon-medium + rotate: false + xy: 983, 547 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +spectre-icon-small + rotate: false + xy: 1111, 530 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +spirit-factory-icon-full + rotate: false + xy: 785, 1315 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +spirit-factory-icon-large + rotate: false + xy: 1831, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +spirit-factory-icon-medium + rotate: false + xy: 1013, 1048 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +spirit-factory-icon-small + rotate: false + xy: 1111, 504 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stone-icon-full + rotate: false + xy: 1017, 810 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stone-icon-medium + rotate: false + xy: 1017, 810 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stone-icon-large + rotate: false + xy: 1881, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stone-icon-small + rotate: false + xy: 1111, 478 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +surge-wall-icon-full + rotate: false + xy: 1017, 742 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +surge-wall-icon-medium + rotate: false + xy: 1017, 742 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +surge-wall-icon-large + rotate: false + xy: 1681, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +surge-wall-icon-small + rotate: false + xy: 1115, 452 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +surge-wall-large-icon-full + rotate: false + xy: 1049, 1579 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +surge-wall-large-icon-large + rotate: false + xy: 1731, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +surge-wall-large-icon-medium + rotate: false + xy: 1017, 708 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +surge-wall-large-icon-small + rotate: false + xy: 1115, 426 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +swarmer-icon-full + rotate: false + xy: 653, 1117 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +swarmer-icon-large + rotate: false + xy: 1831, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +swarmer-icon-medium + rotate: false + xy: 1017, 674 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +swarmer-icon-small + rotate: false + xy: 1115, 400 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +tar-icon-large + rotate: false + xy: 1881, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +tar-icon-small + rotate: false + xy: 1115, 374 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +tau-mech-pad-icon-full + rotate: false + xy: 785, 1249 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +tau-mech-pad-icon-large + rotate: false + xy: 1781, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +tau-mech-pad-icon-medium + rotate: false + xy: 1017, 606 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +tau-mech-pad-icon-small + rotate: false + xy: 1115, 348 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +thermal-generator-icon-full + rotate: false + xy: 917, 1381 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +thermal-generator-icon-large + rotate: false + xy: 1831, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +thermal-generator-icon-medium + rotate: false + xy: 1017, 572 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thermal-generator-icon-small + rotate: false + xy: 1115, 322 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +thermal-pump-icon-full + rotate: false + xy: 1049, 1513 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +thermal-pump-icon-large + rotate: false + xy: 1881, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +thermal-pump-icon-medium + rotate: false + xy: 1017, 538 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thermal-pump-icon-small + rotate: false + xy: 1140, 859 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +thorium-reactor-icon-full + rotate: false + xy: 555, 1047 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +thorium-reactor-icon-large + rotate: false + xy: 1931, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +thorium-reactor-icon-medium + rotate: false + xy: 915, 513 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thorium-reactor-icon-small + rotate: false + xy: 1166, 859 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +thorium-wall-icon-full + rotate: false + xy: 983, 513 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thorium-wall-icon-medium + rotate: false + xy: 983, 513 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thorium-wall-icon-large + rotate: false + xy: 1981, 1701 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +thorium-wall-icon-small + rotate: false + xy: 1192, 859 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +thorium-wall-large-icon-full + rotate: false + xy: 653, 1051 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +thorium-wall-large-icon-large + rotate: false + xy: 1781, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +thorium-wall-large-icon-medium + rotate: false + xy: 1017, 504 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thorium-wall-large-icon-small + rotate: false + xy: 1137, 833 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +titan-factory-icon-full + rotate: false + xy: 555, 753 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +titan-factory-icon-large + rotate: false + xy: 1831, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +titan-factory-icon-medium + rotate: false + xy: 1047, 1082 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titan-factory-icon-small + rotate: false + xy: 1163, 833 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +titanium-conveyor-icon-full + rotate: false + xy: 1017, 470 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium-conveyor-icon-medium + rotate: false + xy: 1017, 470 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium-conveyor-icon-large + rotate: false + xy: 1881, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +titanium-conveyor-icon-small + rotate: false + xy: 1137, 807 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +titanium-wall-icon-full + rotate: false + xy: 787, 473 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium-wall-icon-medium + rotate: false + xy: 787, 473 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium-wall-icon-large + rotate: false + xy: 1931, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +titanium-wall-icon-small + rotate: false + xy: 1189, 833 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +titanium-wall-large-icon-full + rotate: false + xy: 917, 1315 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +titanium-wall-large-icon-large + rotate: false + xy: 1981, 1651 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +titanium-wall-large-icon-medium + rotate: false + xy: 821, 473 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +titanium-wall-large-icon-small + rotate: false + xy: 1163, 807 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +trident-ship-pad-icon-full + rotate: false + xy: 1049, 1447 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +trident-ship-pad-icon-large + rotate: false + xy: 1831, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +trident-ship-pad-icon-medium + rotate: false + xy: 787, 405 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +trident-ship-pad-icon-small + rotate: false + xy: 1137, 781 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +turbine-generator-icon-full + rotate: false + xy: 653, 985 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +turbine-generator-icon-large + rotate: false + xy: 1881, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +turbine-generator-icon-medium + rotate: false + xy: 821, 439 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +turbine-generator-icon-small + rotate: false + xy: 1189, 807 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 unit-icon-dagger rotate: false - xy: 729, 1091 + xy: 1931, 1551 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 unit-icon-fortress rotate: false - xy: 917, 1521 + xy: 785, 1117 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 +unit-icon-ghoul + rotate: false + xy: 1112, 1975 + size: 72, 72 + orig: 72, 72 + offset: 0, 0 + index: -1 +unit-icon-phantom + rotate: false + xy: 653, 629 + size: 56, 56 + orig: 56, 56 + offset: 0, 0 + index: -1 +unit-icon-revenant + rotate: false + xy: 131, 360 + size: 112, 112 + orig: 112, 112 + offset: 0, 0 + index: -1 +unit-icon-spirit + rotate: false + xy: 1981, 1601 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 unit-icon-titan rotate: false - xy: 983, 1587 + xy: 851, 1183 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 unit-icon-wraith rotate: false - xy: 729, 1041 + xy: 1881, 1451 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -wraith +unloader-icon-full rotate: false - xy: 729, 1041 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -item-bioglass - rotate: false - xy: 1827, 1699 + xy: 821, 405 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +unloader-icon-medium + rotate: false + xy: 821, 405 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +unloader-icon-large + rotate: false + xy: 1931, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +unloader-icon-small + rotate: false + xy: 1163, 781 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +vault-icon-full + rotate: false + xy: 555, 557 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +vault-icon-large + rotate: false + xy: 1981, 1551 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +vault-icon-medium + rotate: false + xy: 787, 337 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +vault-icon-small + rotate: false + xy: 1137, 755 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +water-extractor-icon-full + rotate: false + xy: 983, 1315 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +water-extractor-icon-large + rotate: false + xy: 1931, 1451 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +water-extractor-icon-medium + rotate: false + xy: 813, 201 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +water-extractor-icon-small + rotate: false + xy: 1189, 781 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +water-icon-large + rotate: false + xy: 1981, 1501 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +water-icon-small + rotate: false + xy: 1163, 755 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +wave-icon-full + rotate: false + xy: 785, 1051 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +wave-icon-large + rotate: false + xy: 1173, 1397 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +wave-icon-medium + rotate: false + xy: 813, 167 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +wave-icon-small + rotate: false + xy: 1137, 729 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +wraith-factory-icon-full + rotate: false + xy: 917, 1183 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +wraith-factory-icon-large + rotate: false + xy: 1223, 1401 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +wraith-factory-icon-medium + rotate: false + xy: 813, 133 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +wraith-factory-icon-small + rotate: false + xy: 1189, 755 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 item-biomatter rotate: false - xy: 1861, 1699 + xy: 1075, 1163 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-blast-compound rotate: false - xy: 1895, 1699 + xy: 1109, 1163 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-coal rotate: false - xy: 1041, 1488 + xy: 1143, 1177 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-copper rotate: false - xy: 793, 655 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -item-dense-alloy - rotate: false - xy: 793, 621 + xy: 1177, 1177 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-graphite rotate: false - xy: 793, 587 + xy: 1211, 1177 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-lead rotate: false - xy: 793, 553 + xy: 1143, 1143 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +item-metaglass + rotate: false + xy: 1177, 1143 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-phase-fabric rotate: false - xy: 793, 519 + xy: 1211, 1143 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-plastanium rotate: false - xy: 793, 485 + xy: 1245, 1155 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-pyratite rotate: false - xy: 793, 451 + xy: 1279, 1155 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-sand rotate: false - xy: 263, 322 + xy: 1313, 1155 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +item-scrap + rotate: false + xy: 1347, 1155 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-silicon rotate: false - xy: 263, 288 + xy: 1245, 1121 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-stone rotate: false - xy: 263, 254 + xy: 1347, 1121 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-surge-alloy rotate: false - xy: 263, 220 + xy: 1343, 1354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-thorium rotate: false - xy: 263, 186 + xy: 1343, 1320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-titanium rotate: false - xy: 263, 152 + xy: 1377, 1354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-cryofluid rotate: false - xy: 297, 255 + xy: 1615, 1354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-oil rotate: false - xy: 331, 289 + xy: 1649, 1320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-slag rotate: false - xy: 365, 289 + xy: 1751, 1345 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-water rotate: false - xy: 433, 323 + xy: 1785, 1311 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 alpha-mech rotate: false - xy: 1467, 1801 + xy: 637, 475 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 alpha-mech-base rotate: false - xy: 1517, 1801 + xy: 637, 425 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 alpha-mech-leg rotate: false - xy: 1567, 1801 + xy: 637, 375 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 delta-mech rotate: false - xy: 629, 1041 + xy: 579, 261 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 delta-mech-base rotate: false - xy: 629, 991 + xy: 479, 111 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 delta-mech-leg rotate: false - xy: 629, 941 + xy: 529, 161 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 omega-mech rotate: false - xy: 1247, 1793 + xy: 917, 1125 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 omega-mech-armor rotate: false - xy: 719, 1199 + xy: 983, 1191 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 omega-mech-base rotate: false - xy: 785, 1265 + xy: 1049, 1257 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 omega-mech-leg rotate: false - xy: 851, 1331 + xy: 152, 8 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 tau-mech rotate: false - xy: 1305, 1793 + xy: 653, 745 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 tau-mech-base rotate: false - xy: 671, 441 + xy: 1981, 1751 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 tau-mech-leg rotate: false - xy: 703, 1141 + xy: 1731, 1451 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dart-ship rotate: false - xy: 629, 1091 + xy: 429, 111 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 glaive-ship rotate: false - xy: 1988, 1991 - size: 56, 56 - orig: 56, 56 - offset: 0, 0 - index: -1 -mech-icon-glaive-ship - rotate: false - xy: 1988, 1991 + xy: 1115, 1389 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 javelin-ship rotate: false - xy: 621, 491 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -mech-icon-javelin-ship - rotate: false - xy: 621, 491 + xy: 629, 75 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 javelin-ship-shield rotate: false - xy: 621, 441 + xy: 729, 75 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 +trident-ship + rotate: false + xy: 653, 687 + size: 56, 56 + orig: 56, 56 + offset: 0, 0 + index: -1 blank rotate: false - xy: 258, 1828 + xy: 870, 114 size: 1, 1 orig: 1, 1 offset: 0, 0 @@ -5130,21 +8602,37 @@ circle index: -1 clear rotate: false - xy: 721, 688 + xy: 258, 1828 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 shape-3 rotate: false - xy: 983, 1522 + xy: 87, 1 size: 63, 63 orig: 63, 63 offset: 0, 0 index: -1 +bar + rotate: false + xy: 1111, 989 + size: 27, 36 + split: 9, 9, 9, 9 + orig: 27, 36 + offset: 0, 0 + index: -1 +bar-top + rotate: false + xy: 1081, 955 + size: 27, 36 + split: 9, 10, 9, 10 + orig: 27, 36 + offset: 0, 0 + index: -1 button rotate: false - xy: 129, 21 + xy: 1615, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5152,7 +8640,7 @@ button index: -1 button-down rotate: false - xy: 729, 920 + xy: 1273, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5160,7 +8648,7 @@ button-down index: -1 button-edge-1 rotate: false - xy: 729, 891 + xy: 1311, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5168,7 +8656,7 @@ button-edge-1 index: -1 button-edge-2 rotate: false - xy: 729, 862 + xy: 1349, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5176,7 +8664,7 @@ button-edge-2 index: -1 button-edge-3 rotate: false - xy: 729, 833 + xy: 1387, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5184,7 +8672,7 @@ button-edge-3 index: -1 button-edge-4 rotate: false - xy: 729, 804 + xy: 1425, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5192,7 +8680,7 @@ button-edge-4 index: -1 button-over rotate: false - xy: 729, 775 + xy: 1463, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5200,7 +8688,7 @@ button-over index: -1 button-right rotate: false - xy: 729, 688 + xy: 1577, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5208,7 +8696,7 @@ button-right index: -1 button-right-down rotate: false - xy: 729, 746 + xy: 1501, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5216,7 +8704,7 @@ button-right-down index: -1 button-right-over rotate: false - xy: 729, 717 + xy: 1539, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -5224,7 +8712,7 @@ button-right-over index: -1 button-select rotate: false - xy: 1980, 1855 + xy: 1085, 840 size: 24, 24 split: 4, 4, 4, 4 orig: 24, 24 @@ -5232,42 +8720,66 @@ button-select index: -1 check-off rotate: false - xy: 689, 407 + xy: 1043, 1147 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-on rotate: false - xy: 739, 159 + xy: 1073, 1129 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-on-over rotate: false - xy: 739, 125 + xy: 1103, 1129 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-over rotate: false - xy: 739, 91 + xy: 1081, 1095 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 clear rotate: false - xy: 582, 1990 + xy: 741, 575 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 +content-background + rotate: false + xy: 1729, 1422 + size: 36, 27 + split: 12, 12, 12, 12 + orig: 36, 27 + offset: 0, 0 + index: -1 +content-background-locked + rotate: false + xy: 1653, 1422 + size: 36, 27 + split: 12, 12, 12, 12 + orig: 36, 27 + offset: 0, 0 + index: -1 +content-background-over + rotate: false + xy: 1691, 1422 + size: 36, 27 + split: 12, 12, 12, 12 + orig: 36, 27 + offset: 0, 0 + index: -1 cursor rotate: false - xy: 1947, 1727 + xy: 813, 953 size: 4, 4 orig: 4, 4 offset: 0, 0 @@ -5281,511 +8793,525 @@ discord-banner index: -1 empty-sector rotate: false - xy: 1317, 1691 + xy: 430, 43 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 icon-crafting rotate: false - xy: 229, 54 + xy: 2031, 1729 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-defense rotate: false - xy: 514, 33 + xy: 2031, 1711 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-distribution rotate: false - xy: 819, 1247 + xy: 2031, 1693 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-effect rotate: false - xy: 801, 701 + xy: 2031, 1675 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-liquid rotate: false - xy: 773, 329 + xy: 2031, 1513 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-power rotate: false - xy: 2031, 1655 + xy: 915, 928 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-production rotate: false - xy: 2031, 1637 + xy: 1163, 737 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-turret rotate: false - xy: 75, 3 + xy: 57, 3 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-units rotate: false - xy: 111, 8 + xy: 1137, 639 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-upgrade rotate: false - xy: 147, 3 + xy: 1137, 603 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 controller-cursor rotate: false - xy: 1929, 1715 + xy: 1343, 1302 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-about rotate: false - xy: 535, 341 + xy: 245, 572 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-add rotate: false - xy: 1257, 1735 + xy: 637, 541 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-admin rotate: false - xy: 247, 56 + xy: 637, 525 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-admin-small rotate: false - xy: 660, 1994 + xy: 1265, 1393 size: 6, 6 orig: 6, 6 offset: 0, 0 index: -1 icon-areaDelete rotate: false - xy: 245, 344 + xy: 582, 1990 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow rotate: false - xy: 770, 193 + xy: 770, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-arrow-16 rotate: false - xy: 770, 193 + xy: 770, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-arrow-down rotate: false - xy: 801, 689 + xy: 1223, 1347 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-left rotate: false - xy: 582, 1978 + xy: 787, 325 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-right rotate: false - xy: 813, 689 + xy: 933, 934 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-up rotate: false - xy: 582, 1966 + xy: 75, 9 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-back rotate: false - xy: 788, 193 + xy: 788, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-ban rotate: false - xy: 1083, 1561 + xy: 613, 95 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-break rotate: false - xy: 204, 1759 + xy: 806, 1 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-cancel rotate: false - xy: 636, 1852 + xy: 2031, 1783 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 +icon-cancel-2 + rotate: false + xy: 985, 453 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 icon-chat rotate: false - xy: 502, 5 + xy: 582, 1978 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-check rotate: false - xy: 753, 1147 + xy: 2031, 1765 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 +icon-check-2 + rotate: false + xy: 907, 375 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 icon-copy rotate: false - xy: 1239, 1733 + xy: 2031, 1747 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-cursor rotate: false - xy: 825, 689 + xy: 799, 325 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-dev-builds rotate: false - xy: 1059, 1472 + xy: 1837, 1295 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-discord rotate: false - xy: 773, 313 + xy: 1973, 1261 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-donate rotate: false - xy: 1099, 1561 + xy: 2023, 1252 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-dots rotate: false - xy: 310, 1 + xy: 853, 949 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-editor rotate: false - xy: 326, 1 + xy: 613, 79 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-egg rotate: false - xy: 342, 1 + xy: 2033, 1443 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-elevation rotate: false - xy: 1083, 1577 + xy: 2031, 1657 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-eraser rotate: false - xy: 1041, 1470 + xy: 2031, 1639 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-exit rotate: false - xy: 358, 1 + xy: 2033, 1427 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-file rotate: false - xy: 2021, 1727 + xy: 2031, 1621 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-file-image rotate: false - xy: 21, 3 + xy: 2031, 1603 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-file-text rotate: false - xy: 374, 1 + xy: 2033, 1411 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-fill rotate: false - xy: 222, 1759 + xy: 2031, 1585 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-floppy rotate: false - xy: 390, 1 + xy: 993, 1133 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-floppy-16 rotate: false - xy: 39, 3 + xy: 2031, 1567 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-folder rotate: false - xy: 406, 1 + xy: 1199, 739 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-folder-parent rotate: false - xy: 422, 1 + xy: 1137, 569 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-generated rotate: false - xy: 621, 541 + xy: 729, 225 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 icon-github rotate: false - xy: 438, 1 + xy: 1137, 553 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-google-play rotate: false - xy: 454, 1 + xy: 1137, 537 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-grid rotate: false - xy: 240, 1759 + xy: 2031, 1549 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-hold rotate: false - xy: 594, 1832 + xy: 582, 1966 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-holdDelete rotate: false - xy: 1953, 1789 + xy: 933, 922 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-home rotate: false - xy: 470, 1 + xy: 1137, 521 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-host rotate: false - xy: 486, 1 + xy: 1137, 505 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-info rotate: false - xy: 2035, 1843 - size: 10, 10 - orig: 10, 10 + xy: 1137, 489 + size: 14, 14 + orig: 14, 14 offset: 0, 0 index: -1 icon-itch.io rotate: false - xy: 183, 5 + xy: 2027, 1134 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-item rotate: false - xy: 724, 21 + xy: 1233, 1279 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-items-none rotate: false - xy: 1077, 1415 + xy: 273, 66 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-line rotate: false - xy: 57, 3 + xy: 2031, 1531 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-link rotate: false - xy: 1059, 1456 + xy: 2027, 1118 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-liquid-small rotate: false - xy: 708, 5 + xy: 1245, 1279 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-load rotate: false - xy: 789, 313 + xy: 2027, 1102 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-load-image rotate: false - xy: 791, 330 + xy: 2031, 1495 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-load-map rotate: false - xy: 771, 1147 + xy: 2031, 1477 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-loading rotate: false - xy: 514, 15 + xy: 2031, 1459 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-locked rotate: false - xy: 819, 1229 + xy: 204, 1759 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-logic rotate: false - xy: 606, 1832 + xy: 464, 1 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-map rotate: false - xy: 805, 314 + xy: 2027, 1086 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-menu rotate: false - xy: 2035, 1831 + xy: 476, 1 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-menu-large rotate: false - xy: 819, 701 + xy: 636, 1852 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-missing rotate: false - xy: 618, 1832 + xy: 594, 1832 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -5799,287 +9325,315 @@ icon-mission-background index: -1 icon-mission-battle rotate: false - xy: 2035, 1819 + xy: 1143, 1219 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-mission-defense rotate: false - xy: 2035, 1807 + xy: 1245, 1199 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-mission-done rotate: false - xy: 2035, 1795 + xy: 1823, 1197 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-none rotate: false - xy: 514, 3 + xy: 1959, 1163 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 -icon-nullitem - rotate: false - xy: 2021, 1717 - size: 8, 8 - orig: 8, 8 - offset: 0, 0 - index: -1 icon-paste rotate: false - xy: 2031, 1709 + xy: 1361, 1200 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-pause rotate: false - xy: 526, 1 + xy: 824, 7 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-pencil rotate: false - xy: 2031, 1691 + xy: 975, 1131 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-pencil-small rotate: false - xy: 845, 333 + xy: 2027, 1070 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-pick rotate: false - xy: 2031, 1673 + xy: 853, 965 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-play rotate: false - xy: 538, 1 + xy: 836, 1 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-play-2 rotate: false - xy: 532, 13 + xy: 2027, 1054 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-players rotate: false - xy: 550, 1 + xy: 848, 1 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-power-small rotate: false - xy: 562, 1 + xy: 245, 560 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-quit rotate: false - xy: 548, 13 + xy: 1009, 1131 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-redo rotate: false - xy: 2031, 1619 + xy: 1137, 711 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-refresh rotate: false - xy: 564, 13 + xy: 1025, 1131 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-rename rotate: false - xy: 580, 13 + xy: 1041, 1131 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-resize rotate: false - xy: 2031, 1601 + xy: 21, 3 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-rotate rotate: false - xy: 596, 13 + xy: 1057, 1131 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-rotate-arrow rotate: false - xy: 612, 13 + xy: 1219, 1025 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-rotate-left rotate: false - xy: 628, 13 + xy: 2029, 1395 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-rotate-right rotate: false - xy: 644, 17 + xy: 1219, 1009 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-save rotate: false - xy: 644, 1 + xy: 1218, 993 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-save-image rotate: false - xy: 809, 330 + xy: 222, 1759 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-save-map rotate: false - xy: 827, 331 + xy: 1181, 737 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-settings rotate: false - xy: 574, 1 + xy: 1231, 1131 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 +icon-spray + rotate: false + xy: 1137, 693 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 icon-terrain rotate: false - xy: 837, 1237 + xy: 39, 3 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-tools rotate: false - xy: 660, 17 + xy: 899, 306 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-touch rotate: false - xy: 586, 1 + xy: 899, 198 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-touchDelete rotate: false - xy: 598, 1 + xy: 606, 1832 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-trash rotate: false - xy: 660, 1 + xy: 899, 290 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-trash-16 rotate: false - xy: 855, 1237 + xy: 240, 1759 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 +icon-tree + rotate: false + xy: 1137, 675 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +icon-tree-locked + rotate: false + xy: 804, 19 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 icon-trello rotate: false - xy: 676, 17 + xy: 899, 274 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-tutorial rotate: false - xy: 676, 1 + xy: 899, 258 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-undo rotate: false - xy: 93, 8 + xy: 1137, 657 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-unlocked rotate: false - xy: 129, 3 + xy: 1137, 621 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-unlocks rotate: false - xy: 692, 17 + xy: 899, 242 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-wiki rotate: false - xy: 692, 1 + xy: 899, 226 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 +icon-zone + rotate: false + xy: 933, 401 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +icon-zone-locked + rotate: false + xy: 229, 66 + size: 42, 42 + orig: 42, 42 + offset: 0, 0 + index: -1 icon-zoom rotate: false - xy: 165, 3 + xy: 1137, 585 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-zoom-small rotate: false - xy: 708, 17 + xy: 899, 210 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -6093,7 +9647,7 @@ info-banner index: -1 inventory rotate: false - xy: 768, 49 + xy: 1114, 921 size: 24, 40 split: 10, 10, 10, 14 orig: 24, 40 @@ -6108,7 +9662,7 @@ logotext index: -1 pane rotate: false - xy: 721, 583 + xy: 1881, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -6116,7 +9670,7 @@ pane index: -1 pane-2 rotate: false - xy: 167, 21 + xy: 1843, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -6124,7 +9678,7 @@ pane-2 index: -1 scroll rotate: false - xy: 768, 12 + xy: 1111, 790 size: 24, 35 split: 10, 10, 6, 5 orig: 24, 35 @@ -6132,7 +9686,7 @@ scroll index: -1 scroll-horizontal rotate: false - xy: 205, 24 + xy: 1311, 1396 size: 35, 24 split: 6, 5, 10, 10 orig: 35, 24 @@ -6148,7 +9702,7 @@ scroll-knob-horizontal-black index: -1 scroll-knob-vertical-black rotate: false - xy: 2021, 1745 + xy: 1111, 827 size: 24, 40 split: 10, 10, 6, 10 orig: 24, 40 @@ -6156,63 +9710,63 @@ scroll-knob-vertical-black index: -1 sector-edge rotate: false - xy: 671, 237 + xy: 949, 751 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 sector-select rotate: false - xy: 671, 203 + xy: 915, 683 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 selection rotate: false - xy: 2046, 2046 + xy: 873, 322 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 slider rotate: false - xy: 532, 41 + xy: 1137, 859 size: 1, 8 orig: 1, 8 offset: 0, 0 index: -1 slider-knob rotate: false - xy: 739, 273 + xy: 813, 93 size: 29, 38 orig: 29, 38 offset: 0, 0 index: -1 slider-knob-down rotate: false - xy: 739, 233 + xy: 813, 53 size: 29, 38 orig: 29, 38 offset: 0, 0 index: -1 slider-knob-over rotate: false - xy: 739, 193 + xy: 813, 53 size: 29, 38 orig: 29, 38 offset: 0, 0 index: -1 slider-vertical rotate: false - xy: 1375, 1726 + xy: 1311, 1393 size: 8, 1 orig: 8, 1 offset: 0, 0 index: -1 underline rotate: false - xy: 721, 449 + xy: 1273, 1393 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -6220,7 +9774,7 @@ underline index: -1 underline-2 rotate: false - xy: 721, 478 + xy: 1995, 1422 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -6228,14 +9782,14 @@ underline-2 index: -1 white rotate: false - xy: 1048, 1522 + xy: 2044, 2044 size: 3, 3 orig: 3, 3 offset: 0, 0 index: -1 window-empty rotate: false - xy: 739, 28 + xy: 1085, 892 size: 27, 61 split: 8, 8, 44, 11 orig: 27, 61 @@ -6243,203 +9797,182 @@ window-empty index: -1 alpha-drone rotate: false - xy: 1417, 1801 + xy: 653, 525 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dagger rotate: false - xy: 1867, 1801 + xy: 429, 161 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dagger-base rotate: false - xy: 1917, 1801 + xy: 479, 211 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dagger-leg rotate: false - xy: 653, 1141 + xy: 579, 311 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 fortress rotate: false - xy: 719, 1785 + xy: 1188, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 fortress-base rotate: false - xy: 653, 1653 + xy: 1254, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 titan-base rotate: false - xy: 653, 1653 + xy: 1254, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 fortress-leg rotate: false - xy: 719, 1719 + xy: 1320, 1851 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 ghoul rotate: false - xy: 555, 997 - size: 72, 72 - orig: 72, 72 - offset: 0, 0 - index: -1 -unit-icon-ghoul - rotate: false - xy: 555, 997 + xy: 742, 1975 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 phantom rotate: false - xy: 917, 1397 - size: 56, 56 - orig: 56, 56 - offset: 0, 0 - index: -1 -unit-icon-phantom - rotate: false - xy: 917, 1397 + xy: 1115, 1331 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 power-cell rotate: false - xy: 983, 1464 + xy: 653, 803 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 revenant rotate: false - xy: 131, 344 - size: 112, 112 - orig: 112, 112 - offset: 0, 0 - index: -1 -unit-icon-revenant - rotate: false - xy: 131, 344 + xy: 131, 474 size: 112, 112 orig: 112, 112 offset: 0, 0 index: -1 spirit rotate: false - xy: 671, 641 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -unit-icon-spirit - rotate: false - xy: 671, 641 + xy: 1781, 1601 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 titan rotate: false - xy: 719, 1323 + xy: 719, 1117 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 titan-leg rotate: false - xy: 785, 1389 + xy: 785, 1183 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 +wraith + rotate: false + xy: 1173, 1347 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 artillery-equip rotate: false - xy: 1617, 1801 + xy: 229, 260 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 blaster-equip rotate: false - xy: 1717, 1801 + xy: 379, 311 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 bomber-equip rotate: false - xy: 1767, 1801 + xy: 279, 161 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 missiles-equip rotate: false - xy: 1767, 1801 + xy: 279, 161 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 chain-blaster-equip rotate: false - xy: 1817, 1801 + xy: 429, 311 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 flakgun-equip rotate: false - xy: 629, 791 + xy: 1107, 1231 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 flamethrower-equip rotate: false - xy: 629, 741 + xy: 737, 475 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 heal-blaster-equip rotate: false - xy: 621, 641 + xy: 679, 225 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 shockgun-equip rotate: false - xy: 679, 791 + xy: 1831, 1751 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 swarmer-equip rotate: false - xy: 671, 541 + xy: 1781, 1551 size: 48, 48 orig: 48, 48 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index a01b69b020..911b882020 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/assets/ui/uiskin.json b/core/assets/sprites/uiskin.json similarity index 95% rename from core/assets/ui/uiskin.json rename to core/assets/sprites/uiskin.json index c2420b9fcb..3006ee32f2 100644 --- a/core/assets/ui/uiskin.json +++ b/core/assets/sprites/uiskin.json @@ -24,6 +24,7 @@ ButtonStyle: { }, TextButtonStyle: { default: {over: button-over, disabled: button, font: default-font, fontColor: white, disabledFontColor: gray, down: button-down, up: button}, + node: {disabled: content-background, font: default-font, fontColor: white, disabledFontColor: gray, up: content-background, over: content-background-over}, right: {over: button-right-over, font: default-font, fontColor: white, disabledFontColor: gray, down: button-right-down, up: button-right}, wave: {font: default-font, fontColor: white, disabledFontColor: gray, up: button-edge-4}, clear: {over: flat-over, font: default-font, fontColor: white, disabledFontColor: gray, down: flat-over, up: flat}, @@ -37,6 +38,7 @@ TextButtonStyle: { }, ImageButtonStyle: { default: {down: button-down, up: button, over: button-over, imageDisabledColor: gray, imageUpColor: white }, + node: {up: content-background, over: content-background-over}, right: {over: button-right-over, down: button-right-down, up: button-right}, empty: { imageDownColor: accent, imageUpColor: white}, emptytoggle: {imageCheckedColor: white, imageDownColor: white, imageUpColor: gray}, diff --git a/core/assets/ui/title.fnt b/core/assets/ui/title.fnt deleted file mode 100644 index ef571ca7e7..0000000000 --- a/core/assets/ui/title.fnt +++ /dev/null @@ -1,57 +0,0 @@ -info face="Title" size=16 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=0,0 -common lineHeight=14 base=0 scaleW=512 scaleH=512 pages=1 packed=0 -page id=0 file="title.png" -chars count=53 -char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=0 -char id=97 x=1 y=0 width=9 height=12 xoffset=0 yoffset=-12 xadvance=8 page=0 chnl=0 -char id=65 x=1 y=0 width=9 height=12 xoffset=0 yoffset=-12 xadvance=8 page=0 chnl=0 -char id=98 x=14 y=0 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=66 x=14 y=0 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=99 x=26 y=0 width=7 height=12 xoffset=0 yoffset=-12 xadvance=6 page=0 chnl=0 -char id=67 x=26 y=0 width=7 height=12 xoffset=0 yoffset=-12 xadvance=6 page=0 chnl=0 -char id=100 x=39 y=0 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=68 x=39 y=0 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=101 x=50 y=0 width=7 height=12 xoffset=0 yoffset=-12 xadvance=6 page=0 chnl=0 -char id=69 x=50 y=0 width=7 height=12 xoffset=0 yoffset=-12 xadvance=6 page=0 chnl=0 -char id=102 x=63 y=0 width=7 height=12 xoffset=0 yoffset=-12 xadvance=6 page=0 chnl=0 -char id=70 x=63 y=0 width=7 height=12 xoffset=0 yoffset=-12 xadvance=6 page=0 chnl=0 -char id=103 x=74 y=0 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=71 x=74 y=0 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=104 x=86 y=0 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=72 x=86 y=0 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=105 x=100 y=0 width=4 height=12 xoffset=0 yoffset=-12 xadvance=3 page=0 chnl=0 -char id=73 x=100 y=0 width=4 height=12 xoffset=0 yoffset=-12 xadvance=3 page=0 chnl=0 -char id=106 x=2 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=74 x=2 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=107 x=14 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=75 x=14 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=108 x=28 y=12 width=7 height=12 xoffset=0 yoffset=-12 xadvance=6 page=0 chnl=0 -char id=76 x=28 y=12 width=7 height=12 xoffset=0 yoffset=-12 xadvance=6 page=0 chnl=0 -char id=109 x=38 y=12 width=10 height=12 xoffset=0 yoffset=-12 xadvance=9 page=0 chnl=0 -char id=77 x=38 y=12 width=10 height=12 xoffset=0 yoffset=-12 xadvance=9 page=0 chnl=0 -char id=110 x=50 y=12 width=9 height=12 xoffset=0 yoffset=-12 xadvance=8 page=0 chnl=0 -char id=78 x=50 y=12 width=9 height=12 xoffset=0 yoffset=-12 xadvance=8 page=0 chnl=0 -char id=111 x=63 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=79 x=63 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=112 x=75 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=80 x=75 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=113 x=87 y=12 width=9 height=12 xoffset=0 yoffset=-12 xadvance=8 page=0 chnl=0 -char id=81 x=87 y=12 width=9 height=12 xoffset=0 yoffset=-12 xadvance=8 page=0 chnl=0 -char id=114 x=99 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=82 x=99 y=12 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=115 x=2 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=83 x=2 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=116 x=14 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=84 x=14 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=117 x=26 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=85 x=26 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=118 x=37 y=24 width=9 height=12 xoffset=0 yoffset=-12 xadvance=8 page=0 chnl=0 -char id=86 x=37 y=24 width=9 height=12 xoffset=0 yoffset=-12 xadvance=8 page=0 chnl=0 -char id=119 x=50 y=24 width=10 height=12 xoffset=0 yoffset=-12 xadvance=9 page=0 chnl=0 -char id=87 x=50 y=24 width=10 height=12 xoffset=0 yoffset=-12 xadvance=9 page=0 chnl=0 -char id=120 x=62 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=88 x=62 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=121 x=75 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=89 x=75 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=122 x=86 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 -char id=90 x=86 y=24 width=8 height=12 xoffset=0 yoffset=-12 xadvance=7 page=0 chnl=0 diff --git a/core/assets/ui/title.png b/core/assets/ui/title.png deleted file mode 100644 index 0141415b7c..0000000000 Binary files a/core/assets/ui/title.png and /dev/null differ diff --git a/core/assets/ui/uiskin.atlas b/core/assets/ui/uiskin.atlas deleted file mode 100644 index 9926e77897..0000000000 --- a/core/assets/ui/uiskin.atlas +++ /dev/null @@ -1,770 +0,0 @@ - -uiskin.png -size: 512,128 -format: RGBA8888 -filter: Nearest,Nearest -repeat: none -blank - rotate: false - xy: 202, 14 - size: 8, 8 - orig: 8, 8 - offset: 0, 0 - index: -1 -border - rotate: false - xy: 360, 35 - size: 12, 12 - split: 4, 4, 4, 4 - orig: 12, 12 - offset: 0, 0 - index: -1 -border-circle - rotate: false - xy: 418, 35 - size: 28, 28 - orig: 28, 28 - offset: 0, 0 - index: -1 -border-circle-error - rotate: false - xy: 82, 10 - size: 28, 28 - orig: 28, 28 - offset: 0, 0 - index: -1 -border-dark-blue - rotate: false - xy: 500, 42 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -border-error - rotate: false - xy: 37, 7 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -border-white - rotate: false - xy: 58, 2 - size: 12, 12 - split: 4, 4, 4, 4 - orig: 12, 12 - offset: 0, 0 - index: -1 -button - rotate: false - xy: 212, 2 - size: 24, 40 - split: 10, 10, 6, 10 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-blue - rotate: false - xy: 82, 40 - size: 24, 40 - split: 10, 10, 10, 8 - pad: 8, 8, 2, 2 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-blue-down - rotate: false - xy: 448, 40 - size: 24, 40 - split: 10, 10, 10, 8 - pad: 8, 8, 2, 2 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-blue-over - rotate: false - xy: 474, 40 - size: 24, 40 - split: 10, 10, 10, 8 - pad: 8, 8, 2, 2 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-down - rotate: false - xy: 108, 40 - size: 24, 40 - split: 10, 10, 6, 10 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-over - rotate: false - xy: 108, 40 - size: 24, 40 - split: 10, 10, 6, 10 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-gray - rotate: false - xy: 160, 40 - size: 24, 40 - split: 10, 10, 10, 8 - pad: 8, 8, 2, 2 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-gray-over - rotate: false - xy: 134, 40 - size: 24, 40 - split: 10, 10, 10, 8 - pad: 8, 8, 2, 2 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-map - rotate: false - xy: 212, 44 - size: 24, 40 - split: 10, 10, 5, 10 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-map-down - rotate: false - xy: 186, 40 - size: 24, 40 - split: 10, 10, 5, 10 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-map-over - rotate: false - xy: 186, 40 - size: 24, 40 - split: 10, 10, 5, 10 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-red - rotate: false - xy: 238, 44 - size: 24, 40 - split: 10, 10, 10, 8 - pad: 8, 8, 2, 2 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-select - rotate: false - xy: 330, 39 - size: 24, 24 - split: 4, 4, 4, 4 - orig: 24, 24 - offset: 0, 0 - index: -1 -button-window-bg - rotate: false - xy: 264, 44 - size: 24, 40 - split: 10, 10, 10, 8 - pad: 8, 8, 2, 2 - orig: 24, 40 - offset: 0, 0 - index: -1 -button-window-over - rotate: false - xy: 290, 44 - size: 24, 40 - split: 10, 10, 10, 8 - pad: 8, 8, 2, 2 - orig: 24, 40 - offset: 0, 0 - index: -1 -check-off - rotate: false - xy: 474, 6 - size: 28, 32 - orig: 28, 32 - offset: 0, 0 - index: -1 -check-on - rotate: false - xy: 238, 10 - size: 28, 32 - orig: 28, 32 - offset: 0, 0 - index: -1 -check-over - rotate: false - xy: 268, 10 - size: 28, 32 - orig: 28, 32 - offset: 0, 0 - index: -1 -clear - rotate: false - xy: 500, 50 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -color-picker-bar-selector - rotate: false - xy: 495, 98 - size: 14, 28 - orig: 14, 28 - offset: 0, 0 - index: -1 -color-picker-cross - rotate: false - xy: 360, 23 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -color-picker-selector-horizontal - rotate: false - xy: 495, 95 - size: 6, 1 - orig: 6, 1 - offset: 0, 0 - index: -1 -color-picker-selector-vertical - rotate: false - xy: 72, 2 - size: 1, 6 - orig: 1, 6 - offset: 0, 0 - index: -1 -cursor - rotate: false - xy: 316, 44 - size: 4, 4 - orig: 4, 4 - offset: 0, 0 - index: -1 -cursor-normal - rotate: false - xy: 374, 37 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -default-pane - rotate: false - xy: 389, 37 - size: 5, 3 - split: 1, 1, 1, 1 - orig: 5, 3 - offset: 0, 0 - index: -1 -default-pane-no-border - rotate: false - xy: 75, 2 - size: 1, 1 - split: 0, 0, 0, 0 - orig: 1, 1 - offset: 0, 0 - index: -1 -default-select - rotate: false - xy: 2, 12 - size: 54, 48 - split: 8, 32, 0, 48 - orig: 54, 48 - offset: 0, 0 - index: -1 -default-select-selection - rotate: false - xy: 37, 2 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -grey - rotate: false - xy: 78, 2 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -menu-bg - rotate: false - xy: 78, 2 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -icon-cancel - rotate: false - xy: 356, 49 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-check - rotate: false - xy: 372, 49 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-close - rotate: false - xy: 205, 86 - size: 40, 40 - orig: 40, 40 - offset: 0, 0 - index: -1 -icon-close-down - rotate: false - xy: 247, 86 - size: 40, 40 - orig: 40, 40 - offset: 0, 0 - index: -1 -icon-close-over - rotate: false - xy: 289, 86 - size: 40, 40 - orig: 40, 40 - offset: 0, 0 - index: -1 -icon-cursor - rotate: false - xy: 332, 11 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-defense - rotate: false - xy: 344, 11 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-distribution - rotate: false - xy: 356, 11 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-menu - rotate: false - xy: 368, 11 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-pause - rotate: false - xy: 372, 23 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-play - rotate: false - xy: 380, 11 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-production - rotate: false - xy: 384, 23 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-rotate - rotate: false - xy: 328, 23 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-rotate-arrow - rotate: false - xy: 344, 23 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -icon-settings - rotate: false - xy: 396, 30 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -icon-touch - rotate: false - xy: 396, 18 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -list-selection - rotate: false - xy: 386, 36 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -logotext - rotate: false - xy: 68, 105 - size: 89, 21 - orig: 89, 21 - offset: 0, 0 - index: -1 -logotext-gray - rotate: false - xy: 68, 82 - size: 89, 21 - orig: 89, 21 - offset: 0, 0 - index: -1 -padded-list-selection - rotate: false - xy: 500, 47 - size: 10, 1 - split: 4, 4, 0, 1 - orig: 10, 1 - offset: 0, 0 - index: -1 -pane - rotate: false - xy: 448, 2 - size: 24, 36 - split: 10, 10, 5, 5 - orig: 24, 36 - offset: 0, 0 - index: -1 -progressbar - rotate: false - xy: 324, 52 - size: 1, 32 - orig: 1, 32 - offset: 0, 0 - index: -1 -progressbar-filled - rotate: false - xy: 327, 52 - size: 1, 32 - orig: 1, 32 - offset: 0, 0 - index: -1 -progressbar-filled-vertical - rotate: false - xy: 474, 3 - size: 32, 1 - orig: 32, 1 - offset: 0, 0 - index: -1 -progressbar-vertical - rotate: false - xy: 298, 11 - size: 32, 1 - orig: 32, 1 - offset: 0, 0 - index: -1 -radio-off - rotate: false - xy: 112, 10 - size: 28, 28 - orig: 28, 28 - offset: 0, 0 - index: -1 -radio-on - rotate: false - xy: 142, 10 - size: 28, 28 - orig: 28, 28 - offset: 0, 0 - index: -1 -scroll - rotate: false - xy: 274, 2 - size: 34, 6 - split: 4, 4, 2, 2 - orig: 34, 6 - offset: 0, 0 - index: -1 -scroll-horizontal - rotate: false - xy: 316, 50 - size: 6, 34 - split: 2, 2, 0, 34 - pad: 0, 5, 5, 4 - orig: 6, 34 - offset: 0, 0 - index: -1 -scroll-knob-horizontal - rotate: false - xy: 504, 62 - size: 6, 34 - split: 2, 2, 0, 34 - pad: 0, 5, 13, 12 - orig: 6, 34 - offset: 0, 0 - index: -1 -scroll-knob-vertical - rotate: false - xy: 238, 2 - size: 34, 6 - split: 12, 12, 2, 2 - orig: 34, 6 - offset: 0, 0 - index: -1 -select-box-list-bg - rotate: false - xy: 205, 83 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -window-bg - rotate: false - xy: 205, 83 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -select-down - rotate: false - xy: 2, 2 - size: 14, 8 - orig: 14, 8 - offset: 0, 0 - index: -1 -select-up - rotate: false - xy: 18, 2 - size: 14, 8 - orig: 14, 8 - offset: 0, 0 - index: -1 -selection - rotate: false - xy: 328, 20 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -separator - rotate: false - xy: 404, 15 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -tree-over - rotate: false - xy: 404, 15 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -separator-menu - rotate: false - xy: 392, 20 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -slider - rotate: false - xy: 386, 39 - size: 1, 8 - orig: 1, 8 - offset: 0, 0 - index: -1 -slider-knob - rotate: false - xy: 447, 82 - size: 22, 44 - orig: 22, 44 - offset: 0, 0 - index: -1 -slider-knob-disabled - rotate: false - xy: 471, 82 - size: 22, 44 - orig: 22, 44 - offset: 0, 0 - index: -1 -slider-knob-down - rotate: false - xy: 58, 16 - size: 22, 44 - orig: 22, 44 - offset: 0, 0 - index: -1 -slider-knob-over - rotate: false - xy: 58, 16 - size: 22, 44 - orig: 22, 44 - offset: 0, 0 - index: -1 -slider-vertical - rotate: false - xy: 72, 13 - size: 8, 1 - orig: 8, 1 - offset: 0, 0 - index: -1 -slot - rotate: false - xy: 2, 62 - size: 64, 64 - split: 4, 8, 8, 4 - orig: 64, 64 - offset: 0, 0 - index: -1 -splitpane - rotate: false - xy: 202, 11 - size: 8, 1 - orig: 8, 1 - offset: 0, 0 - index: -1 -splitpane-over - rotate: false - xy: 72, 10 - size: 8, 1 - orig: 8, 1 - offset: 0, 0 - index: -1 -splitpane-vertical - rotate: false - xy: 34, 2 - size: 1, 8 - orig: 1, 8 - offset: 0, 0 - index: -1 -splitpane-vertical-over - rotate: false - xy: 356, 39 - size: 1, 8 - orig: 1, 8 - offset: 0, 0 - index: -1 -sub-menu - rotate: false - xy: 202, 24 - size: 8, 14 - orig: 8, 14 - offset: 0, 0 - index: -1 -textfield - rotate: false - xy: 298, 14 - size: 28, 28 - split: 6, 6, 6, 6 - orig: 28, 28 - offset: 0, 0 - index: -1 -textfield-over - rotate: false - xy: 172, 10 - size: 28, 28 - split: 2, 2, 2, 2 - orig: 28, 28 - offset: 0, 0 - index: -1 -tooltip-bg - rotate: false - xy: 408, 37 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -touchpad-knob - rotate: false - xy: 159, 82 - size: 44, 44 - orig: 44, 44 - offset: 0, 0 - index: -1 -tree-minus - rotate: false - xy: 392, 6 - size: 10, 10 - orig: 10, 10 - offset: 0, 0 - index: -1 -tree-plus - rotate: false - xy: 68, 64 - size: 12, 16 - orig: 12, 16 - offset: 0, 0 - index: -1 -tree-selection - rotate: false - xy: 413, 37 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -white - rotate: false - xy: 75, 5 - size: 3, 3 - orig: 3, 3 - offset: 0, 0 - index: -1 -window - rotate: false - xy: 418, 65 - size: 27, 61 - split: 8, 8, 44, 11 - orig: 27, 61 - offset: 0, 0 - index: -1 -window-border-bg - rotate: false - xy: 495, 90 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -window-gray - rotate: false - xy: 331, 65 - size: 27, 61 - split: 5, 4, 52, 4 - orig: 27, 61 - offset: 0, 0 - index: -1 -window-noborder - rotate: false - xy: 360, 65 - size: 27, 61 - split: 5, 4, 53, 3 - orig: 27, 61 - offset: 0, 0 - index: -1 -window-resizable - rotate: false - xy: 389, 42 - size: 27, 84 - split: 3, 19, 2, 20 - pad: 5, 5, 50, 7 - orig: 27, 84 - offset: 0, 0 - index: -1 diff --git a/core/src/io/anuke/mindustry/ai/BlockIndexer.java b/core/src/io/anuke/mindustry/ai/BlockIndexer.java index 6e96b6cb36..6f5e840dcf 100644 --- a/core/src/io/anuke/mindustry/ai/BlockIndexer.java +++ b/core/src/io/anuke/mindustry/ai/BlockIndexer.java @@ -205,7 +205,7 @@ public class BlockIndexer{ for(int x = Math.max(0, tile.x - oreQuadrantSize / 2); x < tile.x + oreQuadrantSize / 2 && x < world.width(); x++){ for(int y = Math.max(0, tile.y - oreQuadrantSize / 2); y < tile.y + oreQuadrantSize / 2 && y < world.height(); y++){ Tile res = world.tile(x, y); - if(res.block() == Blocks.air && res.floor().drops != null && res.floor().drops.item == item){ + if(res.block() == Blocks.air && res.floor().itemDrop == item){ return res; } } @@ -243,9 +243,9 @@ public class BlockIndexer{ for(int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++){ for(int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){ Tile result = world.tile(x, y); - if( result == null || result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue; + if( result == null || result.floor().itemDrop == null || !scanOres.contains(result.floor().itemDrop)) continue; - itemSet.add(result.block().drops.item); + itemSet.add(result.floor().itemDrop); } } @@ -322,8 +322,8 @@ public class BlockIndexer{ Tile tile = world.tile(x, y); //add position of quadrant to list when an ore is found - if(tile.floor().drops != null && scanOres.contains(tile.floor().drops.item) && tile.block() == Blocks.air){ - ores.get(tile.floor().drops.item).add(world.tile( + if(tile.floor().itemDrop != null && scanOres.contains(tile.floor().itemDrop) && tile.block() == Blocks.air){ + ores.get(tile.floor().itemDrop).add(world.tile( //make sure to clamp quadrant middle position, since it might go off bounds Mathf.clamp(qx * oreQuadrantSize + oreQuadrantSize / 2, 0, world.width() - 1), Mathf.clamp(qy * oreQuadrantSize + oreQuadrantSize / 2, 0, world.height() - 1))); diff --git a/core/src/io/anuke/mindustry/ai/Pathfinder.java b/core/src/io/anuke/mindustry/ai/Pathfinder.java index dc44315bb1..2f27133d89 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfinder.java +++ b/core/src/io/anuke/mindustry/ai/Pathfinder.java @@ -182,8 +182,6 @@ public class Pathfinder{ createFor(team); } } - - world.spawner.checkAllQuadrants(); } class PathData{ diff --git a/core/src/io/anuke/mindustry/ai/WaveSpawner.java b/core/src/io/anuke/mindustry/ai/WaveSpawner.java index 969a9befaa..ec098dcf8d 100644 --- a/core/src/io/anuke/mindustry/ai/WaveSpawner.java +++ b/core/src/io/anuke/mindustry/ai/WaveSpawner.java @@ -2,32 +2,18 @@ package io.anuke.mindustry.ai; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; -import io.anuke.arc.collection.GridBits; +import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Structs; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.Squad; import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.game.SpawnGroup; -import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.game.Waves; -import io.anuke.mindustry.world.Tile; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; import static io.anuke.mindustry.Vars.*; public class WaveSpawner{ - private static final int quadsize = 6; - - private GridBits quadrants; - private Array groups; - private boolean dynamicSpawn; - private Array flySpawns = new Array<>(); private Array groundSpawns = new Array<>(); @@ -35,273 +21,76 @@ public class WaveSpawner{ Events.on(WorldLoadEvent.class, e -> reset()); } - public void write(DataOutput output) throws IOException{ - output.writeShort(flySpawns.size); - for(FlyerSpawn spawn : flySpawns){ - output.writeFloat(spawn.angle); - } - - output.writeShort(groundSpawns.size); - for(GroundSpawn spawn : groundSpawns){ - output.writeShort((short) spawn.x); - output.writeShort((short) spawn.y); - } - } - - public void read(DataInput input) throws IOException{ - short flya = input.readShort(); - - for(int i = 0; i < flya; i++){ - FlyerSpawn spawn = new FlyerSpawn(); - spawn.angle = input.readFloat(); - flySpawns.add(spawn); - } - - short grounda = input.readShort(); - for(int i = 0; i < grounda; i++){ - GroundSpawn spawn = new GroundSpawn(); - spawn.x = input.readShort(); - spawn.y = input.readShort(); - groundSpawns.add(spawn); - } - } - public void spawnEnemies(){ - int flyGroups = 0; - int groundGroups = 0; - - //count total subgroups spawned by flying/group types - for(SpawnGroup group : groups){ - int amount = group.getGroupsSpawned(state.wave); - if(group.type.isFlying){ - flyGroups += amount; - }else if(dynamicSpawn){ - groundGroups += amount; - } - } - - int addGround = groundGroups - groundSpawns.size, addFly = flyGroups - flySpawns.size; - - //add extra groups if the total exceeds it - if(dynamicSpawn){ - for(int i = 0; i < addGround; i++){ - GroundSpawn spawn = new GroundSpawn(); - findLocation(spawn); - groundSpawns.add(spawn); - } - } - - for(int i = 0; i < addFly; i++){ - FlyerSpawn spawn = new FlyerSpawn(); - findLocation(spawn); - flySpawns.add(spawn); - } - - //store index of last used fly/ground spawn locations - int flyCount = 0, groundCount = 0; for(SpawnGroup group : groups){ - int groups = group.getGroupsSpawned(state.wave); int spawned = group.getUnitsSpawned(state.wave); - for(int i = 0; i < groups; i++){ - Squad squad = new Squad(); - float spawnX, spawnY; - float spread; - - if(!group.type.isFlying && groundCount >= groundSpawns.size) continue; - - if(group.type.isFlying){ - FlyerSpawn spawn = flySpawns.get(flyCount); + float spawnX, spawnY; + float spread; + if(group.type.isFlying){ + for(FlyerSpawn spawn : flySpawns){ + Squad squad = new Squad(); float margin = 40f; //how far away from the edge flying units spawn - spawnX = world.width() * tilesize / 2f + sqrwavex(spawn.angle) * (world.width() / 2f * tilesize + margin); - spawnY = world.height() * tilesize / 2f + sqrwavey(spawn.angle) * (world.height() / 2f * tilesize + margin); + float trns = (world.width() + world.height()) * tilesize; + spawnX = Mathf.clamp(world.width() * tilesize / 2f + Angles.trnsx(spawn.angle, trns), -margin, world.width() * tilesize + margin); + spawnY = Mathf.clamp(world.height() * tilesize / 2f + Angles.trnsy(spawn.angle, trns), -margin, world.height() * tilesize + margin); spread = margin / 1.5f; - flyCount++; - }else{ //make sure it works for non-dynamic spawns - GroundSpawn spawn = groundSpawns.get(groundCount); - - if(dynamicSpawn){ - checkQuadrant(spawn.x, spawn.y); - if(!getQuad(spawn.x, spawn.y)){ - findLocation(spawn); - } + for(int i = 0; i < spawned; i++){ + BaseUnit unit = group.createUnit(waveTeam); + unit.setWave(); + unit.setSquad(squad); + unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread)); + unit.add(); } - - spawnX = spawn.x * quadsize * tilesize + quadsize * tilesize / 2f; - spawnY = spawn.y * quadsize * tilesize + quadsize * tilesize / 2f; - spread = quadsize * tilesize / 3f; - - groundCount++; } + }else{ + for(GroundSpawn spawn : groundSpawns){ + Squad squad = new Squad(); + spawnX = spawn.x * tilesize; + spawnY = spawn.y * tilesize; + spread = tilesize; - for(int j = 0; j < spawned; j++){ - BaseUnit unit = group.createUnit(Team.red); - unit.setWave(); - unit.setSquad(squad); - unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread)); - unit.add(); - } - } - } - } - - public void checkAllQuadrants(){ - for(int x = 0; x < quadWidth(); x++){ - for(int y = 0; y < quadHeight(); y++){ - checkQuadrant(x, y); - } - } - } - - private void checkQuadrant(int quadx, int quady){ - setQuad(quadx, quady, true); - - outer: - for(int x = quadx * quadsize; x < world.width() && x < (quadx + 1) * quadsize; x++){ - for(int y = quady * quadsize; y < world.height() && y < (quady + 1) * quadsize; y++){ - Tile tile = world.tile(x, y); - - if(tile == null || tile.solid() || tile.getTeam() == defaultTeam || world.pathfinder.getValueforTeam(Team.red, x, y) == Float.MAX_VALUE || tile.floor().isLiquid){ - setQuad(quadx, quady, false); - break outer; + for(int i = 0; i < spawned; i++){ + BaseUnit unit = group.createUnit(waveTeam); + unit.setWave(); + unit.setSquad(squad); + unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread)); + unit.add(); + } } } } } private void reset(){ - dynamicSpawn = false; flySpawns.clear(); groundSpawns.clear(); - quadrants = new GridBits(quadWidth(), quadHeight()); - groups = Waves.getSpawns(); - - dynamicSpawn = true; + groups = state.rules.spawns; for(int x = 0; x < world.width(); x++){ for(int y = 0; y < world.height(); y++){ if(world.tile(x, y).block() == Blocks.spawn){ - dynamicSpawn = false; GroundSpawn spawn = new GroundSpawn(); - spawn.x = x/quadsize; - spawn.y = y/quadsize; + spawn.x = x; + spawn.y = y; groundSpawns.add(spawn); + + FlyerSpawn fspawn = new FlyerSpawn(); + fspawn.angle = Angles.angle(world.width()/2f, world.height()/2f, x, y); + flySpawns.add(fspawn); } } } } - private boolean getQuad(int quadx, int quady){ - return quadrants.get(quadx, quady); - } - - private void setQuad(int quadx, int quady, boolean valid){ - if(quadrants == null){ - quadrants = new GridBits(quadWidth(), quadHeight()); - } - - if(!Structs.inBounds(quadx, quady, quadWidth(), quadHeight())){ - return; - } - - quadrants.set(quadx, quady, valid); - } - - //TODO instead of randomly scattering locations around the map, find spawns close to each other - private void findLocation(GroundSpawn spawn){ - spawn.x = Mathf.random(quadWidth()-1); - spawn.y = Mathf.random(quadHeight()-1); - - int shellWidth = quadWidth() * 2 + quadHeight() * 2 * 6; - shellWidth = Math.min(quadWidth() * quadHeight() / 4, shellWidth); - - traverseSpiral(quadWidth(), quadHeight(), Mathf.random(shellWidth), (x, y) -> { - if(getQuad(x, y)){ - spawn.x = x; - spawn.y = y; - return true; - } - - return false; - }); - } - - //TODO instead of randomly scattering locations around the map, find spawns close to each other - private void findLocation(FlyerSpawn spawn){ - spawn.angle = Mathf.random(360f); - } - - private int quadWidth(){ - return Mathf.ceil(world.width() / (float) quadsize); - } - - private int quadHeight(){ - return Mathf.ceil(world.height() / (float) quadsize); - } - private class FlyerSpawn{ - //square angle float angle; } private class GroundSpawn{ - //quadrant spawn coordinates int x, y; } - - //utility methods - - float sqrwavex(float degrees){ - degrees = Mathf.mod(degrees, 360f); - if(degrees < 45){ - return 1; - }else if(degrees < 135){ - return 1f - (degrees - 45f) / 90f; - }else if(degrees < 225){ - return -1f; - }else if(degrees < 315){ - return (degrees - 225) / 90f; - }else{ - return 1f; - } - } - - float sqrwavey(float degrees){ - return sqrwavex(degrees + 90f); - } - - void traverseSpiral(int width, int height, int offset, SpiralTraverser con){ - int directionIdx = 0; - int curRow = 0, curCol = 0; - for(int i = 0; i < height * width; i++){ - - if(i >= offset && con.accept(curCol, curRow)) break; - - int same = 1, row = curRow, col = curCol; - if(row > height - 1 - row){ - row = height - 1 - row; - same = 0; - } - if(col >= width - 1 - col){ - col = width - 1 - col; - same = 0; - } - row -= same; - - if(row == col){ - directionIdx = (directionIdx + 1) % 4; - } - curRow += directions[directionIdx][0]; - curCol += directions[directionIdx][1]; - } - } - - interface SpiralTraverser{ - boolean accept(int x, int y); - } - - private static int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; } diff --git a/core/src/io/anuke/mindustry/content/Blocks.java b/core/src/io/anuke/mindustry/content/Blocks.java index 1ba3a37028..192a83863a 100644 --- a/core/src/io/anuke/mindustry/content/Blocks.java +++ b/core/src/io/anuke/mindustry/content/Blocks.java @@ -2,11 +2,9 @@ package io.anuke.mindustry.content; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; -import io.anuke.arc.graphics.g2d.Lines; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Time; import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.graphics.CacheLayer; +import io.anuke.mindustry.type.Category; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; @@ -22,16 +20,20 @@ import io.anuke.mindustry.world.blocks.storage.CoreBlock; import io.anuke.mindustry.world.blocks.storage.LaunchPad; import io.anuke.mindustry.world.blocks.storage.SortedUnloader; import io.anuke.mindustry.world.blocks.storage.Vault; -import io.anuke.mindustry.world.blocks.units.*; +import io.anuke.mindustry.world.blocks.units.MechPad; +import io.anuke.mindustry.world.blocks.units.Reconstructor; +import io.anuke.mindustry.world.blocks.units.RepairPoint; +import io.anuke.mindustry.world.blocks.units.UnitFactory; import static io.anuke.mindustry.Vars.content; +import static io.anuke.mindustry.Vars.state; public class Blocks implements ContentList{ public static Block //environment - air, blockpart, spawn, space, metalfloor, deepwater, water, tar, stone, blackstone, dirt, sand, ice, snow, - grass, shrub, rock, icerock, blackrock, rocksSmall, rocksMedium, + air, part, spawn, space, metalfloor, deepwater, water, tar, stone, craters, blackstone, dirt, sand, ice, snow, + grass, shrub, rock, icerock, blackrock, rocks, //crafting siliconSmelter, plastaniumCompressor, phaseWeaver, surgeSmelter, pyratiteMixer, blastMixer, cryofluidMixer, @@ -61,7 +63,7 @@ public class Blocks implements ContentList{ core, vault, container, unloader, launchPad, //turrets - duo, scorch, hail, wave, lancer, arc, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown, + duo, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown, //units spiritFactory, phantomFactory, wraithFactory, ghoulFactory, revenantFactory, daggerFactory, titanFactory, @@ -74,9 +76,7 @@ public class Blocks implements ContentList{ public void load(){ //region environment - air = new Floor("air"){ - { - blend = false; + air = new Floor("air"){{ alwaysReplace = true; } @@ -85,17 +85,10 @@ public class Blocks implements ContentList{ public void init(){} }; - blockpart = new BlockPart(); + part = new BlockPart(); spawn = new Block("spawn"){ - public void drawShadow(Tile tile){} - - public void draw(Tile tile){ - Draw.color(Color.SCARLET); - Lines.circle(tile.worldx(), tile.worldy(), 4f +Mathf.absin(Time.time(), 6f, 6f)); - Draw.color(); - } }; //Registers build blocks from size 1-6 @@ -109,7 +102,6 @@ public class Blocks implements ContentList{ variants = 0; cacheLayer = CacheLayer.space; solid = true; - blend = false; minimapColor = Color.valueOf("000001"); }}; @@ -157,9 +149,11 @@ public class Blocks implements ContentList{ stone = new Floor("stone"){{ hasOres = true; - blends = block -> block != this && !(block instanceof OreBlock); minimapColor = Color.valueOf("323232"); - playerUnmineable = true; + }}; + + craters = new Floor("craters"){{ + minimapColor = Color.valueOf("323232"); }}; blackstone = new Floor("blackstone"){{ @@ -173,7 +167,7 @@ public class Blocks implements ContentList{ }}; sand = new Floor("sand"){{ - drops = new ItemStack(Items.sand, 1); + itemDrop = Items.sand; minimapColor = Color.valueOf("988a67"); hasOres = true; playerUnmineable = true; @@ -210,22 +204,15 @@ public class Blocks implements ContentList{ variants = 1; }}; - rocksSmall = new Rock("rocks-small"){{ - variants = 2; - breakable = alwaysReplace = false; - solid = true; + rocks = new StaticWall("rocks"){{ + variants = 2; }}; - rocksMedium = new Rock("rocks-medium"){{ - variants = 2; - breakable = alwaysReplace = false; - solid = true; - }}; - //endregion //region crafting siliconSmelter = new PowerSmelter("silicon-smelter"){{ + requirements(Category.crafting, ItemStack.with(Items.copper, 60, Items.lead, 50)); health = 90; craftEffect = Fx.smeltsmoke; result = Items.silicon; @@ -239,6 +226,7 @@ public class Blocks implements ContentList{ }}; plastaniumCompressor = new PlastaniumCompressor("plastanium-compressor"){{ + requirements(Category.crafting, ItemStack.with(Items.silicon, 160, Items.lead, 230, Items.graphite, 120, Items.titanium, 160)); hasItems = true; liquidCapacity = 60f; craftTime = 60f; @@ -255,6 +243,7 @@ public class Blocks implements ContentList{ }}; phaseWeaver = new PhaseWeaver("phase-weaver"){{ + requirements(Category.crafting, ItemStack.with(Items.silicon, 260, Items.lead, 240, Items.thorium, 150)); craftEffect = Fx.smeltsmoke; result = Items.phasefabric; craftTime = 120f; @@ -265,6 +254,7 @@ public class Blocks implements ContentList{ }}; surgeSmelter = new PowerSmelter("alloy-smelter"){{ + requirements(Category.crafting, ItemStack.with(Items.silicon, 160, Items.lead, 160, Items.thorium, 140)); craftEffect = Fx.smeltsmoke; result = Items.surgealloy; craftTime = 75f; @@ -278,6 +268,7 @@ public class Blocks implements ContentList{ }}; cryofluidMixer = new LiquidMixer("cryofluidmixer"){{ + requirements(Category.crafting, ItemStack.with(Items.lead, 130, Items.silicon, 80, Items.thorium, 90)); outputLiquid = Liquids.cryofluid; liquidPerItem = 50f; size = 2; @@ -289,6 +280,7 @@ public class Blocks implements ContentList{ }}; blastMixer = new GenericCrafter("blast-mixer"){{ + requirements(Category.crafting, ItemStack.with(Items.lead, 60, Items.titanium, 40)); hasItems = true; hasPower = true; hasLiquids = true; @@ -301,6 +293,7 @@ public class Blocks implements ContentList{ }}; pyratiteMixer = new PowerSmelter("pyratite-mixer"){{ + requirements(Category.crafting, ItemStack.with(Items.copper, 100, Items.lead, 50)); flameColor = Color.CLEAR; hasItems = true; hasPower = true; @@ -313,6 +306,7 @@ public class Blocks implements ContentList{ }}; melter = new PowerCrafter("melter"){{ + requirements(Category.crafting, ItemStack.with(Items.copper, 60, Items.lead, 70, Items.graphite, 90)); health = 200; outputLiquid = Liquids.slag; outputLiquidAmount = 1.5f; @@ -324,11 +318,12 @@ public class Blocks implements ContentList{ }}; separator = new Separator("separator"){{ + requirements(Category.crafting, ItemStack.with(Items.copper, 60, Items.titanium, 50)); results = new ItemStack[]{ - new ItemStack(Items.copper, 5), - new ItemStack(Items.lead, 3), - new ItemStack(Items.titanium, 2), - new ItemStack(Items.thorium, 1) + new ItemStack(Items.copper, 5), + new ItemStack(Items.lead, 3), + new ItemStack(Items.titanium, 2), + new ItemStack(Items.thorium, 1) }; hasPower = true; filterTime = 15f; @@ -343,6 +338,7 @@ public class Blocks implements ContentList{ }}; biomatterCompressor = new Compressor("biomattercompressor"){{ + requirements(Category.crafting, ItemStack.with(Items.lead, 70, Items.silicon, 60)); liquidCapacity = 60f; craftTime = 20f; outputLiquid = Liquids.oil; @@ -356,6 +352,7 @@ public class Blocks implements ContentList{ }}; pulverizer = new Pulverizer("pulverizer"){{ + requirements(Category.crafting, ItemStack.with(Items.copper, 60, Items.lead, 50)); output = Items.sand; craftEffect = Fx.pulverize; craftTime = 40f; @@ -367,73 +364,107 @@ public class Blocks implements ContentList{ }}; incinerator = new Incinerator("incinerator"){{ + requirements(Category.crafting, ItemStack.with(Items.graphite, 10, Items.lead, 30)); health = 90; }}; - + //endregion //region sandbox - - powerVoid = new PowerVoid("power-void"); - powerSource = new PowerSource("power-source"); - itemSource = new ItemSource("item-source"); - itemVoid = new ItemVoid("item-void"); - liquidSource = new LiquidSource("liquid-source"); - + + powerVoid = new PowerVoid("power-void"){{ + requirements(Category.power, () -> state.rules.infiniteResources, ItemStack.with()); + alwaysUnlocked = true; + }}; + powerSource = new PowerSource("power-source"){{ + requirements(Category.power, () -> state.rules.infiniteResources, ItemStack.with()); + alwaysUnlocked = true; + }}; + itemSource = new ItemSource("item-source"){{ + requirements(Category.distribution, () -> state.rules.infiniteResources, ItemStack.with()); + alwaysUnlocked = true; + }}; + itemVoid = new ItemVoid("item-void"){{ + requirements(Category.distribution, () -> state.rules.infiniteResources, ItemStack.with()); + alwaysUnlocked = true; + }}; + liquidSource = new LiquidSource("liquid-source"){{ + requirements(Category.liquid, () -> state.rules.infiniteResources, ItemStack.with()); + alwaysUnlocked = true; + }}; + //endregion //region defense int wallHealthMultiplier = 3; copperWall = new Wall("copper-wall"){{ + requirements(Category.defense, ItemStack.with(Items.copper, 12)); health = 80 * wallHealthMultiplier; }}; copperWallLarge = new Wall("copper-wall-large"){{ + requirements(Category.defense, ItemStack.with(Items.copper, 12 * 4)); + requirements(Category.defense, ItemStack.with(Items.copper, 12)); health = 80 * 4 * wallHealthMultiplier; size = 2; }}; titaniumWall = new Wall("titanium-wall"){{ + requirements(Category.defense, ItemStack.with(Items.titanium, 12)); health = 110 * wallHealthMultiplier; }}; titaniumWallLarge = new Wall("titanium-wall-large"){{ + requirements(Category.defense, ItemStack.with(Items.titanium, 12 * 4)); + requirements(Category.defense, ItemStack.with(Items.titanium, 12)); health = 110 * wallHealthMultiplier * 4; size = 2; }}; thoriumWall = new Wall("thorium-wall"){{ + requirements(Category.defense, ItemStack.with(Items.thorium, 12)); health = 200 * wallHealthMultiplier; }}; thoriumWallLarge = new Wall("thorium-wall-large"){{ + requirements(Category.defense, ItemStack.with(Items.thorium, 12 * 4)); + requirements(Category.defense, ItemStack.with(Items.thorium, 12)); health = 200 * wallHealthMultiplier * 4; size = 2; }}; phaseWall = new DeflectorWall("phase-wall"){{ + requirements(Category.defense, ItemStack.with(Items.phasefabric, 12)); health = 150 * wallHealthMultiplier; }}; phaseWallLarge = new DeflectorWall("phase-wall-large"){{ + requirements(Category.defense, ItemStack.with(Items.phasefabric, 12 * 4)); + requirements(Category.defense, ItemStack.with(Items.phasefabric, 12)); health = 150 * 4 * wallHealthMultiplier; size = 2; }}; surgeWall = new SurgeWall("surge-wall"){{ + requirements(Category.defense, ItemStack.with(Items.surgealloy, 12)); health = 230 * wallHealthMultiplier; }}; surgeWallLarge = new SurgeWall("surge-wall-large"){{ + requirements(Category.defense, ItemStack.with(Items.surgealloy, 12 * 4)); + requirements(Category.defense, ItemStack.with(Items.surgealloy, 12)); health = 230 * 4 * wallHealthMultiplier; size = 2; }}; door = new Door("door"){{ + requirements(Category.defense, ItemStack.with(Items.titanium, 12, Items.silicon, 8)); health = 100 * wallHealthMultiplier; }}; doorLarge = new Door("door-large"){{ + requirements(Category.defense, ItemStack.with(Items.titanium, 12 * 4, Items.silicon, 8 * 4)); + requirements(Category.defense, ItemStack.with(Items.titanium, 12, Items.silicon, 8)); openfx = Fx.dooropenlarge; closefx = Fx.doorcloselarge; health = 100 * 4 * wallHealthMultiplier; @@ -441,85 +472,107 @@ public class Blocks implements ContentList{ }}; mendProjector = new MendProjector("mend-projector"){{ + requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.titanium, 50, Items.silicon, 180)); consumes.power(0.2f, 1.0f); size = 2; consumes.item(Items.phasefabric).optional(true); }}; overdriveProjector = new OverdriveProjector("overdrive-projector"){{ + requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.titanium, 150, Items.silicon, 250)); consumes.power(0.35f, 1.0f); size = 2; consumes.item(Items.phasefabric).optional(true); }}; forceProjector = new ForceProjector("force-projector"){{ + requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.titanium, 150, Items.silicon, 250)); size = 3; consumes.item(Items.phasefabric).optional(true); }}; shockMine = new ShockMine("shock-mine"){{ + requirements(Category.effect, ItemStack.with(Items.lead, 50, Items.silicon, 25)); health = 40; damage = 11; tileDamage = 7f; length = 10; tendrils = 5; }}; - + //endregion //region distribution conveyor = new Conveyor("conveyor"){{ + requirements(Category.distribution, ItemStack.with(Items.copper, 1), true); health = 45; speed = 0.03f; }}; titaniumConveyor = new Conveyor("titanium-conveyor"){{ + requirements(Category.distribution, ItemStack.with(Items.copper, 2, Items.titanium, 1)); health = 65; speed = 0.07f; }}; junction = new Junction("junction"){{ + requirements(Category.distribution, ItemStack.with(Items.copper, 2)); speed = 26; capacity = 32; }}; itemBridge = new BufferedItemBridge("bridge-conveyor"){{ + requirements(Category.distribution, ItemStack.with(Items.titanium, 8, Items.copper, 8)); range = 4; speed = 60f; bufferCapacity = 15; }}; phaseConveyor = new ItemBridge("phase-conveyor"){{ + requirements(Category.distribution, ItemStack.with(Items.phasefabric, 10, Items.silicon, 15, Items.lead, 20, Items.graphite, 20)); range = 12; hasPower = true; consumes.power(0.03f, 1.0f); }}; - sorter = new Sorter("sorter"); + sorter = new Sorter("sorter"){{ + requirements(Category.distribution, ItemStack.with(Items.titanium, 4, Items.copper, 4)); - router = new Router("router"); + }}; + + router = new Router("router"){{ + requirements(Category.distribution, ItemStack.with(Items.copper, 6)); + + }}; distributor = new Router("distributor"){{ + requirements(Category.distribution, ItemStack.with(Items.titanium, 8, Items.copper, 8)); size = 2; }}; - overflowGate = new OverflowGate("overflow-gate"); + overflowGate = new OverflowGate("overflow-gate"){{ + requirements(Category.distribution, ItemStack.with(Items.titanium, 4, Items.copper, 8)); + + }}; massDriver = new MassDriver("mass-driver"){{ + requirements(Category.distribution, ItemStack.with(Items.titanium, 250, Items.silicon, 150, Items.lead, 250, Items.thorium, 100)); size = 3; itemCapacity = 60; range = 440f; }}; - + //endregion //region liquid mechanicalPump = new Pump("mechanical-pump"){{ + requirements(Category.liquid, ItemStack.with(Items.copper, 30, Items.lead, 20)); pumpAmount = 0.1f; tier = 0; }}; rotaryPump = new Pump("rotary-pump"){{ + requirements(Category.liquid, ItemStack.with(Items.copper, 140, Items.lead, 100, Items.silicon, 40, Items.titanium, 70)); pumpAmount = 0.2f; consumes.power(0.015f); liquidCapacity = 30f; @@ -529,6 +582,7 @@ public class Blocks implements ContentList{ }}; thermalPump = new Pump("thermal-pump"){{ + requirements(Category.liquid, ItemStack.with(Items.copper, 160, Items.lead, 130, Items.silicon, 60, Items.titanium, 80, Items.thorium, 70)); pumpAmount = 0.275f; consumes.power(0.03f); liquidCapacity = 40f; @@ -538,47 +592,83 @@ public class Blocks implements ContentList{ }}; conduit = new Conduit("conduit"){{ + requirements(Category.liquid, ItemStack.with(Items.lead, 1)); health = 45; }}; pulseConduit = new Conduit("pulse-conduit"){{ + requirements(Category.liquid, ItemStack.with(Items.titanium, 1, Items.lead, 1)); liquidCapacity = 16f; liquidFlowFactor = 4.9f; health = 90; }}; liquidRouter = new LiquidRouter("liquid-router"){{ + requirements(Category.liquid, ItemStack.with(Items.titanium, 4, Items.lead, 4)); liquidCapacity = 20f; }}; liquidTank = new LiquidTank("liquid-tank"){{ + requirements(Category.liquid, ItemStack.with(Items.titanium, 50, Items.lead, 50)); size = 3; liquidCapacity = 1500f; health = 500; }}; - liquidJunction = new LiquidJunction("liquid-junction"); + liquidJunction = new LiquidJunction("liquid-junction"){{ + requirements(Category.liquid, ItemStack.with(Items.titanium, 4, Items.lead, 4)); + }}; bridgeConduit = new LiquidExtendingBridge("bridge-conduit"){{ + requirements(Category.liquid, ItemStack.with(Items.titanium, 8, Items.lead, 8)); range = 4; hasPower = false; }}; phaseConduit = new LiquidBridge("phase-conduit"){{ + requirements(Category.liquid, ItemStack.with(Items.phasefabric, 10, Items.silicon, 15, Items.lead, 20, Items.titanium, 20)); range = 12; hasPower = true; consumes.power(0.03f, 1.0f); }}; - + //endregion //region power + powerNode = new PowerNode("power-node"){{ + requirements(Category.power, ItemStack.with(Items.copper, 2, Items.lead, 6)); + maxNodes = 4; + laserRange = 6; + }}; + + powerNodeLarge = new PowerNode("power-node-large"){{ + requirements(Category.power, ItemStack.with(Items.titanium, 10, Items.lead, 20, Items.silicon, 6)); + requirements(Category.power, ItemStack.with(Items.copper, 2, Items.lead, 6)); + size = 2; + maxNodes = 6; + laserRange = 9.5f; + }}; + + battery = new Battery("battery"){{ + requirements(Category.power, ItemStack.with(Items.copper, 8, Items.lead, 30, Items.silicon, 4)); + consumes.powerBuffered(320f, 1f); + }}; + + batteryLarge = new Battery("battery-large"){{ + requirements(Category.power, ItemStack.with(Items.titanium, 40, Items.lead, 80, Items.silicon, 30)); + requirements(Category.power, ItemStack.with(Items.copper, 8, Items.lead, 30, Items.silicon, 4)); + size = 3; + consumes.powerBuffered(2000f, 1f); + }}; + combustionGenerator = new BurnerGenerator("combustion-generator"){{ + requirements(Category.power, ItemStack.with(Items.copper, 50, Items.lead, 30)); powerProduction = 0.09f; itemDuration = 40f; }}; thermalGenerator = new LiquidHeatGenerator("thermal-generator"){{ + requirements(Category.power, ItemStack.with(Items.copper, 80, Items.graphite, 70, Items.lead, 100, Items.silicon, 70, Items.thorium, 70)); maxLiquidGenerate = 2f; powerProduction = 2f; generateEffect = Fx.redgeneratespark; @@ -586,6 +676,7 @@ public class Blocks implements ContentList{ }}; turbineGenerator = new TurbineGenerator("turbine-generator"){{ + requirements(Category.power, ItemStack.with(Items.copper, 70, Items.graphite, 50, Items.lead, 80, Items.silicon, 60)); powerProduction = 0.28f; itemDuration = 30f; consumes.liquid(Liquids.water, 0.05f); @@ -593,21 +684,25 @@ public class Blocks implements ContentList{ }}; rtgGenerator = new DecayGenerator("rtg-generator"){{ + requirements(Category.power, ItemStack.with(Items.lead, 200, Items.silicon, 150, Items.phasefabric, 50, Items.plastanium, 150, Items.thorium, 100)); size = 2; powerProduction = 0.3f; itemDuration = 220f; }}; solarPanel = new SolarGenerator("solar-panel"){{ + requirements(Category.power, ItemStack.with(Items.lead, 20, Items.silicon, 30)); powerProduction = 0.0045f; }}; largeSolarPanel = new SolarGenerator("solar-panel-large"){{ + requirements(Category.power, ItemStack.with(Items.lead, 200, Items.silicon, 290, Items.phasefabric, 30)); size = 3; powerProduction = 0.055f; }}; thoriumReactor = new NuclearReactor("thorium-reactor"){{ + requirements(Category.power, ItemStack.with(Items.lead, 600, Items.silicon, 400, Items.graphite, 300, Items.thorium, 300)); size = 3; health = 700; powerProduction = 1.1f; @@ -618,45 +713,28 @@ public class Blocks implements ContentList{ health = 600; }}; - battery = new Battery("battery"){{ - consumes.powerBuffered(320f, 1f); - }}; - - batteryLarge = new Battery("battery-large"){{ - size = 3; - consumes.powerBuffered(2000f, 1f); - }}; - - powerNode = new PowerNode("power-node"){{ - maxNodes = 4; - laserRange = 6; - }}; - - powerNodeLarge = new PowerNode("power-node-large"){{ - size = 2; - maxNodes = 6; - laserRange = 9.5f; - }}; - //endregion power //region production mechanicalDrill = new Drill("mechanical-drill"){{ + requirements(Category.production, ItemStack.with(Items.copper, 20), true); tier = 2; - drillTime = 300; + drillTime = 600; size = 2; drawMineItem = true; }}; pneumaticDrill = new Drill("pneumatic-drill"){{ + requirements(Category.production, ItemStack.with(Items.copper, 60, Items.graphite, 50)); tier = 3; - drillTime = 240; + drillTime = 480; size = 2; drawMineItem = true; }}; laserDrill = new Drill("laser-drill"){{ - drillTime = 140; + requirements(Category.production, ItemStack.with(Items.copper, 70, Items.graphite, 90, Items.silicon, 60, Items.titanium, 50)); + drillTime = 280; size = 2; hasPower = true; tier = 4; @@ -667,7 +745,8 @@ public class Blocks implements ContentList{ }}; blastDrill = new Drill("blast-drill"){{ - drillTime = 60; + requirements(Category.production, ItemStack.with(Items.copper, 130, Items.silicon, 120, Items.titanium, 100, Items.thorium, 60)); + drillTime = 120; size = 3; drawRim = true; hasPower = true; @@ -683,7 +762,7 @@ public class Blocks implements ContentList{ plasmaDrill = new Drill("plasma-drill"){{ heatColor = Color.valueOf("ff461b"); - drillTime = 50; + drillTime = 100; size = 4; hasLiquids = true; hasPower = true; @@ -699,6 +778,7 @@ public class Blocks implements ContentList{ }}; waterExtractor = new SolidPump("water-extractor"){{ + requirements(Category.production, ItemStack.with(Items.copper, 50, Items.graphite, 50, Items.lead, 40)); result = Liquids.water; pumpAmount = 0.065f; size = 2; @@ -709,6 +789,7 @@ public class Blocks implements ContentList{ }}; oilExtractor = new Fracker("oil-extractor"){{ + requirements(Category.production, ItemStack.with(Items.copper, 300, Items.graphite, 350, Items.lead, 230, Items.thorium, 230, Items.silicon, 150)); result = Liquids.oil; updateEffect = Fx.pulverize; liquidCapacity = 50f; @@ -723,6 +804,7 @@ public class Blocks implements ContentList{ }}; cultivator = new Cultivator("cultivator"){{ + requirements(Category.production, ItemStack.with(Items.copper, 20, Items.lead, 50, Items.silicon, 20)); result = Items.biomatter; drillTime = 200; size = 2; @@ -732,61 +814,74 @@ public class Blocks implements ContentList{ consumes.power(0.08f); consumes.liquid(Liquids.water, 0.15f); }}; - + //endregion //region storage core = new CoreBlock("core"){{ + requirements(Category.effect, () -> false, ItemStack.with(Items.titanium, 2000)); + alwaysUnlocked = true; + health = 1100; - itemCapacity = 2000; + itemCapacity = 1000; + launchThreshold = 500; + launchTime = 60f * 10; + launchChunkSize = 100; }}; vault = new Vault("vault"){{ + requirements(Category.effect, ItemStack.with(Items.titanium, 500, Items.thorium, 250)); size = 3; itemCapacity = 1000; }}; container = new Vault("container"){{ + requirements(Category.effect, ItemStack.with(Items.titanium, 200)); size = 2; itemCapacity = 300; }}; unloader = new SortedUnloader("unloader"){{ + requirements(Category.distribution, ItemStack.with(Items.titanium, 50, Items.silicon, 60)); speed = 7f; }}; launchPad = new LaunchPad("launch-pad"){{ + requirements(Category.effect, ItemStack.with(Items.copper, 500)); size = 3; itemCapacity = 100; launchTime = 60f * 6; + hasPower = true; consumes.power(0.1f); }}; - + //endregion //region turrets duo = new DoubleTurret("duo"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 60), true); ammo( Items.copper, Bullets.standardCopper, Items.graphite, Bullets.standardDense, Items.pyratite, Bullets.standardIncendiary, Items.silicon, Bullets.standardHoming ); - reload = 25f; + reload = 20f; restitution = 0.03f; range = 90f; shootCone = 15f; ammoUseEffect = Fx.shellEjectSmall; - health = 80; + health = 110; inaccuracy = 2f; rotatespeed = 10f; }}; hail = new ArtilleryTurret("hail"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 60, Items.graphite, 35)); ammo( - Items.graphite, Bullets.artilleryDense, - Items.silicon, Bullets.artilleryHoming, - Items.pyratite, Bullets.artlleryIncendiary + Items.graphite, Bullets.artilleryDense, + Items.silicon, Bullets.artilleryHoming, + Items.pyratite, Bullets.artlleryIncendiary ); reload = 60f; recoil = 2f; @@ -796,21 +891,13 @@ public class Blocks implements ContentList{ health = 120; }}; - scorch = new LiquidTurret("scorch"){{ - ammo(Liquids.oil, Bullets.basicFlame); - recoil = 0f; - reload = 4f; - shootCone = 50f; - ammoUseEffect = Fx.shellEjectSmall; - health = 160; - }}; - wave = new LiquidTurret("wave"){{ + requirements(Category.turret, ItemStack.with(Items.titanium, 70, Items.lead, 150)); ammo( - Liquids.water, Bullets.waterShot, - Liquids.slag, Bullets.slagShot, - Liquids.cryofluid, Bullets.cryoShot, - Liquids.oil, Bullets.oilShot + Liquids.water, Bullets.waterShot, + Liquids.slag, Bullets.slagShot, + Liquids.cryofluid, Bullets.cryoShot, + Liquids.oil, Bullets.oilShot ); size = 2; recoil = 0f; @@ -832,6 +919,7 @@ public class Blocks implements ContentList{ }}; lancer = new ChargeTurret("lancer"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 50, Items.lead, 100, Items.silicon, 90)); range = 90f; chargeTime = 60f; chargeMaxDelay = 30f; @@ -854,6 +942,7 @@ public class Blocks implements ContentList{ }}; arc = new PowerTurret("arc"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 70, Items.lead, 60)); shootType = Bullets.arc; reload = 85f; shootShake = 1f; @@ -869,10 +958,11 @@ public class Blocks implements ContentList{ }}; swarmer = new BurstTurret("swarmer"){{ + requirements(Category.turret, ItemStack.with(Items.graphite, 70, Items.titanium, 70, Items.plastanium, 90, Items.silicon, 60)); ammo( - Items.blastCompound, Bullets.missileExplosive, - Items.pyratite, Bullets.missileIncendiary, - Items.surgealloy, Bullets.missileSurge + Items.blastCompound, Bullets.missileExplosive, + Items.pyratite, Bullets.missileIncendiary, + Items.surgealloy, Bullets.missileSurge ); reload = 50f; shots = 4; @@ -885,12 +975,13 @@ public class Blocks implements ContentList{ }}; salvo = new BurstTurret("salvo"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 210, Items.graphite, 190, Items.thorium, 130)); ammo( - Items.copper, Bullets.standardCopper, - Items.graphite, Bullets.standardDense, - Items.pyratite, Bullets.standardIncendiary, - Items.silicon, Bullets.standardHoming, - Items.thorium, Bullets.standardThorium + Items.copper, Bullets.standardCopper, + Items.graphite, Bullets.standardDense, + Items.pyratite, Bullets.standardIncendiary, + Items.silicon, Bullets.standardHoming, + Items.thorium, Bullets.standardThorium ); size = 2; @@ -908,12 +999,13 @@ public class Blocks implements ContentList{ }}; ripple = new ArtilleryTurret("ripple"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 300, Items.graphite, 220, Items.thorium, 120)); ammo( - Items.graphite, Bullets.artilleryDense, - Items.silicon, Bullets.artilleryHoming, - Items.pyratite, Bullets.artlleryIncendiary, - Items.blastCompound, Bullets.artilleryExplosive, - Items.plastanium, Bullets.arilleryPlastic + Items.graphite, Bullets.artilleryDense, + Items.silicon, Bullets.artilleryHoming, + Items.pyratite, Bullets.artlleryIncendiary, + Items.blastCompound, Bullets.artilleryExplosive, + Items.plastanium, Bullets.arilleryPlastic ); size = 3; shots = 4; @@ -932,10 +1024,11 @@ public class Blocks implements ContentList{ }}; cyclone = new ItemTurret("cyclone"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 400, Items.surgealloy, 200, Items.plastanium, 150)); ammo( - Items.blastCompound, Bullets.flakExplosive, - Items.plastanium, Bullets.flakPlastic, - Items.surgealloy, Bullets.flakSurge + Items.blastCompound, Bullets.flakExplosive, + Items.plastanium, Bullets.flakPlastic, + Items.surgealloy, Bullets.flakSurge ); xRand = 4f; reload = 8f; @@ -950,6 +1043,7 @@ public class Blocks implements ContentList{ }}; fuse = new ItemTurret("fuse"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 450, Items.graphite, 450, Items.surgealloy, 250)); ammo(Items.graphite, Bullets.fuseShot); reload = 50f; shootShake = 4f; @@ -962,10 +1056,11 @@ public class Blocks implements ContentList{ }}; spectre = new DoubleTurret("spectre"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 700, Items.graphite, 600, Items.surgealloy, 500, Items.plastanium, 350, Items.thorium, 500)); ammo( - Items.graphite, Bullets.standardDenseBig, - Items.pyratite, Bullets.standardIncendiaryBig, - Items.thorium, Bullets.standardThoriumBig + Items.graphite, Bullets.standardDenseBig, + Items.pyratite, Bullets.standardIncendiaryBig, + Items.thorium, Bullets.standardThoriumBig ); reload = 6f; coolantMultiplier = 0.5f; @@ -986,6 +1081,7 @@ public class Blocks implements ContentList{ }}; meltdown = new LaserTurret("meltdown"){{ + requirements(Category.turret, ItemStack.with(Items.copper, 500, Items.lead, 700, Items.graphite, 600, Items.surgealloy, 650, Items.silicon, 650)); shootType = Bullets.meltdownLaser; shootEffect = Fx.shootBigSmoke2; shootCone = 40f; @@ -1001,11 +1097,12 @@ public class Blocks implements ContentList{ health = 165 * size * size; }}; - + //endregion //region units spiritFactory = new UnitFactory("spirit-factory"){{ + requirements(Category.units, ItemStack.with(Items.copper, 70, Items.lead, 110, Items.silicon, 130)); type = UnitTypes.spirit; produceTime = 5700; size = 2; @@ -1014,6 +1111,7 @@ public class Blocks implements ContentList{ }}; phantomFactory = new UnitFactory("phantom-factory"){{ + requirements(Category.units, ItemStack.with(Items.titanium, 90, Items.thorium, 80, Items.lead, 110, Items.silicon, 210)); type = UnitTypes.phantom; produceTime = 7300; size = 2; @@ -1022,6 +1120,7 @@ public class Blocks implements ContentList{ }}; wraithFactory = new UnitFactory("wraith-factory"){{ + requirements(Category.units, ItemStack.with(Items.titanium, 60, Items.lead, 80, Items.silicon, 90)); type = UnitTypes.wraith; produceTime = 1800; size = 2; @@ -1030,6 +1129,7 @@ public class Blocks implements ContentList{ }}; ghoulFactory = new UnitFactory("ghoul-factory"){{ + requirements(Category.units, ItemStack.with(Items.plastanium, 80, Items.titanium, 100, Items.lead, 130, Items.silicon, 220)); type = UnitTypes.ghoul; produceTime = 3600; size = 3; @@ -1038,6 +1138,7 @@ public class Blocks implements ContentList{ }}; revenantFactory = new UnitFactory("revenant-factory"){{ + requirements(Category.units, ItemStack.with(Items.plastanium, 300, Items.titanium, 400, Items.lead, 300, Items.silicon, 400, Items.surgealloy, 100)); type = UnitTypes.revenant; produceTime = 8000; size = 4; @@ -1046,6 +1147,7 @@ public class Blocks implements ContentList{ }}; daggerFactory = new UnitFactory("dagger-factory"){{ + requirements(Category.units, ItemStack.with(Items.lead, 90, Items.silicon, 70)); type = UnitTypes.dagger; produceTime = 1700; size = 2; @@ -1054,6 +1156,7 @@ public class Blocks implements ContentList{ }}; titanFactory = new UnitFactory("titan-factory"){{ + requirements(Category.units, ItemStack.with(Items.thorium, 90, Items.lead, 140, Items.silicon, 90)); type = UnitTypes.titan; produceTime = 3400; size = 3; @@ -1062,6 +1165,7 @@ public class Blocks implements ContentList{ }}; fortressFactory = new UnitFactory("fortress-factory"){{ + requirements(Category.units, ItemStack.with(Items.thorium, 200, Items.lead, 220, Items.silicon, 150, Items.surgealloy, 100, Items.phasefabric, 50)); type = UnitTypes.fortress; produceTime = 5000; size = 3; @@ -1070,64 +1174,73 @@ public class Blocks implements ContentList{ }}; repairPoint = new RepairPoint("repair-point"){{ + requirements(Category.units, ItemStack.with(Items.lead, 30, Items.copper, 30, Items.silicon, 30)); repairSpeed = 0.1f; }}; reconstructor = new Reconstructor("reconstructor"){{ size = 2; }}; - + //endregion //region upgrades alphaPad = new MechPad("alpha-mech-pad"){{ + requirements(Category.upgrade, ItemStack.with(Items.lead, 200, Items.graphite, 100, Items.copper, 150)); mech = Mechs.alpha; size = 2; consumes.powerBuffered(50f); }}; deltaPad = new MechPad("delta-mech-pad"){{ + requirements(Category.upgrade, ItemStack.with(Items.lead, 350, Items.titanium, 350, Items.copper, 400, Items.silicon, 450, Items.thorium, 300)); mech = Mechs.delta; size = 2; consumes.powerBuffered(70f); }}; tauPad = new MechPad("tau-mech-pad"){{ + requirements(Category.upgrade, ItemStack.with(Items.lead, 250, Items.titanium, 250, Items.copper, 250, Items.silicon, 250)); mech = Mechs.tau; size = 2; consumes.powerBuffered(100f); }}; omegaPad = new MechPad("omega-mech-pad"){{ + requirements(Category.upgrade, ItemStack.with(Items.lead, 450, Items.graphite, 550, Items.silicon, 650, Items.thorium, 600, Items.surgealloy, 240)); mech = Mechs.omega; size = 3; consumes.powerBuffered(120f); }}; dartPad = new MechPad("dart-ship-pad"){{ + requirements(Category.upgrade, ItemStack.with(Items.lead, 150, Items.copper, 150, Items.silicon, 200, Items.titanium, 240)); mech = Mechs.dart; size = 2; consumes.powerBuffered(50f); }}; javelinPad = new MechPad("javelin-ship-pad"){{ + requirements(Category.upgrade, ItemStack.with(Items.lead, 350, Items.silicon, 450, Items.titanium, 500, Items.plastanium, 400, Items.phasefabric, 200)); mech = Mechs.javelin; size = 2; consumes.powerBuffered(80f); }}; tridentPad = new MechPad("trident-ship-pad"){{ + requirements(Category.upgrade, ItemStack.with(Items.lead, 250, Items.copper, 250, Items.silicon, 250, Items.titanium, 300, Items.plastanium, 200)); mech = Mechs.trident; size = 2; consumes.powerBuffered(100f); }}; glaivePad = new MechPad("glaive-ship-pad"){{ + requirements(Category.upgrade, ItemStack.with(Items.lead, 450, Items.silicon, 650, Items.titanium, 700, Items.plastanium, 600, Items.surgealloy, 200)); mech = Mechs.glaive; size = 3; consumes.powerBuffered(120f); }}; - + //endregion //region ores diff --git a/core/src/io/anuke/mindustry/content/Bullets.java b/core/src/io/anuke/mindustry/content/Bullets.java index 0cc7113f10..a9d7abd474 100644 --- a/core/src/io/anuke/mindustry/content/Bullets.java +++ b/core/src/io/anuke/mindustry/content/Bullets.java @@ -267,7 +267,7 @@ public class Bullets implements ContentList{ bulletHeight = 9f; homingPower = 5f; reloadMultiplier = 1.4f; - ammoMultiplier = 5; + ammoMultiplier = 3; }}; standardIncendiary = new BasicBulletType(3.2f, 11, "bullet"){{ diff --git a/core/src/io/anuke/mindustry/content/Fx.java b/core/src/io/anuke/mindustry/content/Fx.java index 03325d4dc6..3fad4e7458 100644 --- a/core/src/io/anuke/mindustry/content/Fx.java +++ b/core/src/io/anuke/mindustry/content/Fx.java @@ -24,14 +24,15 @@ public class Fx implements ContentList{ vtolHover, unitDrop, unitPickup, unitLand, pickup, healWave, heal, landShock, reactorsmoke, nuclearsmoke, nuclearcloud, redgeneratespark, generatespark, fuelburn, plasticburn, pulverize, pulverizeRed, pulverizeRedder, pulverizeSmall, pulverizeMedium, producesmoke, smeltsmoke, formsmoke, blastsmoke, lava, doorclose, dooropen, dooropenlarge, doorcloselarge, purify, purifyoil, purifystone, generate, - mine, mineBig, mineHuge, smelt, teleportActivate, teleport, teleportOut, ripple, bubble, commandSend, + mine, mineBig, mineHuge, smelt, teleportActivate, teleport, teleportOut, ripple, bubble, launch, healBlock, healBlockFull, healWaveMend, overdriveWave, overdriveBlockFull, shieldBreak, hitBulletSmall, hitFuse, hitBulletBig, hitFlameSmall, hitLiquid, hitLaser, hitLancer, hitMeltdown, despawn, flakExplosion, blastExplosion, plasticExplosion, artilleryTrail, incendTrail, missileTrail, absorb, flakExplosionBig, plasticExplosionFlak, burning, fire, fireSmoke, steam, fireballsmoke, ballfire, freezing, melting, wet, oily, overdriven, dropItem, shockwave, bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke, shootSmall, shootHeal, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke, shootBigSmoke2, shootSmallFlame, shootLiquid, shellEjectSmall, shellEjectMedium, - shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot; + shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot, + launchFull; @Override public void load(){ @@ -1060,7 +1061,7 @@ public class Fx implements ContentList{ Draw.reset(); }); - commandSend = new Effect(28, e -> { + launch = new Effect(28, e -> { Draw.color(Palette.command); Lines.stroke(e.fout() * 2f); Lines.poly(e.x, e.y, 40, 4f + e.finpow() * 120f); @@ -1108,5 +1109,12 @@ public class Fx implements ContentList{ Lines.poly(e.x, e.y, 6, e.rotation + e.fin(), 90); Draw.reset(); }); + + launchFull = new Effect(60, 9999999999f, e -> { + Draw.color(); + Draw.alpha(e.fslope()); + Fill.rect(Core.camera.position.x, Core.camera.position.y, Core.camera.width + 10, Core.camera.height + 10); + Draw.reset(); + }); } } diff --git a/core/src/io/anuke/mindustry/content/Items.java b/core/src/io/anuke/mindustry/content/Items.java index 673ca105d3..a3e7279909 100644 --- a/core/src/io/anuke/mindustry/content/Items.java +++ b/core/src/io/anuke/mindustry/content/Items.java @@ -7,7 +7,7 @@ import io.anuke.mindustry.type.ItemType; public class Items implements ContentList{ public static Item scrap, copper, lead, graphite, coal, titanium, thorium, silicon, plastanium, phasefabric, surgealloy, - biomatter, sand, blastCompound, pyratite, bioglass; + biomatter, sand, blastCompound, pyratite, metaglass; @Override public void load(){ @@ -26,6 +26,11 @@ public class Items implements ContentList{ genOre = true; }}; + metaglass = new Item("metaglass", Color.valueOf("648b55")){{ + type = ItemType.material; + cost = 2f; + }}; + graphite = new Item("graphite", Color.valueOf("b2c6d2")){{ type = ItemType.material; cost = 1.3f; @@ -55,7 +60,7 @@ public class Items implements ContentList{ }}; scrap = new Item("scrap", Color.valueOf("777777")){{ - + genOre = true; }}; silicon = new Item("silicon", Color.valueOf("53565c")){{ @@ -99,10 +104,5 @@ public class Items implements ContentList{ flammability = 0.7f; explosiveness = 0.2f; }}; - - bioglass = new Item("bioglass", Color.valueOf("648b55")){{ - type = ItemType.material; - cost = 2f; - }}; } } diff --git a/core/src/io/anuke/mindustry/content/Liquids.java b/core/src/io/anuke/mindustry/content/Liquids.java index 6ee2e641b9..f7f120725f 100644 --- a/core/src/io/anuke/mindustry/content/Liquids.java +++ b/core/src/io/anuke/mindustry/content/Liquids.java @@ -5,7 +5,7 @@ import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.type.Liquid; public class Liquids implements ContentList{ - public static Liquid water, slag, oil, cryofluid, acid; + public static Liquid water, slag, oil, cryofluid; @Override public void load(){ @@ -16,7 +16,7 @@ public class Liquids implements ContentList{ effect = StatusEffects.wet; }}; - slag = new Liquid("slag", Color.valueOf("e37341")){{ + slag = new Liquid("slag", Color.valueOf("ffcd66")){{ temperature = 1f; viscosity = 0.8f; tier = 2; @@ -38,10 +38,5 @@ public class Liquids implements ContentList{ tier = 1; effect = StatusEffects.freezing; }}; - - acid = new Liquid("acid", Color.valueOf("e9f9b3")){{ - heatCapacity = 0.1f; //don't use acid as coolant, it's bad - effect = StatusEffects.corroded; - }}; } } diff --git a/core/src/io/anuke/mindustry/content/Mechs.java b/core/src/io/anuke/mindustry/content/Mechs.java index 9124d484d3..59e654c357 100644 --- a/core/src/io/anuke/mindustry/content/Mechs.java +++ b/core/src/io/anuke/mindustry/content/Mechs.java @@ -40,8 +40,8 @@ public class Mechs implements ContentList{ } @Override - public void updateAlt(Player player){ - + public boolean alwaysUnlocked(){ + return true; } }; @@ -182,18 +182,25 @@ public class Mechs implements ContentList{ } }; - dart = new Mech("dart-ship", true){{ - drillPower = 1; - mineSpeed = 0.9f; - speed = 0.4f; - drag = 0.1f; - armor = 10f; - weapon = Weapons.blasterSmall; - weaponOffsetX = -1; - weaponOffsetY = -1; - trailColor = Palette.lightTrail; - cellTrnsY = 1f; - }}; + dart = new Mech("dart-ship", true){ + { + drillPower = 1; + mineSpeed = 0.9f; + speed = 0.4f; + drag = 0.1f; + armor = 10f; + weapon = Weapons.blasterSmall; + weaponOffsetX = -1; + weaponOffsetY = -1; + trailColor = Palette.lightTrail; + cellTrnsY = 1f; + } + + @Override + public boolean alwaysUnlocked(){ + return true; + } + }; javelin = new Mech("javelin-ship", true){ float minV = 3.6f; diff --git a/core/src/io/anuke/mindustry/content/Recipes.java b/core/src/io/anuke/mindustry/content/Recipes.java deleted file mode 100644 index 078455d809..0000000000 --- a/core/src/io/anuke/mindustry/content/Recipes.java +++ /dev/null @@ -1,180 +0,0 @@ -package io.anuke.mindustry.content; - -import io.anuke.mindustry.game.ContentList; -import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.type.Recipe; -import io.anuke.mindustry.type.Recipe.RecipeVisibility; - -import static io.anuke.mindustry.type.Category.*; - -public class Recipes implements ContentList{ - - @Override - public void load(){ - //DEBUG - new Recipe(distribution, Blocks.itemSource).setVisible(RecipeVisibility.sandboxOnly).setHidden(true).setAlwaysUnlocked(true); - new Recipe(distribution, Blocks.itemVoid).setVisible(RecipeVisibility.sandboxOnly).setHidden(true).setAlwaysUnlocked(true); - new Recipe(liquid, Blocks.liquidSource).setVisible(RecipeVisibility.sandboxOnly).setHidden(true).setAlwaysUnlocked(true); - new Recipe(power, Blocks.powerVoid).setVisible(RecipeVisibility.sandboxOnly).setHidden(true).setAlwaysUnlocked(true); - new Recipe(power, Blocks.powerSource).setVisible(RecipeVisibility.sandboxOnly).setHidden(true).setAlwaysUnlocked(true); - - //DEFENSE - - //walls - new Recipe(defense, Blocks.copperWall, new ItemStack(Items.copper, 12)).setAlwaysUnlocked(true); - new Recipe(defense, Blocks.copperWallLarge, new ItemStack(Items.copper, 12 * 4)).setAlwaysUnlocked(true); - - new Recipe(defense, Blocks.titaniumWall, new ItemStack(Items.titanium, 12)); - new Recipe(defense, Blocks.titaniumWallLarge, new ItemStack(Items.titanium, 12 * 4)); - - new Recipe(defense, Blocks.door, new ItemStack(Items.titanium, 12), new ItemStack(Items.silicon, 8)); - new Recipe(defense, Blocks.doorLarge, new ItemStack(Items.titanium, 12 * 4), new ItemStack(Items.silicon, 8 * 4)); - - new Recipe(defense, Blocks.thoriumWall, new ItemStack(Items.thorium, 12)); - new Recipe(defense, Blocks.thoriumWallLarge, new ItemStack(Items.thorium, 12 * 4)); - - new Recipe(defense, Blocks.phaseWall, new ItemStack(Items.phasefabric, 12)); - new Recipe(defense, Blocks.phaseWallLarge, new ItemStack(Items.phasefabric, 12 * 4)); - - new Recipe(defense, Blocks.surgeWall, new ItemStack(Items.surgealloy, 12)); - new Recipe(defense, Blocks.surgeWallLarge, new ItemStack(Items.surgealloy, 12 * 4)); - - new Recipe(effect, Blocks.container, new ItemStack(Items.titanium, 200)); - new Recipe(effect, Blocks.vault, new ItemStack(Items.titanium, 500), new ItemStack(Items.thorium, 250)); - new Recipe(effect, Blocks.launchPad, new ItemStack(Items.copper, 500)); - - //projectors - new Recipe(effect, Blocks.mendProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.titanium, 150), new ItemStack(Items.titanium, 50), new ItemStack(Items.silicon, 180)); - new Recipe(effect, Blocks.overdriveProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.titanium, 150), new ItemStack(Items.titanium, 150), new ItemStack(Items.silicon, 250)); - new Recipe(effect, Blocks.forceProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.titanium, 150), new ItemStack(Items.titanium, 150), new ItemStack(Items.silicon, 250)); - - new Recipe(effect, Blocks.shockMine, new ItemStack(Items.lead, 50), new ItemStack(Items.silicon, 25)); - - //TURRETS - new Recipe(turret, Blocks.duo, new ItemStack(Items.copper, 40)).setAlwaysUnlocked(true); - new Recipe(turret, Blocks.arc, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 40)); - new Recipe(turret, Blocks.hail, new ItemStack(Items.copper, 60), new ItemStack(Items.graphite, 35)); - new Recipe(turret, Blocks.lancer, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 90)); - new Recipe(turret, Blocks.wave, new ItemStack(Items.titanium, 70), new ItemStack(Items.lead, 150)); - new Recipe(turret, Blocks.salvo, new ItemStack(Items.copper, 210), new ItemStack(Items.graphite, 190), new ItemStack(Items.thorium, 130)); - new Recipe(turret, Blocks.swarmer, new ItemStack(Items.graphite, 70), new ItemStack(Items.titanium, 70), new ItemStack(Items.plastanium, 90), new ItemStack(Items.silicon, 60)); - new Recipe(turret, Blocks.ripple, new ItemStack(Items.copper, 300), new ItemStack(Items.graphite, 220), new ItemStack(Items.thorium, 120)); - new Recipe(turret, Blocks.cyclone, new ItemStack(Items.copper, 400), new ItemStack(Items.surgealloy, 200), new ItemStack(Items.plastanium, 150)); - new Recipe(turret, Blocks.fuse, new ItemStack(Items.copper, 450), new ItemStack(Items.graphite, 450), new ItemStack(Items.surgealloy, 250)); - new Recipe(turret, Blocks.spectre, new ItemStack(Items.copper, 700), new ItemStack(Items.graphite, 600), new ItemStack(Items.surgealloy, 500), new ItemStack(Items.plastanium, 350), new ItemStack(Items.thorium, 500)); - new Recipe(turret, Blocks.meltdown, new ItemStack(Items.copper, 500), new ItemStack(Items.lead, 700), new ItemStack(Items.graphite, 600), new ItemStack(Items.surgealloy, 650), new ItemStack(Items.silicon, 650)); - - //DISTRIBUTION - new Recipe(distribution, Blocks.conveyor, new ItemStack(Items.copper, 1)).setAlwaysUnlocked(true); - new Recipe(distribution, Blocks.titaniumConveyor, new ItemStack(Items.copper, 2), new ItemStack(Items.titanium, 1)); - new Recipe(distribution, Blocks.phaseConveyor, new ItemStack(Items.phasefabric, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.graphite, 20)); - - //starter transport - new Recipe(distribution, Blocks.junction, new ItemStack(Items.copper, 2)).setAlwaysUnlocked(true); - new Recipe(distribution, Blocks.router, new ItemStack(Items.copper, 6)).setAlwaysUnlocked(true); - - //more advanced transport - new Recipe(distribution, Blocks.distributor, new ItemStack(Items.titanium, 8), new ItemStack(Items.copper, 8)); - new Recipe(distribution, Blocks.sorter, new ItemStack(Items.titanium, 4), new ItemStack(Items.copper, 4)); - new Recipe(distribution, Blocks.overflowGate, new ItemStack(Items.titanium, 4), new ItemStack(Items.copper, 8)); - new Recipe(distribution, Blocks.itemBridge, new ItemStack(Items.titanium, 8), new ItemStack(Items.copper, 8)); - new Recipe(distribution, Blocks.unloader, new ItemStack(Items.titanium, 50), new ItemStack(Items.silicon, 60)); - new Recipe(distribution, Blocks.massDriver, new ItemStack(Items.titanium, 250), new ItemStack(Items.silicon, 150), new ItemStack(Items.lead, 250), new ItemStack(Items.thorium, 100)); - - //CRAFTING - - //smelting - new Recipe(crafting, Blocks.siliconSmelter, new ItemStack(Items.copper, 60), new ItemStack(Items.lead, 50)); - - //advanced fabrication - new Recipe(crafting, Blocks.plastaniumCompressor, new ItemStack(Items.silicon, 160), new ItemStack(Items.lead, 230), new ItemStack(Items.graphite, 120), new ItemStack(Items.titanium, 160)); - new Recipe(crafting, Blocks.phaseWeaver, new ItemStack(Items.silicon, 260), new ItemStack(Items.lead, 240), new ItemStack(Items.thorium, 150)); - new Recipe(crafting, Blocks.surgeSmelter, new ItemStack(Items.silicon, 160), new ItemStack(Items.lead, 160), new ItemStack(Items.thorium, 140)); - - //misc - new Recipe(crafting, Blocks.pulverizer, new ItemStack(Items.copper, 60), new ItemStack(Items.lead, 50)); - new Recipe(crafting, Blocks.pyratiteMixer, new ItemStack(Items.copper, 100), new ItemStack(Items.lead, 50)); - new Recipe(crafting, Blocks.blastMixer, new ItemStack(Items.lead, 60), new ItemStack(Items.titanium, 40)); - new Recipe(crafting, Blocks.cryofluidMixer, new ItemStack(Items.lead, 130), new ItemStack(Items.silicon, 80), new ItemStack(Items.thorium, 90)); - - new Recipe(crafting, Blocks.melter, new ItemStack(Items.copper, 60), new ItemStack(Items.lead, 70), new ItemStack(Items.graphite, 90)); - new Recipe(crafting, Blocks.incinerator, new ItemStack(Items.graphite, 10), new ItemStack(Items.lead, 30)); - - //processing - new Recipe(crafting, Blocks.biomatterCompressor, new ItemStack(Items.lead, 70), new ItemStack(Items.silicon, 60)); - new Recipe(crafting, Blocks.separator, new ItemStack(Items.copper, 60), new ItemStack(Items.titanium, 50)); - - //POWER - new Recipe(power, Blocks.powerNode, new ItemStack(Items.copper, 2), new ItemStack(Items.lead, 6)); - new Recipe(power, Blocks.powerNodeLarge, new ItemStack(Items.titanium, 10), new ItemStack(Items.lead, 20), new ItemStack(Items.silicon, 6)); - new Recipe(power, Blocks.battery, new ItemStack(Items.copper, 8), new ItemStack(Items.lead, 30), new ItemStack(Items.silicon, 4)); - new Recipe(power, Blocks.batteryLarge, new ItemStack(Items.titanium, 40), new ItemStack(Items.lead, 80), new ItemStack(Items.silicon, 30)); - - //generators - combustion - new Recipe(power, Blocks.combustionGenerator, new ItemStack(Items.copper, 50), new ItemStack(Items.lead, 30)); - new Recipe(power, Blocks.turbineGenerator, new ItemStack(Items.copper, 70), new ItemStack(Items.graphite, 50), new ItemStack(Items.lead, 80), new ItemStack(Items.silicon, 60)); - new Recipe(power, Blocks.thermalGenerator, new ItemStack(Items.copper, 80), new ItemStack(Items.graphite, 70), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 70), new ItemStack(Items.thorium, 70)); - - //generators - solar - new Recipe(power, Blocks.solarPanel, new ItemStack(Items.lead, 20), new ItemStack(Items.silicon, 30)); - new Recipe(power, Blocks.largeSolarPanel, new ItemStack(Items.lead, 200), new ItemStack(Items.silicon, 290), new ItemStack(Items.phasefabric, 30)); - - //generators - nuclear - new Recipe(power, Blocks.thoriumReactor, new ItemStack(Items.lead, 600), new ItemStack(Items.silicon, 400), new ItemStack(Items.graphite, 300), new ItemStack(Items.thorium, 300)); - new Recipe(power, Blocks.rtgGenerator, new ItemStack(Items.lead, 200), new ItemStack(Items.silicon, 150), new ItemStack(Items.phasefabric, 50), new ItemStack(Items.plastanium, 150), new ItemStack(Items.thorium, 100)); - - //DRILLS, PRODUCERS - new Recipe(production, Blocks.mechanicalDrill, new ItemStack(Items.copper, 20)).setAlwaysUnlocked(true); - new Recipe(production, Blocks.pneumaticDrill, new ItemStack(Items.copper, 60), new ItemStack(Items.graphite, 50)); - new Recipe(production, Blocks.laserDrill, new ItemStack(Items.copper, 70), new ItemStack(Items.graphite, 90), new ItemStack(Items.silicon, 60), new ItemStack(Items.titanium, 50)); - new Recipe(production, Blocks.blastDrill, new ItemStack(Items.copper, 130), new ItemStack(Items.silicon, 120), new ItemStack(Items.titanium, 100), new ItemStack(Items.thorium, 60)); - - new Recipe(production, Blocks.waterExtractor, new ItemStack(Items.copper, 50), new ItemStack(Items.graphite, 50), new ItemStack(Items.lead, 40)); - new Recipe(production, Blocks.cultivator, new ItemStack(Items.copper, 20), new ItemStack(Items.lead, 50), new ItemStack(Items.silicon, 20)); - new Recipe(production, Blocks.oilExtractor, new ItemStack(Items.copper, 300), new ItemStack(Items.graphite, 350), new ItemStack(Items.lead, 230), new ItemStack(Items.thorium, 230), new ItemStack(Items.silicon, 150)); - - //UNITS - - //upgrades - new Recipe(upgrade, Blocks.dartPad, new ItemStack(Items.lead, 150), new ItemStack(Items.copper, 150), new ItemStack(Items.silicon, 200), new ItemStack(Items.titanium, 240)).setVisible(RecipeVisibility.desktopOnly); - new Recipe(upgrade, Blocks.tridentPad, new ItemStack(Items.lead, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250), new ItemStack(Items.titanium, 300), new ItemStack(Items.plastanium, 200)); - new Recipe(upgrade, Blocks.javelinPad, new ItemStack(Items.lead, 350), new ItemStack(Items.silicon, 450), new ItemStack(Items.titanium, 500), new ItemStack(Items.plastanium, 400), new ItemStack(Items.phasefabric, 200)); - new Recipe(upgrade, Blocks.glaivePad, new ItemStack(Items.lead, 450), new ItemStack(Items.silicon, 650), new ItemStack(Items.titanium, 700), new ItemStack(Items.plastanium, 600), new ItemStack(Items.surgealloy, 200)); - - new Recipe(upgrade, Blocks.alphaPad, new ItemStack(Items.lead, 200), new ItemStack(Items.graphite, 100), new ItemStack(Items.copper, 150)).setVisible(RecipeVisibility.mobileOnly); - new Recipe(upgrade, Blocks.tauPad, new ItemStack(Items.lead, 250), new ItemStack(Items.titanium, 250), new ItemStack(Items.copper, 250), new ItemStack(Items.silicon, 250)); - new Recipe(upgrade, Blocks.deltaPad, new ItemStack(Items.lead, 350), new ItemStack(Items.titanium, 350), new ItemStack(Items.copper, 400), new ItemStack(Items.silicon, 450), new ItemStack(Items.thorium, 300)); - new Recipe(upgrade, Blocks.omegaPad, new ItemStack(Items.lead, 450), new ItemStack(Items.graphite, 550), new ItemStack(Items.silicon, 650), new ItemStack(Items.thorium, 600), new ItemStack(Items.surgealloy, 240)); - - //unit factories - new Recipe(units, Blocks.spiritFactory, new ItemStack(Items.copper, 70), new ItemStack(Items.lead, 110), new ItemStack(Items.silicon, 130)); - new Recipe(units, Blocks.phantomFactory, new ItemStack(Items.titanium, 90), new ItemStack(Items.thorium, 80), new ItemStack(Items.lead, 110), new ItemStack(Items.silicon, 210)); - - new Recipe(units, Blocks.daggerFactory, new ItemStack(Items.lead, 90), new ItemStack(Items.silicon, 70)); - new Recipe(units, Blocks.titanFactory, new ItemStack(Items.thorium, 90), new ItemStack(Items.lead, 140), new ItemStack(Items.silicon, 90)); - new Recipe(units, Blocks.fortressFactory, new ItemStack(Items.thorium, 200), new ItemStack(Items.lead, 220), new ItemStack(Items.silicon, 150), new ItemStack(Items.surgealloy, 100), new ItemStack(Items.phasefabric, 50)); - - new Recipe(units, Blocks.wraithFactory, new ItemStack(Items.titanium, 60), new ItemStack(Items.lead, 80), new ItemStack(Items.silicon, 90)); - new Recipe(units, Blocks.ghoulFactory, new ItemStack(Items.plastanium, 80), new ItemStack(Items.titanium, 100), new ItemStack(Items.lead, 130), new ItemStack(Items.silicon, 220)); - new Recipe(units, Blocks.revenantFactory, new ItemStack(Items.plastanium, 300), new ItemStack(Items.titanium, 400), new ItemStack(Items.lead, 300), new ItemStack(Items.silicon, 400), new ItemStack(Items.surgealloy, 100)); - - new Recipe(units, Blocks.repairPoint, new ItemStack(Items.lead, 30), new ItemStack(Items.copper, 30), new ItemStack(Items.silicon, 30)); - - //removed for testing MOBA-style unit production - //new Recipe(units, Blocks.commandCenter, new ItemStack(Items.lead, 100), new ItemStack(Items.densealloy, 100), new ItemStack(Items.silicon, 200)); - - //LIQUIDS - new Recipe(liquid, Blocks.conduit, new ItemStack(Items.lead, 1)); - new Recipe(liquid, Blocks.pulseConduit, new ItemStack(Items.titanium, 1), new ItemStack(Items.lead, 1)); - new Recipe(liquid, Blocks.phaseConduit, new ItemStack(Items.phasefabric, 10), new ItemStack(Items.silicon, 15), new ItemStack(Items.lead, 20), new ItemStack(Items.titanium, 20)); - - new Recipe(liquid, Blocks.liquidRouter, new ItemStack(Items.titanium, 4), new ItemStack(Items.lead, 4)); - new Recipe(liquid, Blocks.liquidTank, new ItemStack(Items.titanium, 50), new ItemStack(Items.lead, 50)); - new Recipe(liquid, Blocks.liquidJunction, new ItemStack(Items.titanium, 4), new ItemStack(Items.lead, 4)); - new Recipe(liquid, Blocks.bridgeConduit, new ItemStack(Items.titanium, 8), new ItemStack(Items.lead, 8)); - - new Recipe(liquid, Blocks.mechanicalPump, new ItemStack(Items.copper, 30), new ItemStack(Items.lead, 20)); - new Recipe(liquid, Blocks.rotaryPump, new ItemStack(Items.copper, 140), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 40), new ItemStack(Items.titanium, 70)); - new Recipe(liquid, Blocks.thermalPump, new ItemStack(Items.copper, 160), new ItemStack(Items.lead, 130), new ItemStack(Items.silicon, 60), new ItemStack(Items.titanium, 80), new ItemStack(Items.thorium, 70)); - } -} diff --git a/core/src/io/anuke/mindustry/content/TechTree.java b/core/src/io/anuke/mindustry/content/TechTree.java new file mode 100644 index 0000000000..92e3103a91 --- /dev/null +++ b/core/src/io/anuke/mindustry/content/TechTree.java @@ -0,0 +1,285 @@ +package io.anuke.mindustry.content; + +import io.anuke.arc.collection.Array; +import io.anuke.mindustry.game.ContentList; +import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.world.Block; + +import static io.anuke.mindustry.content.Blocks.*; + +public class TechTree implements ContentList{ + public static TechNode root; + + @Override + public void load(){ + root = node(core, () -> { + + node(conveyor, () -> { + node(launchPad, () -> { + + }); + + node(junction, () -> { + node(itemBridge); + node(router, () -> { + node(distributor); + node(overflowGate); + node(sorter); + node(container, () -> { + node(unloader); + node(vault, () -> { + + }); + }); + }); + node(titaniumConveyor, () -> { + node(phaseConveyor, () -> { + node(massDriver, () -> { + + }); + }); + }); + }); + }); + + node(duo, () -> { + node(hail, () -> { + + node(salvo, () -> { + node(swarmer, () -> { + node(cyclone, () -> { + node(spectre, () -> { + + }); + }); + }); + + node(ripple, () -> { + node(fuse, () -> { + + }); + }); + }); + }); + + node(arc, () -> { + node(wave, () -> { + + }); + + node(lancer, () -> { + node(meltdown, () -> { + + }); + + node(shockMine, () -> { + + }); + }); + }); + + node(copperWall, () -> { + node(copperWallLarge); + node(titaniumWall, () -> { + node(door, () -> { + node(doorLarge); + }); + node(titaniumWallLarge); + node(thoriumWall, () -> { + node(thoriumWallLarge); + node(surgeWall, () -> { + node(surgeWallLarge); + node(phaseWall, () -> { + node(phaseWallLarge); + }); + }); + }); + }); + }); + }); + + node(mechanicalDrill, () -> { + node(pneumaticDrill, () -> { + node(cultivator, () -> { + + }); + + node(laserDrill, () -> { + node(blastDrill, () -> { + + }); + + node(waterExtractor, () -> { + node(oilExtractor, () -> { + + }); + }); + }); + }); + + node(siliconSmelter, () -> { + + node(pyratiteMixer, () -> { + node(blastMixer, () -> { + + }); + }); + + node(biomatterCompressor, () -> { + node(plastaniumCompressor, () -> { + node(phaseWeaver, () -> { + + }); + }); + }); + + node(incinerator, () -> { + node(melter, () -> { + node(surgeSmelter, () -> { + + }); + + node(separator, () -> { + node(pulverizer, () -> { + + }); + }); + + node(cryofluidMixer, () -> { + + }); + }); + }); + }); + + node(mechanicalPump, () -> { + node(conduit, () -> { + node(liquidJunction, () -> { + node(liquidRouter, () -> { + node(liquidTank); + + node(pulseConduit, () -> { + node(phaseConduit, () -> { + + }); + }); + + node(rotaryPump, () -> { + node(thermalPump, () -> { + + }); + }); + }); + node(bridgeConduit); + }); + }); + }); + }); + + node(powerNode, () -> { + node(combustionGenerator, () -> { + node(powerNodeLarge, () -> { + node(battery, () -> { + node(batteryLarge, () -> { + + }); + }); + + node(mendProjector, () -> { + node(forceProjector, () -> { + node(overdriveProjector, () -> { + + }); + }); + + node(repairPoint, () -> { + + }); + }); + }); + + node(turbineGenerator, () -> { + node(thermalGenerator, () -> { + node(rtgGenerator, () -> { + node(thoriumReactor, () -> { + + }); + }); + }); + }); + + node(solarPanel, () -> { + node(largeSolarPanel, () -> { + + }); + }); + }); + + node(alphaPad, () -> { + node(dartPad); + node(deltaPad, () -> { + node(javelinPad); + node(tauPad, () -> { + node(tridentPad); + node(omegaPad, () -> { + node(glaivePad); + }); + }); + }); + + node(spiritFactory, () -> { + node(daggerFactory, () -> { + node(daggerFactory, () -> { + node(titanFactory, () -> { + node(fortressFactory); + }); + node(wraithFactory, () -> { + node(phantomFactory); + node(ghoulFactory, () -> { + node(revenantFactory); + }); + }); + }); + }); + }); + }); + }); + }); + } + + private TechNode node(Block block, Runnable children){ + ItemStack[] requirements = new ItemStack[block.buildRequirements.length]; + for(int i = 0; i < requirements.length; i++){ + requirements[i] = new ItemStack(block.buildRequirements[i].item, block.buildRequirements[i].amount * 50); + } + + return new TechNode(block, requirements, children); + } + + private TechNode node(Block block){ + return node(block, () -> {}); + } + + public static class TechNode{ + static TechNode context; + + public final Block block; + public final ItemStack[] requirements; + public final Array children = new Array<>(); + + TechNode(Block block, ItemStack[] requirements, Runnable children){ + if(context != null){ + context.children.add(this); + } + + //TODO remove requirements... for now + this.block = block; + this.requirements = requirements; + + TechNode last = context; + context = this; + children.run(); + context = last; + } + } +} diff --git a/core/src/io/anuke/mindustry/content/Weapons.java b/core/src/io/anuke/mindustry/content/Weapons.java index 1d4d3b5153..647e41ac04 100644 --- a/core/src/io/anuke/mindustry/content/Weapons.java +++ b/core/src/io/anuke/mindustry/content/Weapons.java @@ -20,7 +20,7 @@ public class Weapons implements ContentList{ blasterSmall = new Weapon("blaster"){{ length = 1.5f; - reload = 15f; + reload = 20f; roundrobin = true; ejectEffect = Fx.shellEjectSmall; ammo = Bullets.standardCopper; @@ -28,7 +28,7 @@ public class Weapons implements ContentList{ glaiveBlaster = new Weapon("bomber"){{ length = 1.5f; - reload = 10f; + reload = 13f; roundrobin = true; ejectEffect = Fx.shellEjectSmall; ammo = Bullets.standardGlaive; @@ -54,7 +54,7 @@ public class Weapons implements ContentList{ missiles = new Weapon("missiles"){{ length = 1.5f; - reload = 60f; + reload = 70f; shots = 4; inaccuracy = 2f; roundrobin = true; diff --git a/core/src/io/anuke/mindustry/content/Zones.java b/core/src/io/anuke/mindustry/content/Zones.java index 76b0f41aa9..c3fa1aeaf7 100644 --- a/core/src/io/anuke/mindustry/content/Zones.java +++ b/core/src/io/anuke/mindustry/content/Zones.java @@ -1,25 +1,207 @@ package io.anuke.mindustry.content; +import io.anuke.arc.collection.Array; import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.game.Rules; -import io.anuke.mindustry.maps.generators.BasicGenerator; +import io.anuke.mindustry.game.SpawnGroup; +import io.anuke.mindustry.maps.generators.MapGenerator; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Zone; +import io.anuke.mindustry.world.Block; public class Zones implements ContentList{ - public Zone wasteland; + public static Zone groundZero, craters, frozenForest, ruinousShores, crags, stainedMountains, + impact, desolateRift, arcticDesert, dryWastes, nuclearComplex, moltenFault; @Override public void load(){ - wasteland = new Zone("wasteland", new BasicGenerator(256, 256, Items.lead, Items.copper)){{ - deployCost = ItemStack.with(Items.copper, 100); + groundZero = new Zone("groundZero", new MapGenerator("groundZero", 1)){{ + deployCost = ItemStack.with(Items.copper, 60); startingItems = ItemStack.with(Items.copper, 50); + alwaysUnlocked = true; + conditionWave = 10; rules = () -> new Rules(){{ waves = true; waveTimer = true; - waveSpacing = 60 * 60; + waveSpacing = 60 * 60 * 2; //2 mins + spawns = Array.with( + new SpawnGroup(UnitTypes.dagger){{ + unitScaling = 2; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 10; + unitScaling = 2; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 15; + unitScaling = 1; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 20; + unitScaling = 1; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 25; + unitScaling = 1; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 30; + unitScaling = 1; + }} + ); }}; }}; + + craters = new Zone("craters", new MapGenerator("craters", 1){{ distortion = 1.44f; }}){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + itemRequirements = ItemStack.with(Items.copper, 2000); + zoneRequirements = new Zone[]{groundZero}; + blockRequirements = new Block[]{Blocks.router}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + frozenForest = new Zone("frozenForest", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + ruinousShores = new Zone("ruinousShores", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + crags = new Zone("crags", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + stainedMountains = new Zone("stainedMountains", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + impact = new Zone("impact", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + desolateRift = new Zone("desolateRift", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + arcticDesert = new Zone("arcticDesert", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + dryWastes = new Zone("dryWastes", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + nuclearComplex = new Zone("nuclearComplex", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + moltenFault = new Zone("moltenFault", new MapGenerator("groundZero", 1)){{ //TODO implement + deployCost = ItemStack.with(Items.copper, 300); + startingItems = ItemStack.with(Items.copper, 200); + conditionWave = 15; + zoneRequirements = new Zone[]{frozenForest}; + blockRequirements = new Block[]{Blocks.copperWall}; + rules = () -> new Rules(){{ + waves = true; + waveTimer = true; + waveSpacing = 60 * 80; + }}; + }}; + + frozenForest.zoneRequirements = new Zone[]{frozenForest}; } } diff --git a/core/src/io/anuke/mindustry/core/ContentLoader.java b/core/src/io/anuke/mindustry/core/ContentLoader.java index 7df856e83e..c2ce06754a 100644 --- a/core/src/io/anuke/mindustry/core/ContentLoader.java +++ b/core/src/io/anuke/mindustry/core/ContentLoader.java @@ -44,7 +44,7 @@ public class ContentLoader{ new Mechs(), new UnitTypes(), new Blocks(), - new Recipes(), + new TechTree(), new Zones(), //these are not really content classes, but this makes initialization easier @@ -165,7 +165,7 @@ public class ContentLoader{ } if(id >= contentMap[type.ordinal()].size || id < 0){ - throw new RuntimeException("No " + type.name() + " with ID '" + id + "' found!"); + return null; } return (T)contentMap[type.ordinal()].get(id); } @@ -184,14 +184,6 @@ public class ContentLoader{ return (Block) getByID(ContentType.block, id); } - public Array recipes(){ - return getBy(ContentType.recipe); - } - - public Recipe recipe(int id){ - return (Recipe) getByID(ContentType.recipe, id); - } - public Array items(){ return getBy(ContentType.item); } diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 756b759399..e9b793fc73 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -116,9 +116,16 @@ public class Control implements ApplicationListener{ //todo high scores for custom maps, as well as other statistics Events.on(GameOverEvent.class, event -> { + state.stats.wavesLasted = state.wave; Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y); //the restart dialog can show info for any number of scenarios Call.onGameOver(event.winner); + if(state.rules.zone != -1){ + //remove zone save on game over + if(saves.getZoneSlot() != null){ + saves.getZoneSlot().delete(); + } + } }); //autohost for pvp sectors @@ -133,6 +140,30 @@ public class Control implements ApplicationListener{ } } }); + + Events.on(UnlockEvent.class, e -> ui.hudfrag.showUnlock(e.content)); + + Events.on(BlockBuildEndEvent.class, e -> { + if(e.team == players[0].getTeam()){ + if(e.breaking){ + state.stats.buildingsDeconstructed++; + }else{ + state.stats.buildingsBuilt ++; + } + } + }); + + Events.on(BlockDestroyEvent.class, e -> { + if(e.tile.getTeam() == players[0].getTeam()){ + state.stats.buildingsDestroyed ++; + } + }); + + Events.on(UnitDestroyEvent.class, e -> { + if(e.unit.getTeam() != players[0].getTeam()){ + state.stats.enemyUnitsDestroyed ++; + } + }); } public void addPlayer(int index){ diff --git a/core/src/io/anuke/mindustry/core/GameState.java b/core/src/io/anuke/mindustry/core/GameState.java index 7ec682daeb..b1d19aa9ec 100644 --- a/core/src/io/anuke/mindustry/core/GameState.java +++ b/core/src/io/anuke/mindustry/core/GameState.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.core; import io.anuke.arc.Events; import io.anuke.mindustry.game.EventType.StateChangeEvent; import io.anuke.mindustry.game.Rules; +import io.anuke.mindustry.game.Stats; import io.anuke.mindustry.game.Teams; import io.anuke.mindustry.net.Net; @@ -15,9 +16,11 @@ public class GameState{ /**Wave countdown in ticks.*/ public float wavetime; /**Whether the game is in game over state.*/ - public boolean gameOver = false; + public boolean gameOver = false, launched = false; /**The current game rules.*/ public Rules rules = new Rules(); + /**Statistics for this save/game. Displayed after game over.*/ + public Stats stats = new Stats(); /**Team data. Gets reset every new game.*/ public Teams teams = new Teams(); /**Number of enemies in the game; only used clientside in servers.*/ diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 4ccedec0b7..50681fb1b4 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -11,12 +11,8 @@ import io.anuke.arc.util.Time; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.game.EventType.*; -import io.anuke.mindustry.game.Rules; -import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.game.Teams; -import io.anuke.mindustry.game.UnlockableContent; +import io.anuke.mindustry.game.*; import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.*; @@ -33,8 +29,14 @@ public class Logic implements ApplicationListener{ public Logic(){ Events.on(TileChangeEvent.class, event -> { - if(event.tile.getTeam() == defaultTeam && Recipe.getByResult(event.tile.block()) != null){ - handleContent(Recipe.getByResult(event.tile.block())); + if(event.tile.getTeam() == defaultTeam && event.tile.block().isVisible()){ + handleContent(event.tile.block()); + } + }); + + Events.on(WaveEvent.class, event -> { + if(world.isZone()){ + data.updateWaveScore(world.getZone(), state.wave); } }); } @@ -65,9 +67,11 @@ public class Logic implements ApplicationListener{ public void reset(){ state.wave = 1; state.wavetime = state.rules.waveSpacing; - state.gameOver = false; + state.gameOver = state.launched = false; state.teams = new Teams(); state.rules = new Rules(); + state.rules.spawns = Waves.getDefaultSpawns(); + state.stats = new Stats(); Time.clear(); Entities.clear(); diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index dd6d520598..1df4e182e1 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -296,7 +296,7 @@ public class NetServer implements ApplicationListener{ //auto-skip done requests if(req.breaking && world.tile(req.x, req.y).block() == Blocks.air){ continue; - }else if(!req.breaking && world.tile(req.x, req.y).block() == req.recipe.result && (!req.recipe.result.rotate || world.tile(req.x, req.y).getRotation() == req.rotation)){ + }else if(!req.breaking && world.tile(req.x, req.y).block() == req.block && (!req.block.rotate || world.tile(req.x, req.y).getRotation() == req.rotation)){ continue; } player.getPlaceQueue().addLast(req); diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index a5b237e5f0..e1db7dcfd8 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -47,7 +47,7 @@ public class UI implements ApplicationListener{ public LoadingFragment loadfrag; public AboutDialog about; - public RestartDialog restart; + public GameOverDialog restart; public CustomGameDialog levels; public MapsDialog maps; public LoadDialog load; @@ -64,16 +64,17 @@ public class UI implements ApplicationListener{ public TraceDialog traces; public ChangelogDialog changelog; public LocalPlayerDialog localplayers; - public UnlocksDialog unlocks; + public DatabaseDialog database; public ContentInfoDialog content; public DeployDialog deploy; + public TechTreeDialog tech; public Cursor drillCursor, unloadCursor; public UI(){ Skin skin = new Skin(Core.atlas); generateFonts(skin); - skin.load(Core.files.internal("ui/uiskin.json")); + skin.load(Core.files.internal("sprites/uiskin.json")); for(BitmapFont font : skin.getAll(BitmapFont.class).values()){ font.setUseIntegerPositions(true); @@ -158,13 +159,13 @@ public class UI implements ApplicationListener{ editor = new MapEditorDialog(); controls = new ControlsDialog(); - restart = new RestartDialog(); + restart = new GameOverDialog(); join = new JoinDialog(); discord = new DiscordDialog(); load = new LoadDialog(); levels = new CustomGameDialog(); language = new LanguageDialog(); - unlocks = new UnlocksDialog(); + database = new DatabaseDialog(); settings = new SettingsMenuDialog(); host = new HostDialog(); paused = new PausedDialog(); @@ -177,6 +178,7 @@ public class UI implements ApplicationListener{ localplayers = new LocalPlayerDialog(); content = new ContentInfoDialog(); deploy = new DeployDialog(); + tech = new TechTreeDialog(); Group group = Core.scene.root; @@ -236,7 +238,7 @@ public class UI implements ApplicationListener{ Table table = new Table(); table.setFillParent(true); table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor()); - table.top().add(info).padTop(8); + table.top().add(info).padTop(40); Core.scene.add(table); } diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index b0ce757754..5725acf4c4 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -5,15 +5,21 @@ import io.anuke.arc.Core; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.IntArray; +import io.anuke.arc.collection.ObjectSet.ObjectSetIterator; +import io.anuke.arc.entities.Effects; import io.anuke.arc.entities.EntityQuery; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Point2; import io.anuke.arc.util.Log; import io.anuke.arc.util.Structs; +import io.anuke.arc.util.Time; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.ai.BlockIndexer; import io.anuke.mindustry.ai.Pathfinder; import io.anuke.mindustry.ai.WaveSpawner; import io.anuke.mindustry.content.Blocks; +import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.TileChangeEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent; @@ -22,6 +28,8 @@ import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.Maps; import io.anuke.mindustry.maps.generators.Generator; +import io.anuke.mindustry.type.ContentType; +import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Zone; import io.anuke.mindustry.world.Block; @@ -178,6 +186,8 @@ public class World implements ApplicationListener{ } } + addDarkness(tiles); + EntityQuery.resizeTree(0, 0, tiles.length * tilesize, tiles[0].length * tilesize); generating = false; @@ -188,6 +198,32 @@ public class World implements ApplicationListener{ return generating; } + public void launchZone(){ + Effects.effect(Fx.launchFull, 0, 0); + + for(Tile tile : new ObjectSetIterator<>(state.teams.get(defaultTeam).cores)){ + Effects.effect(Fx.launch, tile); + } + + Time.runTask(30f, () -> { + for(Tile tile : new ObjectSetIterator<>(state.teams.get(defaultTeam).cores)){ + for(Item item : content.items()){ + data.addItem(item, tile.entity.items.get(item)); + } + world.removeBlock(tile); + } + state.launched = true; + }); + } + + public boolean isZone(){ + return getZone() != null; + } + + public Zone getZone(){ + return content.getByID(ContentType.zone, state.rules.zone); + } + public void playZone(Zone zone){ ui.loadAnd(() -> { logic.reset(); @@ -198,6 +234,8 @@ public class World implements ApplicationListener{ core.entity.items.add(stack.item, stack.amount); } } + state.rules.zone = zone.id; + control.saves.zoneSave(); logic.play(); }); } @@ -394,13 +432,60 @@ public class World implements ApplicationListener{ for(int x = 0; x < data.width(); x++){ data.read(marker); - tiles[x][y] = new Tile(x, y, marker.floor, marker.wall == Blocks.blockpart.id ? 0 : marker.wall, marker.rotation, marker.team); + tiles[x][y] = new Tile(x, y, marker.floor, marker.wall == Blocks.part.id ? 0 : marker.wall, marker.rotation, marker.team); } } prepareTiles(tiles); } + public void addDarkness(Tile[][] tiles){ + + byte[][] dark = new byte[tiles.length][tiles[0].length]; + byte[][] writeBuffer = new byte[tiles.length][tiles[0].length]; + + byte darkIterations = 4; + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ + Tile tile = tiles[x][y]; + if(tile.block().solid && !tile.block().update){ + dark[x][y] = darkIterations; + } + } + } + + for(int i = 0; i < darkIterations; i++){ + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ + boolean min = false; + for(Point2 point : Geometry.d4){ + int newX = x + point.x, newY = y + point.y; + if(Structs.inBounds(newX, newY, tiles) && dark[newX][newY] < dark[x][y]){ + min = true; + break; + } + } + writeBuffer[x][y] = (byte)Math.max(0, dark[x][y] - Mathf.num(min)); + } + } + + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ + dark[x][y] = writeBuffer[x][y]; + } + } + } + + for(int x = 0; x < tiles.length; x++){ + for(int y = 0; y < tiles[0].length; y++){ + Tile tile = tiles[x][y]; + if(tile.block().solid && !tile.block().update){ + tiles[x][y].setRotation(dark[x][y]); + } + } + } + } + /**'Prepares' a tile array by:
* - setting up multiblocks
* - updating occlusion
diff --git a/core/src/io/anuke/mindustry/editor/DrawOperation.java b/core/src/io/anuke/mindustry/editor/DrawOperation.java index 03ca6be4a1..e1b09d2325 100755 --- a/core/src/io/anuke/mindustry/editor/DrawOperation.java +++ b/core/src/io/anuke/mindustry/editor/DrawOperation.java @@ -1,70 +1,28 @@ package io.anuke.mindustry.editor; -import io.anuke.arc.collection.Array; -import io.anuke.arc.collection.IntSet; +import io.anuke.arc.collection.LongArray; import io.anuke.arc.util.Pack; public class DrawOperation{ - /** - * Data to apply operation to. - */ - private MapTileData data; - /** - * List of per-tile operations that occurred. - */ - private Array operations = new Array<>(); - /** - * Checks for duplicate operations, useful for brushes. - */ - private IntSet checks = new IntSet(); - - public DrawOperation(MapTileData data){ - this.data = data; - } + private LongArray array = new LongArray(); public boolean isEmpty(){ - return operations.size == 0; + return array.isEmpty(); } - public boolean checkDuplicate(short x, short y){ - int i = Pack.shortInt(x, y); - if(checks.contains(i)) return true; - - checks.add(i); - return false; - } - - public void addOperation(TileOperation op){ - operations.add(op); + public void addOperation(int xy, byte type, byte from, byte to){ + array.add(Pack.longInt(xy, Pack.intBytes(type, from, to, (byte)0))); } public void undo(MapEditor editor){ - for(int i = operations.size - 1; i >= 0; i--){ - TileOperation op = operations.get(i); - data.position(op.x, op.y); - data.write(op.from); - editor.renderer().updatePoint(op.x, op.y); + for(int i = 0; i < array.size; i++){ + long l = array.get(i); } } public void redo(MapEditor editor){ - for(TileOperation op : operations){ - data.position(op.x, op.y); - data.write(op.to); - editor.renderer().updatePoint(op.x, op.y); - } - } - - public static class TileOperation{ - public short x, y; - public TileDataMarker from; - public TileDataMarker to; - - public TileOperation(short x, short y, TileDataMarker from, TileDataMarker to){ - this.x = x; - this.y = y; - this.from = from; - this.to = to; + for(int i = 0; i < array.size; i++){ + long l = array.get(i); } } } diff --git a/core/src/io/anuke/mindustry/editor/EditorTool.java b/core/src/io/anuke/mindustry/editor/EditorTool.java index c773aba50e..51ac91362e 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTool.java +++ b/core/src/io/anuke/mindustry/editor/EditorTool.java @@ -14,7 +14,7 @@ import static io.anuke.mindustry.Vars.ui; public enum EditorTool{ pick{ public void touched(MapEditor editor, int x, int y){ - if(!Structs.inBounds(x, y, editor.getMap().width(), editor.getMap().height())) return; + if(!Structs.inBounds(x, y, world.width(), world.height())) return; byte bf = editor.getMap().read(x, y, DataPosition.floor); byte bw = editor.getMap().read(x, y, DataPosition.wall); @@ -54,7 +54,7 @@ public enum EditorTool{ editor.draw(x, y, Blocks.air); } }, - elevation{ + spray{ { edit = true; draggable = true; @@ -62,7 +62,7 @@ public enum EditorTool{ @Override public void touched(MapEditor editor, int x, int y){ - editor.elevate(x, y); + editor.draw(x, y, editor.getDrawBlock(), 0.012); } }, line{ @@ -82,7 +82,7 @@ public enum EditorTool{ MapTileData data; public void touched(MapEditor editor, int x, int y){ - if(!Structs.inBounds(x, y, editor.getMap().width(), editor.getMap().height())) return; + if(!Structs.inBounds(x, y, world.width(), world.height())) return; if(editor.getDrawBlock().isMultiblock()){ //don't fill multiblocks, thanks @@ -96,7 +96,6 @@ public enum EditorTool{ byte bf = data.read(x, y, DataPosition.floor); byte bw = data.read(x, y, DataPosition.wall); - be = data.read(x, y, DataPosition.elevation); boolean synth = editor.getDrawBlock().synthetic(); byte brt = Pack.byteByte((byte) editor.getDrawRotation(), (byte) editor.getDrawTeam().ordinal()); @@ -107,8 +106,8 @@ public enum EditorTool{ return; } - width = editor.getMap().width(); - int height = editor.getMap().height(); + width = world.width(); + int height = world.height(); int x1; boolean spanAbove, spanBelow; diff --git a/core/src/io/anuke/mindustry/editor/MapEditor.java b/core/src/io/anuke/mindustry/editor/MapEditor.java index 9ec4881e6f..e1fdcb7e0b 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditor.java +++ b/core/src/io/anuke/mindustry/editor/MapEditor.java @@ -9,54 +9,42 @@ import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.editor.DrawOperation.TileOperation; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; import static io.anuke.mindustry.Vars.content; +import static io.anuke.mindustry.Vars.world; public class MapEditor{ - public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15}; + public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15, 20}; - private MapTileData map; private ObjectMap tags = new ObjectMap<>(); private MapRenderer renderer = new MapRenderer(this); private int brushSize = 1; - private byte elevation; private int rotation; private Block drawBlock = Blocks.stone; private Team drawTeam = Team.blue; - public MapTileData getMap(){ - return map; - } - public ObjectMap getTags(){ return tags; } - public void beginEdit(MapTileData map, ObjectMap tags, boolean clear){ - this.map = map; + public void beginEdit(Tile[][] map, ObjectMap tags, boolean clear){ + this.brushSize = 1; this.tags = tags; if(clear){ - for(int x = 0; x < map.width(); x++){ - for(int y = 0; y < map.height(); y++){ - map.write(x, y, DataPosition.floor, Blocks.stone.id); + for(int x = 0; x < map.length; x++){ + for(int y = 0; y < map[0].length; y++){ + map[x][y].setFloor((Floor)Blocks.stone); } } } drawBlock = Blocks.stone; - renderer.resize(map.width(), map.height()); - } - - public byte getDrawElevation(){ - return elevation; - } - - public void setDrawElevation(int elevation){ - this.elevation = (byte) elevation; + renderer.resize(map.length, map[0].length); } public int getDrawRotation(){ @@ -96,19 +84,19 @@ public class MapEditor{ } public void draw(int x, int y, Block drawBlock){ - if(x < 0 || y < 0 || x >= map.width() || y >= map.height()){ - return; - } + draw(x, y, drawBlock, 1.0); + } + public void draw(int x, int y, Block drawBlock, double chance){ byte writeID = drawBlock.id; - byte partID = Blocks.blockpart.id; + byte partID = Blocks.part.id; byte rotationTeam = Pack.byteByte(drawBlock.rotate ? (byte)rotation : 0, drawBlock.synthetic() ? (byte)drawTeam.ordinal() : 0); boolean isfloor = drawBlock instanceof Floor && drawBlock != Blocks.air; if(drawBlock.isMultiblock()){ - x = Mathf.clamp(x, (drawBlock.size-1)/2, map.width() - drawBlock.size/2 - 1); - y = Mathf.clamp(y, (drawBlock.size-1)/2, map.height() - drawBlock.size/2 - 1); + x = Mathf.clamp(x, (drawBlock.size-1)/2, world.width() - drawBlock.size/2 - 1); + y = Mathf.clamp(y, (drawBlock.size-1)/2, world.height() - drawBlock.size/2 - 1); int offsetx = -(drawBlock.size - 1) / 2; int offsety = -(drawBlock.size - 1) / 2; @@ -119,7 +107,7 @@ public class MapEditor{ int worldx = dx + offsetx + x; int worldy = dy + offsety + y; - if(Structs.inBounds(worldx, worldy, map.width(), map.height())){ + if(Structs.inBounds(worldx, worldy, world.width(), world.height())){ TileDataMarker prev = getPrev(worldx, worldy, false); if(i == 1){ @@ -151,10 +139,9 @@ public class MapEditor{ onWrite(x, y, prev); }else{ - for(int rx = -brushSize; rx <= brushSize; rx++){ for(int ry = -brushSize; ry <= brushSize; ry++){ - if(Mathf.dst(rx, ry) <= brushSize - 0.5f){ + if(Mathf.dst(rx, ry) <= brushSize - 0.5f && (chance >= 0.999 || Mathf.chance(chance))){ int wx = x + rx, wy = y + ry; if(wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()){ @@ -175,7 +162,6 @@ public class MapEditor{ if(isfloor){ map.write(wx, wy, DataPosition.floor, writeID); - map.write(wx, wy, DataPosition.elevation, elevation); }else{ map.write(wx, wy, DataPosition.wall, writeID); map.write(wx, wy, DataPosition.link, (byte) 0); @@ -189,30 +175,6 @@ public class MapEditor{ } } - public void elevate(int x, int y){ - if(x < 0 || y < 0 || x >= map.width() || y >= map.height()){ - return; - } - - for(int rx = -brushSize; rx <= brushSize; rx++){ - for(int ry = -brushSize; ry <= brushSize; ry++){ - if(Mathf.dst(rx, ry) <= brushSize - 0.5f){ - int wx = x + rx, wy = y + ry; - - if(wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()){ - continue; - } - - TileDataMarker prev = getPrev(wx, wy, true); - - map.write(wx, wy, DataPosition.elevation, elevation); - - onWrite(x + rx, y + ry, prev); - } - } - } - } - private void removeLinked(int x, int y){ Block block = content.block(map.read(x, y, DataPosition.wall)); diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 841213d8e2..a1616a402e 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.editor; import io.anuke.arc.Core; +import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.files.FileHandle; import io.anuke.arc.function.Consumer; @@ -11,21 +12,21 @@ import io.anuke.arc.input.KeyCode; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.scene.actions.Actions; +import io.anuke.arc.scene.style.TextureRegionDrawable; import io.anuke.arc.scene.ui.*; -import io.anuke.arc.scene.ui.layout.Stack; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Unit; import io.anuke.arc.scene.utils.UIUtils; import io.anuke.arc.util.*; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.maps.Map; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; +import io.anuke.mindustry.world.blocks.OreBlock; import java.io.DataInputStream; import java.io.InputStream; @@ -42,6 +43,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ private FloatingDialog menu; private boolean saved = false; private boolean shownWithMap = false; + private Array blocksOut = new Array<>(); private ButtonGroup blockgroup; @@ -146,7 +148,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ }).padTop(-5).size(swidth * 2f + 10, 60f); resizeDialog = new MapResizeDialog(editor, (x, y) -> { - if(!(editor.getMap().width() == x && editor.getMap().height() == y)){ + if(!(world.width() == x && world.height() == y)){ ui.loadAnd(() -> { editor.resize(x, y); view.clearStack(); @@ -386,7 +388,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ tools.row(); addTool.accept(EditorTool.fill); - addTool.accept(EditorTool.elevation); + addTool.accept(EditorTool.spray); ImageButton rotate = tools.addImageButton("icon-arrow-16", "clear", 16 * 2f, () -> editor.setDrawRotation((editor.getDrawRotation() + 1) % 4)).get(); rotate.getImage().update(() -> { @@ -497,29 +499,21 @@ public class MapEditorDialog extends Dialog implements Disposable{ int i = 0; - for(Block block : Vars.content.blocks()){ - TextureRegion[] regions = block.getCompactIcon(); - if((block.synthetic() && (Recipe.getByResult(block) == null || !data.isUnlocked(Recipe.getByResult(block)))) - && block != Blocks.core){ - continue; - } + blocksOut.clear(); + blocksOut.addAll(Vars.content.blocks()); + blocksOut.sort((b1, b2) -> b1.synthetic() && !b2.synthetic() ? 1 : b2.synthetic() && !b1.synthetic() ? -1 : + b1 instanceof OreBlock && !(b2 instanceof OreBlock) ? 1 : !(b1 instanceof OreBlock) && b2 instanceof OreBlock ? -1 : + Integer.compare(b1.id, b2.id)); - if(Recipe.getByResult(block) != null && !Recipe.getByResult(block).visibility.shown()){ - continue; - } + for(Block block : blocksOut){ + TextureRegion region = block.icon(Icon.medium); - if(regions.length == 0 || regions[0] == Core.atlas.find("jjfgj")) continue; - - Stack stack = new Stack(); - - for(TextureRegion region : regions){ - stack.add(new Image(region)); - } + if(region == Core.atlas.find("jjfgj")) continue; ImageButton button = new ImageButton("white", "clear-toggle"); + button.getStyle().imageUp = new TextureRegionDrawable(region); button.clicked(() -> editor.setDrawBlock(block)); button.resizeImage(8 * 4f); - button.replaceImage(stack); button.update(() -> button.setChecked(editor.getDrawBlock() == block)); group.add(button); content.add(button).size(50f); diff --git a/core/src/io/anuke/mindustry/editor/MapRenderer.java b/core/src/io/anuke/mindustry/editor/MapRenderer.java index 439cd97bec..c472db4f8c 100644 --- a/core/src/io/anuke/mindustry/editor/MapRenderer.java +++ b/core/src/io/anuke/mindustry/editor/MapRenderer.java @@ -8,9 +8,11 @@ import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.util.Disposable; import io.anuke.arc.util.Pack; +import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.graphics.IndexedRenderer; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; import static io.anuke.mindustry.Vars.content; import static io.anuke.mindustry.Vars.tilesize; @@ -22,7 +24,6 @@ public class MapRenderer implements Disposable{ private IntSet delayedUpdates = new IntSet(); private MapEditor editor; private int width, height; - private Color tmpColor = Color.WHITE.cpy(); public MapRenderer(MapEditor editor){ this.editor = editor; @@ -109,33 +110,38 @@ public class MapRenderer implements Disposable{ TextureRegion region; - if(bw != 0){ - region = wall.getEditorIcon(); + int idxWall = (wx % chunksize) + (wy % chunksize) * chunksize; + int idxDecal = (wx % chunksize) + (wy % chunksize) * chunksize + chunksize * chunksize; + + if(bw != 0 && (wall.synthetic() || wall == Blocks.part)){ + region = wall.icon(Icon.full) == Core.atlas.find("____") ? Core.atlas.find("clear") : wall.icon(Icon.full); if(wall.rotate){ - mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, + mesh.draw(idxWall, region, wx * tilesize + wall.offset(), wy * tilesize + wall.offset(), region.getWidth() * Draw.scl, region.getHeight() * Draw.scl, rotation * 90 - 90); }else{ - mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, + mesh.draw(idxWall, region, wx * tilesize + wall.offset() + (tilesize - region.getWidth() * Draw.scl)/2f, wy * tilesize + wall.offset() + (tilesize - region.getHeight() * Draw.scl)/2f, region.getWidth() * Draw.scl, region.getHeight() * Draw.scl); } }else{ - region = floor.getEditorIcon(); + region = floor.icon(Icon.full); - mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, wx * tilesize, wy * tilesize, 8, 8); + mesh.draw(idxWall, region, wx * tilesize, wy * tilesize, 8, 8); } if(wall.update || wall.destructible){ mesh.setColor(team.color); region = Core.atlas.find("block-border"); + }else if(!wall.synthetic() && bw != 0){ + region = wall.icon(Icon.full) == Core.atlas.find("____") ? Core.atlas.find("clear") : wall.icon(Icon.full); }else{ region = Core.atlas.find("clear"); } - mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize + chunksize * chunksize, region, + mesh.draw(idxDecal, region, wx * tilesize - (wall.size/3) * tilesize, wy * tilesize - (wall.size/3) * tilesize, region.getWidth() * Draw.scl, region.getHeight() * Draw.scl); mesh.setColor(Color.WHITE); diff --git a/core/src/io/anuke/mindustry/editor/MapView.java b/core/src/io/anuke/mindustry/editor/MapView.java index d89fb3c248..1b6972e717 100644 --- a/core/src/io/anuke/mindustry/editor/MapView.java +++ b/core/src/io/anuke/mindustry/editor/MapView.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.editor; import io.anuke.arc.Core; import io.anuke.arc.collection.Array; +import io.anuke.arc.collection.GridBits; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; @@ -18,19 +19,19 @@ import io.anuke.arc.scene.event.Touchable; import io.anuke.arc.scene.ui.TextField; import io.anuke.arc.scene.ui.layout.Unit; import io.anuke.arc.util.Tmp; -import io.anuke.mindustry.editor.DrawOperation.TileOperation; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.ui.GridImage; +import io.anuke.mindustry.world.Pos; -import static io.anuke.mindustry.Vars.mobile; -import static io.anuke.mindustry.Vars.ui; +import static io.anuke.mindustry.Vars.*; public class MapView extends Element implements GestureListener{ private MapEditor editor; private EditorTool tool = EditorTool.pencil; private OperationStack stack = new OperationStack(); private DrawOperation op; + private GridBits used; private Bresenham2 br = new Bresenham2(); private boolean updated = false; private float offsetx, offsety; @@ -86,7 +87,12 @@ public class MapView extends Element implements GestureListener{ mousex = x; mousey = y; - op = new DrawOperation(editor.getMap()); + op = new DrawOperation(); + if(used == null || used.width() != world.width() || used.height() != world.height()){ + used = new GridBits(world.width(), world.height()); + }else{ + used.clear(); + } updated = false; @@ -146,7 +152,7 @@ public class MapView extends Element implements GestureListener{ Point2 p = project(x, y); - if(drawing && tool.draggable){ + if(drawing && tool.draggable && !(p.x == lastx && p.y == lasty)){ ui.editor.resetSaved(); Array points = br.line(lastx, lasty, p.x, p.y); for(Point2 point : points){ @@ -196,12 +202,13 @@ public class MapView extends Element implements GestureListener{ } } - public void addTileOp(TileOperation t){ - op.addOperation(t); + public void addTileOp(int xy, byte type, byte from, byte to){ + used.set(Pos.x(xy), Pos.y(xy)); + op.addOperation(xy, type, from, to); } public boolean checkForDuplicates(short x, short y){ - return op.checkDuplicate(x, y); + return used.get(x, y); } @Override @@ -227,12 +234,12 @@ public class MapView extends Element implements GestureListener{ } private Point2 project(float x, float y){ - float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height()); + float ratio = 1f / ((float) world.width() / world.height()); float size = Math.min(width, height); float sclwidth = size * zoom; float sclheight = size * zoom * ratio; - x = (x - getWidth() / 2 + sclwidth / 2 - offsetx * zoom) / sclwidth * editor.getMap().width(); - y = (y - getHeight() / 2 + sclheight / 2 - offsety * zoom) / sclheight * editor.getMap().height(); + x = (x - getWidth() / 2 + sclwidth / 2 - offsetx * zoom) / sclwidth * world.width(); + y = (y - getHeight() / 2 + sclheight / 2 - offsety * zoom) / sclheight * world.height(); if(editor.getDrawBlock().size % 2 == 0 && tool != EditorTool.eraser){ return Tmp.g1.set((int) (x - 0.5f), (int) (y - 0.5f)); @@ -242,26 +249,26 @@ public class MapView extends Element implements GestureListener{ } private Vector2 unproject(int x, int y){ - float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height()); + float ratio = 1f / ((float) world.width() / world.height()); float size = Math.min(width, height); float sclwidth = size * zoom; float sclheight = size * zoom * ratio; - float px = ((float) x / editor.getMap().width()) * sclwidth + offsetx * zoom - sclwidth / 2 + getWidth() / 2; - float py = ((float) (y) / editor.getMap().height()) * sclheight + float px = ((float) x / world.width()) * sclwidth + offsetx * zoom - sclwidth / 2 + getWidth() / 2; + float py = ((float) (y) / world.height()) * sclheight + offsety * zoom - sclheight / 2 + getHeight() / 2; return vec.set(px, py); } @Override public void draw(){ - float ratio = 1f / ((float) editor.getMap().width() / editor.getMap().height()); + float ratio = 1f / ((float) world.width() / world.height()); float size = Math.min(width, height); float sclwidth = size * zoom; float sclheight = size * zoom * ratio; float centerx = x + width / 2 + offsetx * zoom; float centery = y + height / 2 + offsety * zoom; - image.setImageSize(editor.getMap().width(), editor.getMap().height()); + image.setImageSize(world.width(), world.height()); if(!ScissorStack.pushScissors(rect.set(x, y, width, height))){ return; @@ -292,7 +299,7 @@ public class MapView extends Element implements GestureListener{ } } - float scaling = zoom * Math.min(width, height) / editor.getMap().width(); + float scaling = zoom * Math.min(width, height) / world.width(); Draw.color(Palette.accent); Lines.stroke(Unit.dp.scl(1f * zoom)); diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index c2e4ea6a52..a1dbab0c41 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -26,12 +26,14 @@ import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.io.TypeIO; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetConnection; import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity; @@ -109,6 +111,31 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra rectangle.setSize(mech.hitsize * 2f / 3f).setCenter(x, y); } + @Override + public void onRespawn(Tile tile){ + boostHeat = 1f; + achievedFlight = true; + } + + @Override + public void move(float x, float y){ + if(!mech.flying){ + EntityQuery.collisions().move(this, x, y); + }else{ + moveBy(x, y); + } + } + + @Override + public boolean collidesGrid(int x, int y){ + Tile tile = world.tile(x, y); + if(!isFlying()) return true; + if(!mech.flying && tile != null && !tile.block().synthetic() && tile.block().solid){ + return true; + } + return false; + } + @Override public float drag(){ return mech.drag; @@ -304,7 +331,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra Floor floor = getFloorOn(); Draw.color(); - Draw.alpha(hitTime / hitDuration); + Draw.alpha(Draw.getShader() != Shaders.mix ? 1f : hitTime / hitDuration); if(!mech.flying){ if(floor.isLiquid){ @@ -422,7 +449,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra Lines.stroke(2f, Palette.removeBack); float rad = Mathf.absin(Time.time(), 7f, 1f) + block.size * tilesize / 2f - 1; - Lines.square( request.x * tilesize + block.offset(), request.y * tilesize + block.offset() - 1, @@ -435,21 +461,28 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra request.y * tilesize + block.offset(), rad); }else{ - //draw place request - Lines.stroke(2f, Palette.accentBack); + float rad = Mathf.absin(Time.time(), 7f, 1f) - 1.5f + request.block.size * tilesize / 2f; - float rad = Mathf.absin(Time.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f; + //draw place request + Lines.stroke(1f, Palette.accentBack); Lines.square( - request.x * tilesize + request.recipe.result.offset(), - request.y * tilesize + request.recipe.result.offset() - 1, + request.x * tilesize + request.block.offset(), + request.y * tilesize + request.block.offset() - 1, rad); + Draw.color(); + + Draw.rect(request.block.icon(Icon.full), + request.x * tilesize + request.block.offset(), + request.y * tilesize + request.block.offset(), rad*2, rad*2, request.rotation * 90); + + Draw.color(Palette.accent); Lines.square( - request.x * tilesize + request.recipe.result.offset(), - request.y * tilesize + request.recipe.result.offset(), + request.x * tilesize + request.block.offset(), + request.y * tilesize + request.block.offset(), rad); } } diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/TileEntity.java index d570310052..97fd2beb9c 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/TileEntity.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.entities; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; +import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectSet; import io.anuke.arc.entities.Effects; @@ -16,6 +17,7 @@ import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.traits.TargetTrait; +import io.anuke.mindustry.game.EventType.BlockDestroyEvent; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.world.Block; @@ -244,6 +246,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ dead = true; Block block = tile.block(); + Events.fire(new BlockDestroyEvent(tile)); block.onDestroyed(tile); world.removeBlock(tile); block.afterDestroyed(tile, this); diff --git a/core/src/io/anuke/mindustry/entities/Unit.java b/core/src/io/anuke/mindustry/entities/Unit.java index 207c5f7087..8ee287a454 100644 --- a/core/src/io/anuke/mindustry/entities/Unit.java +++ b/core/src/io/anuke/mindustry/entities/Unit.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.entities; import io.anuke.arc.Core; +import io.anuke.arc.Events; import io.anuke.arc.entities.Effects; import io.anuke.arc.entities.impl.DestructibleEntity; import io.anuke.arc.entities.trait.DamageTrait; @@ -17,6 +18,7 @@ import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.entities.traits.*; +import io.anuke.mindustry.game.EventType.UnitDestroyEvent; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Teams.TeamData; import io.anuke.mindustry.net.Interpolator; @@ -72,6 +74,11 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ return carrier; } + @Override + public boolean collidesGrid(int x, int y){ + return !isFlying(); + } + @Override public void setCarrier(CarryTrait carrier){ this.carrier = carrier; @@ -121,6 +128,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ inventory.clear(); drownTime = 0f; status.clear(); + Events.fire(new UnitDestroyEvent(this)); } @Override @@ -217,6 +225,8 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ return tile == null ? (Floor) Blocks.air : tile.floor(); } + public void onRespawn(Tile tile){} + @Override public boolean isValid(){ return !isDead() && isAdded(); @@ -239,8 +249,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ velocity.limit(maxVelocity()).scl(1f + (status.getSpeedMultiplier()-1f) * Time.delta()); if(isFlying()){ - x += velocity.x * Time.delta(); - y += velocity.y * Time.delta(); + move(velocity.x * Time.delta(), velocity.y * Time.delta()); }else{ boolean onLiquid = floor.isLiquid; diff --git a/core/src/io/anuke/mindustry/entities/effect/Decal.java b/core/src/io/anuke/mindustry/entities/effect/Decal.java index 4181cec8f7..9bcaf7a2c3 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Decal.java +++ b/core/src/io/anuke/mindustry/entities/effect/Decal.java @@ -14,7 +14,7 @@ import static io.anuke.mindustry.Vars.groundEffectGroup; * Class for creating block rubble on the ground. */ public abstract class Decal extends TimedEntity implements BelowLiquidTrait, DrawTrait{ - private static final Color color = Color.valueOf("52504e"); + private static final Color color = Color.valueOf("3a3635"); @Override public float lifetime(){ diff --git a/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java b/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java index bc0dfaaf5e..8c32ccde94 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java +++ b/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java @@ -105,13 +105,9 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ @Override public void draw(){ - float length = fslope() * 6f; - float angle = current.set(x, y).sub(from).angle(); Lines.stroke(fslope() * 2f, Palette.accent); Lines.circle(x, y, fslope() * 2f); - Lines.lineAngleCenter(x, y, angle, length); - Lines.lineAngle(x, y, angle, fout() * 6f); Draw.color(item.color); Fill.circle(x, y, fslope() * 1.5f); diff --git a/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java b/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java index ced259f6e9..58aa066d06 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java +++ b/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java @@ -31,12 +31,16 @@ public class ScorchDecal extends Decal{ @Override public void drawDecal(){ - for(int i = 0; i < 5; i++){ TextureRegion region = regions[Mathf.randomSeed(id - i, 0, scorches - 1)]; float rotation = Mathf.randomSeed(id + i, 0, 360); float space = 1.5f + Mathf.randomSeed(id + i + 1, 0, 20) / 10f; - Draw.rect(region, x + Angles.trnsx(rotation, space), y + Angles.trnsy(rotation, space) + region.getHeight()/2f, region.getWidth()/2f, 0, rotation - 90); + Draw.rect(region, + x + Angles.trnsx(rotation, space), + y + Angles.trnsy(rotation, space) + region.getHeight()/2f*Draw.scl, + region.getWidth() * Draw.scl, + region.getHeight() * Draw.scl, + region.getWidth()/2f*Draw.scl, 0, rotation - 90); } } } diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index dc1f1ba96b..503f5d780e 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -26,7 +26,7 @@ import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Shapes; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Recipe; +import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Build; import io.anuke.mindustry.world.Pos; import io.anuke.mindustry.world.Tile; @@ -81,7 +81,7 @@ public interface BuilderTrait extends Entity{ output.writeInt(Pos.get(request.x, request.y)); output.writeFloat(request.progress); if(!request.breaking){ - output.writeByte(request.recipe.id); + output.writeByte(request.block.id); output.writeByte(request.rotation); } }else{ @@ -105,9 +105,9 @@ public interface BuilderTrait extends Entity{ if(type == 1){ //remove request = new BuildRequest(Pos.x(position), Pos.y(position)); }else{ //place - byte recipe = input.readByte(); + byte block = input.readByte(); byte rotation = input.readByte(); - request = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.recipe(recipe)); + request = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.block(block)); } request.progress = progress; @@ -129,7 +129,7 @@ public interface BuilderTrait extends Entity{ * If a place request matching this signature is present, it is removed. * Otherwise, a new place request is added to the queue. */ - default void replaceBuilding(int x, int y, int rotation, Recipe recipe){ + default void replaceBuilding(int x, int y, int rotation, Block block){ for(BuildRequest request : getPlaceQueue()){ if(request.x == x && request.y == y){ clearBuilding(); @@ -138,7 +138,7 @@ public interface BuilderTrait extends Entity{ } } - addBuildRequest(new BuildRequest(x, y, rotation, recipe)); + addBuildRequest(new BuildRequest(x, y, rotation, block)); } /**Clears the placement queue.*/ @@ -184,8 +184,8 @@ public interface BuilderTrait extends Entity{ for(BuildRequest request : removal){ if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) || (!request.breaking && - (world.tile(request.x, request.y).getRotation() == request.rotation || !request.recipe.result.rotate) - && world.tile(request.x, request.y).block() == request.recipe.result))){ + (world.tile(request.x, request.y).getRotation() == request.rotation || !request.block.rotate) + && world.tile(request.x, request.y).block() == request.block))){ getPlaceQueue().addLast(request); } } @@ -209,8 +209,8 @@ public interface BuilderTrait extends Entity{ } if(!(tile.block() instanceof BuildBlock)){ - if(canCreateBlocks() && !current.breaking && Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)){ - Build.beginPlace(unit.getTeam(), current.x, current.y, current.recipe, current.rotation); + if(canCreateBlocks() && !current.breaking && Build.validPlace(unit.getTeam(), current.x, current.y, current.block, current.rotation)){ + Build.beginPlace(unit.getTeam(), current.x, current.y, current.block, current.rotation); }else if(canCreateBlocks() && current.breaking && Build.validBreak(unit.getTeam(), current.x, current.y)){ Build.beginBreak(unit.getTeam(), current.x, current.y); }else{ @@ -264,10 +264,10 @@ public interface BuilderTrait extends Entity{ TileEntity core = unit.getClosestCore(); if(core == null || tile.block() != Blocks.air || unit.dst(tile.worldx(), tile.worldy()) > mineDistance - || tile.floor().drops == null || !unit.inventory.canAcceptItem(tile.floor().drops.item) || !canMine(tile.floor().drops.item)){ + || tile.floor().itemDrop == null || !unit.inventory.canAcceptItem(tile.floor().itemDrop) || !canMine(tile.floor().itemDrop)){ setMineTile(null); }else{ - Item item = tile.floor().drops.item; + Item item = tile.floor().itemDrop; unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(tile.worldx(), tile.worldy()), 0.4f); if(Mathf.chance(Time.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){ @@ -370,18 +370,18 @@ public interface BuilderTrait extends Entity{ /**Class for storing build requests. Can be either a place or remove request.*/ class BuildRequest{ public final int x, y, rotation; - public final Recipe recipe; + public final Block block; public final boolean breaking; public float progress; public boolean initialized; /**This creates a build request.*/ - public BuildRequest(int x, int y, int rotation, Recipe recipe){ + public BuildRequest(int x, int y, int rotation, Block block){ this.x = x; this.y = y; this.rotation = rotation; - this.recipe = recipe; + this.block = block; this.breaking = false; } @@ -390,7 +390,7 @@ public interface BuilderTrait extends Entity{ this.x = x; this.y = y; this.rotation = -1; - this.recipe = Recipe.getByResult(world.tile(x, y).block()); + this.block = world.tile(x, y).block(); this.breaking = true; } @@ -400,7 +400,7 @@ public interface BuilderTrait extends Entity{ "x=" + x + ", y=" + y + ", rotation=" + rotation + - ", recipe=" + recipe + + ", recipe=" + block + ", breaking=" + breaking + ", progress=" + progress + ", initialized=" + initialized + diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java index d212974cb2..3894e22ea5 100644 --- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java @@ -88,9 +88,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ return type.drag; } - /**Called when a command is recieved from the command center.*/ - public abstract void onCommand(UnitCommand command); - /**Initialize the type and team of this unit. Only call once!*/ public void init(UnitType type, Team team){ if(this.type != null) throw new RuntimeException("This unit is already initialized!"); diff --git a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java b/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java index a7096d80eb..fe1ecd0ff7 100644 --- a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java @@ -11,6 +11,7 @@ import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.entities.traits.CarriableTrait; import io.anuke.mindustry.entities.traits.CarryTrait; +import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockFlag; @@ -120,11 +121,8 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ }; @Override - public void onCommand(UnitCommand command){ - state.set(command == UnitCommand.retreat ? retreat : - command == UnitCommand.attack ? attack : - command == UnitCommand.patrol ? patrol : - null); + public void move(float x, float y){ + moveBy(x, y); } @Override @@ -154,7 +152,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ @Override public void draw(){ - Draw.alpha(hitTime / hitDuration); + Draw.alpha(Draw.getShader() != Shaders.mix ? 1f : hitTime / hitDuration); Draw.rect(type.name, x, y, rotation - 90); diff --git a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java b/core/src/io/anuke/mindustry/entities/units/GroundUnit.java index fe15b562ed..ae278c9c36 100644 --- a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/GroundUnit.java @@ -12,6 +12,7 @@ import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Weapon; import io.anuke.mindustry.world.Tile; @@ -78,14 +79,6 @@ public abstract class GroundUnit extends BaseUnit{ } }; - @Override - public void onCommand(UnitCommand command){ - state.set(command == UnitCommand.retreat ? retreat : - command == UnitCommand.attack ? attack : - command == UnitCommand.patrol ? patrol : - null); - } - @Override public void init(UnitType type, Team team){ super.init(type, team); @@ -140,7 +133,7 @@ public abstract class GroundUnit extends BaseUnit{ @Override public void draw(){ - Draw.alpha(hitTime / hitDuration); + Draw.alpha(Draw.getShader() != Shaders.mix ? 1f : hitTime / hitDuration); float ft = Mathf.sin(walkTime * type.speed*5f, 6f, 2f); @@ -272,7 +265,9 @@ public abstract class GroundUnit extends BaseUnit{ float angle = angleTo(targetTile); velocity.add(vec.trns(angleTo(targetTile), type.speed*Time.delta())); - rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed); + if(Units.invalidateTarget(target, this)){ + rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed); + } } protected void moveAwayFromCore(){ diff --git a/core/src/io/anuke/mindustry/entities/units/UnitCommand.java b/core/src/io/anuke/mindustry/entities/units/UnitCommand.java deleted file mode 100644 index 5939ec3aff..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/UnitCommand.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.anuke.mindustry.entities.units; - -import io.anuke.arc.Core; - -public enum UnitCommand{ - attack, retreat, patrol; - - private final String localized; - - UnitCommand(){ - localized = Core.bundle.get("command." + name()); - } - - public String localized(){ - return localized; - } -} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Drone.java b/core/src/io/anuke/mindustry/entities/units/types/Drone.java index ea0458ab54..6a7306b950 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Drone.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Drone.java @@ -13,7 +13,6 @@ import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.traits.BuilderTrait; import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.FlyingUnit; -import io.anuke.mindustry.entities.units.UnitCommand; import io.anuke.mindustry.entities.units.UnitState; import io.anuke.mindustry.game.EventType.BuildSelectEvent; import io.anuke.mindustry.gen.Call; @@ -66,13 +65,13 @@ public class Drone extends FlyingUnit implements BuilderTrait{ if(isBreaking){ getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y)); }else{ - getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.getRotation(), entity.recipe)); + getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.getRotation(), entity.block)); } } //if it's missing requirements, try and mine them - if(entity.recipe != null){ - for(ItemStack stack : entity.recipe.requirements){ + if(entity.block != null){ + for(ItemStack stack : entity.block.buildRequirements){ if(!core.items.has(stack.item, stack.amount) && type.toMine.contains(stack.item)){ targetItem = stack.item; getPlaceQueue().clear(); @@ -262,11 +261,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{ } } - @Override - public void onCommand(UnitCommand command){ - //no - } - @Override public boolean canMine(Item item){ return type.toMine.contains(item); diff --git a/core/src/io/anuke/mindustry/game/EventType.java b/core/src/io/anuke/mindustry/game/EventType.java index 32e680e4ae..ef730a377a 100644 --- a/core/src/io/anuke/mindustry/game/EventType.java +++ b/core/src/io/anuke/mindustry/game/EventType.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.game; import io.anuke.arc.Events.Event; import io.anuke.mindustry.core.GameState.State; +import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.traits.BuilderTrait; import io.anuke.mindustry.world.Tile; @@ -60,9 +61,9 @@ public class EventType{ } public static class UnlockEvent implements Event{ - public final Content content; + public final UnlockableContent content; - public UnlockEvent(Content content){ + public UnlockEvent(UnlockableContent content){ this.content = content; } } @@ -81,6 +82,18 @@ public class EventType{ } } + public static class BlockBuildEndEvent implements Event{ + public final Tile tile; + public final Team team; + public final boolean breaking; + + public BlockBuildEndEvent(Tile tile, Team team, boolean breaking){ + this.tile = tile; + this.team = team; + this.breaking = breaking; + } + } + /**Called when a player or drone begins building something. * This does not necessarily happen when a new BuildBlock is created.*/ public static class BuildSelectEvent implements Event{ @@ -97,6 +110,22 @@ public class EventType{ } } + public static class BlockDestroyEvent implements Event{ + public final Tile tile; + + public BlockDestroyEvent(Tile tile){ + this.tile = tile; + } + } + + public static class UnitDestroyEvent implements Event{ + public final Unit unit; + + public UnitDestroyEvent(Unit unit){ + this.unit = unit; + } + } + public static class ResizeEvent implements Event{ } diff --git a/core/src/io/anuke/mindustry/game/GlobalData.java b/core/src/io/anuke/mindustry/game/GlobalData.java index 80b84e6107..d12c5d1889 100644 --- a/core/src/io/anuke/mindustry/game/GlobalData.java +++ b/core/src/io/anuke/mindustry/game/GlobalData.java @@ -6,10 +6,15 @@ import io.anuke.arc.collection.ObjectIntMap; import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.collection.ObjectSet; import io.anuke.mindustry.Vars; +import io.anuke.mindustry.content.Items; +import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.UnlockEvent; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.type.Zone; + +import static io.anuke.mindustry.Vars.*; /**Stores player unlocks. Clientside only.*/ public class GlobalData{ @@ -19,11 +24,33 @@ public class GlobalData{ public GlobalData(){ Core.settings.setSerializer(ContentType.class, (stream, t) -> stream.writeInt(t.ordinal()), stream -> ContentType.values()[stream.readInt()]); + Core.settings.setSerializer(Item.class, (stream, t) -> stream.writeUTF(t.name), stream -> content.getByName(ContentType.item, stream.readUTF())); + } + + public void updateWaveScore(Zone zone, int wave){ + int value = Core.settings.getInt(zone.name + "-wave", 0); + if(value < wave){ + Core.settings.put(zone.name + "-wave", wave); + modified = true; + } + } + + public int getWaveScore(Zone zone){ + return Core.settings.getInt(zone.name + "-wave", 0); + } + + public boolean isCompleted(Zone zone){ + return getWaveScore(zone) >= zone.conditionWave; + } + + public int getItem(Item item){ + return items.get(item, 0); } public void addItem(Item item, int amount){ modified = true; items.getAndIncrement(item, 0, amount); + state.stats.itemsDelivered.getAndIncrement(item, 0, amount); } public boolean hasItems(ItemStack[] stacks){ @@ -42,37 +69,34 @@ public class GlobalData{ modified = true; } + public boolean has(Item item, int amount){ + return items.get(item, 0) >= amount; + } + public ObjectIntMap items(){ return items; } /** Returns whether or not this piece of content is unlocked yet.*/ public boolean isUnlocked(UnlockableContent content){ - return true; - //return content.alwaysUnlocked() || unlocked.getOr(content.getContentType(), ObjectSet::new).contains(content.getContentName()); + return (!state.is(State.menu) && !world.isZone()) || content.alwaysUnlocked() || unlocked.getOr(content.getContentType(), ObjectSet::new).contains(content.getContentName()); } /** * Makes this piece of content 'unlocked', if possible. * If this piece of content is already unlocked or cannot be unlocked due to dependencies, nothing changes. * Results are not saved until you call {@link #save()}. - * - * @return whether or not this content was newly unlocked. */ - public boolean unlockContent(UnlockableContent content){ - if(!content.canBeUnlocked() || content.alwaysUnlocked()) return false; - - boolean ret = unlocked.getOr(content.getContentType(), ObjectSet::new).add(content.getContentName()); + public void unlockContent(UnlockableContent content){ + if(content.alwaysUnlocked()) return; //fire unlock event so other classes can use it - if(ret){ + if(unlocked.getOr(content.getContentType(), ObjectSet::new).add(content.getContentName())){ modified = true; content.onUnlock(); Events.fire(new UnlockEvent(content)); save(); } - - return ret; } /** Clears all unlocked content. Automatically saves.*/ @@ -93,6 +117,11 @@ public class GlobalData{ for(Item item : Vars.content.items()){ items.put(item, Core.settings.getInt("item-" + item.name, 0)); } + + //set up default values + if(!Core.settings.has("item-" + Items.copper)){ + addItem(Items.copper, 500); + } } public void save(){ diff --git a/core/src/io/anuke/mindustry/game/Rules.java b/core/src/io/anuke/mindustry/game/Rules.java index 2983a5e805..ce6d1c7552 100644 --- a/core/src/io/anuke/mindustry/game/Rules.java +++ b/core/src/io/anuke/mindustry/game/Rules.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.game; import io.anuke.annotations.Annotations.Serialize; +import io.anuke.arc.collection.Array; /**Defines current rules on how the game should function. * Does not store game state, just configuration.*/ @@ -24,4 +25,8 @@ public class Rules{ public float respawnTime = 60 * 4; /**Time between waves in ticks.*/ public float waveSpacing = 60 * 60; + /**Zone ID, -1 for invalid zone.*/ + public byte zone = -1; + /**Spawn layout. Since only zones modify this, it should be assigned on save load.*/ + public transient Array spawns = new Array<>(); } diff --git a/core/src/io/anuke/mindustry/game/Saves.java b/core/src/io/anuke/mindustry/game/Saves.java index 92e2dce743..5555684cef 100644 --- a/core/src/io/anuke/mindustry/game/Saves.java +++ b/core/src/io/anuke/mindustry/game/Saves.java @@ -11,8 +11,11 @@ import io.anuke.arc.util.Time; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.StateChangeEvent; import io.anuke.mindustry.io.SaveIO; +import io.anuke.mindustry.io.SaveIO.SaveException; import io.anuke.mindustry.io.SaveMeta; import io.anuke.mindustry.maps.Map; +import io.anuke.mindustry.type.ContentType; +import io.anuke.mindustry.type.Zone; import java.io.IOException; import java.text.SimpleDateFormat; @@ -105,6 +108,16 @@ public class Saves{ return saving; } + public void zoneSave(){ + SaveSlot slot = new SaveSlot(-1); + slot.setName("zone"); + saves.remove(s -> s.index == -1); + saves.add(slot); + saveMap.put(slot.index, slot); + slot.save(); + saveSlots(); + } + public SaveSlot addSave(String name){ SaveSlot slot = new SaveSlot(nextSlot); nextSlot++; @@ -129,6 +142,11 @@ public class Saves{ return slot; } + public SaveSlot getZoneSlot(){ + SaveSlot slot = getByID(-1); + return slot == null || slot.getZone() == null ? null : slot; + } + public SaveSlot getByID(int id){ return saveMap.get(id); } @@ -153,11 +171,15 @@ public class Saves{ this.index = index; } - public void load(){ - SaveIO.loadFromSlot(index); - meta = SaveIO.getData(index); - current = this; - totalPlaytime = meta.timePlayed; + public void load() throws SaveException{ + try{ + SaveIO.loadFromSlot(index); + meta = SaveIO.getData(index); + current = this; + totalPlaytime = meta.timePlayed; + }catch(Exception e){ + throw new SaveException(e); + } } public void save(){ @@ -203,6 +225,10 @@ public class Saves{ Core.settings.save(); } + public Zone getZone(){ + return content.getByID(ContentType.zone, meta.rules.zone); + } + public int getBuild(){ return meta.build; } @@ -211,10 +237,6 @@ public class Saves{ return meta.wave; } - public Difficulty getDifficulty(){ - return meta.difficulty; - } - public boolean isAutosave(){ return Core.settings.getBool("save-" + index + "-autosave", true); } diff --git a/core/src/io/anuke/mindustry/game/SpawnGroup.java b/core/src/io/anuke/mindustry/game/SpawnGroup.java index 98640d4616..56347177c3 100644 --- a/core/src/io/anuke/mindustry/game/SpawnGroup.java +++ b/core/src/io/anuke/mindustry/game/SpawnGroup.java @@ -13,53 +13,25 @@ import io.anuke.mindustry.type.Weapon; * Each spawn group can have multiple sub-groups spawned in different areas of the map. */ public class SpawnGroup{ - /** - * The unit type spawned - */ + /**The unit type spawned*/ public final UnitType type; - /** - * When this spawn should end - */ + /**When this spawn should end*/ protected int end = Integer.MAX_VALUE; - /** - * When this spawn should start - */ + /**When this spawn should start*/ protected int begin; - /** - * The spacing, in waves, of spawns. For example, 2 = spawns every other wave - */ + /**The spacing, in waves, of spawns. For example, 2 = spawns every other wave*/ protected int spacing = 1; - /** - * Maximum amount of units that spawn - */ + /**Maximum amount of units that spawn*/ protected int max = 60; - /** - * How many waves need to pass before the amount of units spawned increases by 1 - */ + /**How many waves need to pass before the amount of units spawned increases by 1*/ protected float unitScaling = 9999f; - /** - * How many waves need to pass before the amount of instances of this group increases by 1 - */ - protected float groupScaling = 9999f; - /** - * Amount of enemies spawned initially, with no scaling - */ + /**Amount of enemies spawned initially, with no scaling*/ protected int unitAmount = 1; - /** - * Amount of enemies spawned initially, with no scaling - */ - protected int groupAmount = 1; - /** - * Weapon used by the spawned unit. Null to disable. Only applicable to ground units. - */ + /**Weapon used by the spawned unit. Null to disable. Only applicable to ground units.*/ protected Weapon weapon; - /** - * Status effect applied to the spawned unit. Null to disable. - */ + /**Status effect applied to the spawned unit. Null to disable.*/ protected StatusEffect effect; - /** - * Items this unit spawns with. Null to disable. - */ + /**Items this unit spawns with. Null to disable.*/ protected ItemStack items; public SpawnGroup(UnitType type){ @@ -75,18 +47,7 @@ public class SpawnGroup{ } float scaling = this.unitScaling; - return Math.min(unitAmount - 1 + Math.max((int) ((wave / spacing) / scaling), 1), max); - } - - /** - * Returns the amount of different unit groups at a specific wave. - */ - public int getGroupsSpawned(int wave){ - if(wave < begin || wave > end || (wave - begin) % spacing != 0){ - return 0; - } - - return Math.min(groupAmount - 1 + Math.max((int) ((wave / spacing) / groupScaling), 1), max); + return Math.min(unitAmount - 1 + Math.max((int) (((wave - begin) / spacing) / scaling), 1), max); } /** @@ -110,4 +71,20 @@ public class SpawnGroup{ return unit; } + + @Override + public String toString(){ + return "SpawnGroup{" + + "type=" + type + + ", end=" + end + + ", begin=" + begin + + ", spacing=" + spacing + + ", max=" + max + + ", unitScaling=" + unitScaling + + ", unitAmount=" + unitAmount + + ", weapon=" + weapon + + ", effect=" + effect + + ", items=" + items + + '}'; + } } diff --git a/core/src/io/anuke/mindustry/game/Stats.java b/core/src/io/anuke/mindustry/game/Stats.java new file mode 100644 index 0000000000..49c3427cd0 --- /dev/null +++ b/core/src/io/anuke/mindustry/game/Stats.java @@ -0,0 +1,23 @@ +package io.anuke.mindustry.game; + +import io.anuke.annotations.Annotations.Serialize; +import io.anuke.arc.collection.ObjectIntMap; +import io.anuke.mindustry.type.Item; + +@Serialize +public class Stats{ + /**Items delivered to global resoure counter. Zones only.*/ + public ObjectIntMap itemsDelivered = new ObjectIntMap<>(); + /**Enemy (red team) units destroyed.*/ + public int enemyUnitsDestroyed; + /**Total waves lasted.*/ + public int wavesLasted; + /**Total (ms) time lasted in this save/zone.*/ + public long timeLasted; + /**Friendly buildings fully built.*/ + public int buildingsBuilt; + /**Friendly buildings fully deconstructed.*/ + public int buildingsDeconstructed; + /**Friendly buildings destroyed.*/ + public int buildingsDestroyed; +} diff --git a/core/src/io/anuke/mindustry/game/UnlockableContent.java b/core/src/io/anuke/mindustry/game/UnlockableContent.java index 3786604b53..c2bf0caea7 100644 --- a/core/src/io/anuke/mindustry/game/UnlockableContent.java +++ b/core/src/io/anuke/mindustry/game/UnlockableContent.java @@ -3,8 +3,6 @@ package io.anuke.mindustry.game; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.scene.ui.layout.Table; -import static io.anuke.mindustry.Vars.data; - /**Base interface for an unlockable content type.*/ public abstract class UnlockableContent extends MappableContent{ /**Returns the localized name of this content.*/ @@ -28,24 +26,4 @@ public abstract class UnlockableContent extends MappableContent{ public boolean alwaysUnlocked(){ return false; } - - /**Lists the content that must be unlocked in order for this specific content to become unlocked. May return null.*/ - public UnlockableContent[] getDependencies(){ - return null; - } - - /**Returns whether dependencies are satisfied for unlocking this content.*/ - public boolean canBeUnlocked(){ - UnlockableContent[] depend = getDependencies(); - if(depend == null){ - return true; - }else{ - for(UnlockableContent cont : depend){ - if(!data.isUnlocked(cont)){ - return false; - } - } - return true; - } - } } diff --git a/core/src/io/anuke/mindustry/game/Waves.java b/core/src/io/anuke/mindustry/game/Waves.java index d05a2f9aa3..3b6355c2c8 100644 --- a/core/src/io/anuke/mindustry/game/Waves.java +++ b/core/src/io/anuke/mindustry/game/Waves.java @@ -8,9 +8,11 @@ import io.anuke.mindustry.content.Weapons; import io.anuke.mindustry.type.ItemStack; public class Waves{ + private static Array spawns; - public static Array getSpawns(){ - return Array.with( + public static Array getDefaultSpawns(){ + if(spawns == null){ + spawns = Array.with( new SpawnGroup(UnitTypes.dagger){{ end = 8; unitScaling = 3; @@ -82,7 +84,6 @@ public class Waves{ begin = 82; spacing = 3; unitAmount = 4; - groupAmount = 2; unitScaling = 3; effect = StatusEffects.overdrive; }}, @@ -108,7 +109,6 @@ public class Waves{ begin = 35; spacing = 3; unitAmount = 4; - groupAmount = 2; effect = StatusEffects.overdrive; items = new ItemStack(Items.blastCompound, 60); end = 60; @@ -118,7 +118,6 @@ public class Waves{ begin = 42; spacing = 3; unitAmount = 4; - groupAmount = 2; effect = StatusEffects.overdrive; items = new ItemStack(Items.pyratite, 100); end = 130; @@ -137,7 +136,6 @@ public class Waves{ unitAmount = 4; unitScaling = 3; spacing = 5; - groupAmount = 2; effect = StatusEffects.overdrive; max = 8; }}, @@ -147,7 +145,6 @@ public class Waves{ unitAmount = 4; unitScaling = 3; spacing = 5; - groupAmount = 2; max = 8; }}, @@ -168,16 +165,17 @@ public class Waves{ max = 8; end = 74; }} - ); + ); + } + return spawns; } - public static void testWaves(int from, int to){ - Array spawns = getSpawns(); + public static void testWaves(Array spawns, int from, int to){ for(int i = from; i <= to; i++){ System.out.print(i + ": "); int total = 0; for(SpawnGroup spawn : spawns){ - int a = spawn.getUnitsSpawned(i) * spawn.getGroupsSpawned(i); + int a = spawn.getUnitsSpawned(i); total += a; if(a > 0){ diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 4552f3e1c3..8da7a2280b 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -4,11 +4,14 @@ import io.anuke.arc.Core; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.Sort; +import io.anuke.arc.entities.EntityDraw; +import io.anuke.arc.entities.EntityGroup; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.glutils.FrameBuffer; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.content.Blocks; +import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.game.EventType.TileChangeEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.game.Team; @@ -57,7 +60,7 @@ public class BlockRenderer{ public void drawShadows(){ if(disableShadows) return; - if(shadows.getWidth() != Core.graphics.getWidth() || shadows.getHeight() != Core.graphics.getHeight()){ + if(!Core.graphics.isHidden() && (shadows.getWidth() != Core.graphics.getWidth() || shadows.getHeight() != Core.graphics.getHeight())){ shadows.resize(Core.graphics.getWidth(), Core.graphics.getHeight()); } @@ -70,7 +73,16 @@ public class BlockRenderer{ shadows.begin(); Core.graphics.clear(Color.CLEAR); Draw.color(shadowColor); + floor.beginDraw(); + floor.drawLayer(CacheLayer.walls); + floor.endDraw(); drawBlocks(Layer.shadow); + + EntityDraw.drawWith(playerGroup, player -> !player.isDead(), Unit::draw); + for(EntityGroup group : unitGroups){ + EntityDraw.drawWith(group, unit -> !unit.isDead(), Unit::draw); + } + Draw.color(); Draw.flush(); shadows.end(); @@ -110,11 +122,11 @@ public class BlockRenderer{ Tile tile = world.rawTile(x, y); Block block = tile.block(); - if(!expanded && block != Blocks.air && world.isAccessible(x, y)){ + if(!expanded && block != Blocks.air && block.cacheLayer == CacheLayer.normal && world.isAccessible(x, y)){ tile.block().drawShadow(tile); } - if(block != Blocks.air){ + if(block != Blocks.air && block.cacheLayer == CacheLayer.normal){ if(!expanded){ addRequest(tile, Layer.shadow); addRequest(tile, Layer.block); @@ -139,6 +151,10 @@ public class BlockRenderer{ lastCamY = avgy; lastRangeX = rangex; lastRangeY = rangey; + + floor.beginDraw(); + floor.drawLayer(CacheLayer.walls); + floor.endDraw(); } public void drawBlocks(Layer stopAt){ @@ -154,8 +170,13 @@ public class BlockRenderer{ if(req.layer == Layer.shadow){ block.drawShadow(req.tile); - }else if(req.layer == Layer.block){ + }else if(req.layer == Layer.block){ block.draw(req.tile); + if(block.synthetic() && req.tile.getTeam() != players[0].getTeam()){ + Draw.color(req.tile.getTeam().color); + Draw.rect("block-border", req.tile.drawx() - block.size * tilesize/2f + 4, req.tile.drawy() - block.size * tilesize/2f + 4); + Draw.color(); + } }else if(req.layer == block.layer){ block.drawLayer(req.tile); }else if(req.layer == block.layer2){ diff --git a/core/src/io/anuke/mindustry/graphics/CacheLayer.java b/core/src/io/anuke/mindustry/graphics/CacheLayer.java index bd1d1a88c9..dca1a53df7 100644 --- a/core/src/io/anuke/mindustry/graphics/CacheLayer.java +++ b/core/src/io/anuke/mindustry/graphics/CacheLayer.java @@ -1,5 +1,6 @@ package io.anuke.mindustry.graphics; +//TODO implement effects again public enum CacheLayer{ water{ }, @@ -9,7 +10,9 @@ public enum CacheLayer{ }, space{ }, - normal; + normal, + walls{ //TODO implement walls + }; public void begin(){ diff --git a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java index 97165b9a00..115615b682 100644 --- a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java @@ -22,7 +22,8 @@ import io.anuke.mindustry.world.blocks.Floor; import java.util.Arrays; -import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.Vars.tilesize; +import static io.anuke.mindustry.Vars.world; public class FloorRenderer{ private final static int chunksize = 64; @@ -156,7 +157,11 @@ public class FloorRenderer{ Tile tile = world.tile(tilex, tiley); if(tile != null){ - used.add(tile.floor().cacheLayer); + if(tile.block().cacheLayer != CacheLayer.normal){ + used.add(tile.block().cacheLayer); + }else{ + used.add(tile.floor().cacheLayer); + } } } } @@ -183,7 +188,9 @@ public class FloorRenderer{ floor = tile.floor(); } - if(floor.cacheLayer == layer){ + if(tile.block().cacheLayer == layer && layer == CacheLayer.walls){ + tile.block().draw(tile); + }else if(floor.cacheLayer == layer && tile.block().cacheLayer != CacheLayer.walls){ floor.draw(tile); } } diff --git a/core/src/io/anuke/mindustry/graphics/IndexedRenderer.java b/core/src/io/anuke/mindustry/graphics/IndexedRenderer.java index a05bec2c6d..c082b7c8a9 100644 --- a/core/src/io/anuke/mindustry/graphics/IndexedRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/IndexedRenderer.java @@ -40,7 +40,7 @@ public class IndexedRenderer implements Disposable{ program.setUniformMatrix4("u_projTrans", BatchShader.copyTransform(combined)); program.setUniformi("u_texture", 0); - mesh.render(program, GL20.GL_TRIANGLES, 0, vertices.length / 5); + mesh.render(program, GL20.GL_TRIANGLES, 0, vertices.length / vsize); program.end(); } @@ -187,14 +187,6 @@ public class IndexedRenderer implements Disposable{ return transMatrix; } - public void setTransformMatrix(Matrix3 matrix){ - transMatrix = matrix; - } - - public Matrix3 getProjectionMatrix(){ - return projMatrix; - } - public void setProjectionMatrix(Matrix3 matrix){ projMatrix = matrix; } diff --git a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java index 9342f85e2d..0f133e6b90 100644 --- a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java @@ -88,6 +88,8 @@ public class MinimapRenderer implements Disposable{ } Draw.color(); + + ScissorStack.popScissors(); } public TextureRegion getRegion(){ diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index 61d9400df1..6211e4ee35 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -89,7 +89,7 @@ public class OverlayRenderer{ Draw.reset(); //draw selected block bars and info - if(input.recipe == null && !Core.scene.hasMouse()){ + if(input.block == null && !Core.scene.hasMouse()){ Vector2 vec = Core.input.mouseWorld(input.getMouseX(), input.getMouseY()); Tile tile = world.tileWorld(vec.x, vec.y); diff --git a/core/src/io/anuke/mindustry/graphics/Palette.java b/core/src/io/anuke/mindustry/graphics/Palette.java index 0ffcf551be..4483f9c281 100644 --- a/core/src/io/anuke/mindustry/graphics/Palette.java +++ b/core/src/io/anuke/mindustry/graphics/Palette.java @@ -38,13 +38,11 @@ public class Palette{ stoneGray = Color.valueOf("8f8f8f"), - portalLight = Color.valueOf("9054ea"), - portal = Color.valueOf("6344d7"), - portalDark = Color.valueOf("3f3dac"), - + health = Color.valueOf("ff341c"), heal = Color.valueOf("98ffa9"), bar = Color.SLATE, accent = Color.valueOf("ffd37f"), + locked = Color.valueOf("989aa4"), accentBack = Color.valueOf("d4816b"), place = Color.valueOf("6335f8"), remove = Color.valueOf("e55454"), @@ -54,7 +52,7 @@ public class Palette{ range = Color.valueOf("f4ba6e"), power = Color.valueOf("fbad67"), powerLight = Color.valueOf("fbd367"), - placing = Color.valueOf("616161"), + placing = accent, lightTrail = Color.valueOf("ffe2a9"), diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 84e23a5d00..02c212da5c 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -15,6 +15,7 @@ import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult; import io.anuke.mindustry.input.PlaceUtils.NormalizeResult; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.*; @@ -45,13 +46,10 @@ public class DesktopInput extends InputHandler{ if(validPlace(x, y, block, rotation)){ Draw.color(); - TextureRegion[] regions = block.getBlockIcon(); - - for(TextureRegion region : regions){ - Draw.rect(region, x * tilesize + block.offset(), y * tilesize + block.offset(), - region.getWidth() * selectScale * Draw.scl, - region.getHeight() * selectScale * Draw.scl, block.rotate ? rotation * 90 : 0); - } + TextureRegion region = block.icon(Icon.full); + Draw.rect(region, x * tilesize + block.offset(), y * tilesize + block.offset(), + region.getWidth() * selectScale * Draw.scl, + region.getHeight() * selectScale * Draw.scl, block.rotate ? rotation * 90 : 0); }else{ Draw.color(Palette.removeBack); Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset() - 1, block.size * tilesize / 2f); @@ -62,7 +60,7 @@ public class DesktopInput extends InputHandler{ @Override public boolean isDrawing(){ - return mode != none || recipe != null; + return mode != none || block != null; } @Override @@ -72,22 +70,30 @@ public class DesktopInput extends InputHandler{ int cursorY = tileY(Core.input.mouseY()); //draw selection(s) - if(mode == placing && recipe != null){ + if(mode == placing && block != null){ NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursorX, cursorY, rotation, true, maxLength); - for(int i = 0; i <= result.getLength(); i += recipe.result.size){ + for(int i = 0; i <= result.getLength(); i += block.size){ int x = selectX + i * Mathf.sign(cursorX - selectX) * Mathf.num(result.isX()); int y = selectY + i * Mathf.sign(cursorY - selectY) * Mathf.num(!result.isX()); - if(i + recipe.result.size > result.getLength() && recipe.result.rotate){ - Draw.color(!validPlace(x, y, recipe.result, result.rotation) ? Palette.remove : Palette.placeRotate); - Draw.rect(Core.atlas.find("place-arrow"), x * tilesize + recipe.result.offset(), - y * tilesize + recipe.result.offset(), - Core.atlas.find("place-arrow").getWidth() * Draw.scl, Core.atlas.find("place-arrow").getHeight() * Draw.scl, - x * tilesize + recipe.result.offset()/2f, 0f, result.rotation * 90 - 90); + if(i + block.size > result.getLength() && block.rotate){ + Draw.color(!validPlace(x, y, block, result.rotation) ? Palette.removeBack : Palette.accentBack); + Draw.rect(Core.atlas.find("place-arrow"), + x * tilesize + block.offset(), + y * tilesize + block.offset() - 1, + Core.atlas.find("place-arrow").getWidth() * Draw.scl, + Core.atlas.find("place-arrow").getHeight() * Draw.scl, result.rotation * 90 - 90); + + Draw.color(!validPlace(x, y, block, result.rotation) ? Palette.remove : Palette.accent); + Draw.rect(Core.atlas.find("place-arrow"), + x * tilesize + block.offset(), + y * tilesize + block.offset(), + Core.atlas.find("place-arrow").getWidth() * Draw.scl, + Core.atlas.find("place-arrow").getHeight() * Draw.scl, result.rotation * 90 - 90); } - drawPlace(x, y, recipe.result, result.rotation); + drawPlace(x, y, block, result.rotation); } Draw.reset(); @@ -113,16 +119,23 @@ public class DesktopInput extends InputHandler{ Draw.color(Palette.remove); Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y); }else if(isPlacing()){ - if(recipe.result.rotate){ - Draw.color(!validPlace(cursorX, cursorY, recipe.result, rotation) ? Palette.remove : Palette.placeRotate); - Draw.rect(Core.atlas.find("place-arrow"), cursorX * tilesize + recipe.result.offset(), - cursorY * tilesize + recipe.result.offset(), - Core.atlas.find("place-arrow").getWidth() * Draw.scl, - Core.atlas.find("place-arrow").getHeight() * Draw.scl, - cursorX * tilesize + recipe.result.offset()/2f, 0, rotation * 90 - 90); + if(block.rotate){ + Draw.color(!validPlace(cursorX, cursorY, block, rotation) ? Palette.removeBack : Palette.accentBack); + Draw.rect(Core.atlas.find("place-arrow"), + cursorX * tilesize + block.offset(), + cursorY * tilesize + block.offset() - 1, + Core.atlas.find("place-arrow").getWidth() * Draw.scl, + Core.atlas.find("place-arrow").getHeight() * Draw.scl, rotation * 90 - 90); + + Draw.color(!validPlace(cursorX, cursorY, block, rotation) ? Palette.remove : Palette.accent); + Draw.rect(Core.atlas.find("place-arrow"), + cursorX * tilesize + block.offset(), + cursorY * tilesize + block.offset(), + Core.atlas.find("place-arrow").getWidth() * Draw.scl, + Core.atlas.find("place-arrow").getHeight() * Draw.scl, rotation * 90 - 90); } - drawPlace(cursorX, cursorY, recipe.result, rotation); - recipe.result.drawPlace(cursorX, cursorY, rotation, validPlace(cursorX, cursorY, recipe.result, rotation)); + drawPlace(cursorX, cursorY, block, rotation); + block.drawPlace(cursorX, cursorY, rotation, validPlace(cursorX, cursorY, block, rotation)); } Draw.reset(); @@ -167,7 +180,7 @@ public class DesktopInput extends InputHandler{ selectScale = 0f; } - rotation = Mathf.mod(rotation + (int) Core.input.axis(Binding.rotate), 4); + rotation = Mathf.mod(rotation + (int) Core.input.axisTap(Binding.rotate), 4); Tile cursor = tileAt(Core.input.mouseX(), Core.input.mouseY()); @@ -221,13 +234,13 @@ public class DesktopInput extends InputHandler{ }else if(!ui.chatfrag.chatOpen()){ //if it's out of bounds, shooting is just fine player.isShooting = true; } - }else if(Core.input.keyTap(Binding.deselect) && (recipe != null || mode != none || player.isBuilding()) && + }else if(Core.input.keyTap(Binding.deselect) && (block != null || mode != none || player.isBuilding()) && !(player.getCurrentRequest() != null && player.getCurrentRequest().breaking && Core.keybinds.get(Binding.deselect) == Core.keybinds.get(Binding.break_block))){ - if(recipe == null){ + if(block == null){ player.clearBuilding(); } - recipe = null; + block = null; mode = none; }else if(Core.input.keyTap(Binding.break_block) && !Core.scene.hasMouse()){ //is recalculated because setting the mode to breaking removes potential multiblock cursor offset @@ -239,10 +252,10 @@ public class DesktopInput extends InputHandler{ if(Core.input.keyRelease(Binding.break_block) || Core.input.keyRelease(Binding.select)){ - if(mode == placing && recipe != null){ //touch up while placing, place everything in selection + if(mode == placing && block != null){ //touch up while placing, place everything in selection NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursorX, cursorY, rotation, true, maxLength); - for(int i = 0; i <= result.getLength(); i += recipe.result.size){ + for(int i = 0; i <= result.getLength(); i += block.size){ int x = selectX + i * Mathf.sign(cursorX - selectX) * Mathf.num(result.isX()); int y = selectY + i * Mathf.sign(cursorY - selectY) * Mathf.num(!result.isX()); @@ -286,11 +299,6 @@ public class DesktopInput extends InputHandler{ return !controlling ? Core.input.mouseY() : controly; } - @Override - public boolean isCursorVisible(){ - return controlling; - } - @Override public void updateController(){ diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index c5b54dcb7d..11a1fa8a56 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -21,7 +21,6 @@ import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.ValidateException; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.ui.fragments.OverlayFragment; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Build; @@ -41,7 +40,7 @@ public abstract class InputHandler implements InputProcessor{ public final Player player; public final OverlayFragment frag = new OverlayFragment(this); - public Recipe recipe; + public Block block; public int rotation; public boolean droppingItem; @@ -130,14 +129,6 @@ public abstract class InputHandler implements InputProcessor{ return Core.input.mouseY(); } - public void resetCursor(){ - - } - - public boolean isCursorVisible(){ - return false; - } - public void buildUI(Table table){ } @@ -162,7 +153,7 @@ public abstract class InputHandler implements InputProcessor{ boolean tileTapped(Tile tile){ tile = tile.target(); - boolean consumed = false, showedInventory = false, showedConsume = false; + boolean consumed = false, showedInventory = false; //check if tapped block is configurable if(tile.block().configurable && tile.getTeam() == player.getTeam()){ @@ -207,7 +198,7 @@ public abstract class InputHandler implements InputProcessor{ if(!consumed && player.isBuilding()){ player.clearBuilding(); - recipe = null; + block = null; return true; } @@ -239,9 +230,9 @@ public abstract class InputHandler implements InputProcessor{ boolean canMine(Tile tile){ return !Core.scene.hasMouse() - && tile.floor().drops != null && tile.floor().drops.item.hardness <= player.mech.drillPower + && tile.floor().itemDrop != null && tile.floor().itemDrop.hardness <= player.mech.drillPower && !tile.floor().playerUnmineable - && player.inventory.canAcceptItem(tile.floor().drops.item) + && player.inventory.canAcceptItem(tile.floor().itemDrop) && tile.block() == Blocks.air && player.dst(tile.worldx(), tile.worldy()) <= Player.mineDistance; } @@ -253,7 +244,7 @@ public abstract class InputHandler implements InputProcessor{ int tileX(float cursorX){ Vector2 vec = Core.input.mouseWorld(cursorX, 0); if(selectedBlock()){ - vec.sub(recipe.result.offset(), recipe.result.offset()); + vec.sub(block.offset(), block.offset()); } return world.toTile(vec.x); } @@ -261,7 +252,7 @@ public abstract class InputHandler implements InputProcessor{ int tileY(float cursorY){ Vector2 vec = Core.input.mouseWorld(0, cursorY); if(selectedBlock()){ - vec.sub(recipe.result.offset(), recipe.result.offset()); + vec.sub(block.offset(), block.offset()); } return world.toTile(vec.y); } @@ -271,7 +262,7 @@ public abstract class InputHandler implements InputProcessor{ } public boolean isPlacing(){ - return recipe != null; + return block != null; } public float mouseAngle(float x, float y){ @@ -284,7 +275,7 @@ public abstract class InputHandler implements InputProcessor{ } public boolean canShoot(){ - return recipe == null && !Core.scene.hasMouse() && !onConfigurable() && !isDroppingItem(); + return block == null && !Core.scene.hasMouse() && !onConfigurable() && !isDroppingItem(); } public boolean onConfigurable(){ @@ -317,8 +308,8 @@ public abstract class InputHandler implements InputProcessor{ } public void tryPlaceBlock(int x, int y){ - if(recipe != null && validPlace(x, y, recipe.result, rotation) && cursorNear()){ - placeBlock(x, y, recipe, rotation); + if(block != null && validPlace(x, y, block, rotation) && cursorNear()){ + placeBlock(x, y, block, rotation); } } @@ -329,20 +320,16 @@ public abstract class InputHandler implements InputProcessor{ } public boolean validPlace(int x, int y, Block type, int rotation){ - for(Tile tile : state.teams.get(player.getTeam()).cores){ - return Build.validPlace(player.getTeam(), x, y, type, rotation) && - Mathf.dst(player.x, player.y, x * tilesize, y * tilesize) < Player.placeDistance; - } - - return false; + return Build.validPlace(player.getTeam(), x, y, type, rotation) && + Mathf.dst(player.x, player.y, x * tilesize, y * tilesize) < Player.placeDistance; } public boolean validBreak(int x, int y){ return Build.validBreak(player.getTeam(), x, y) && Mathf.dst(player.x, player.y, x * tilesize, y * tilesize) < Player.placeDistance; } - public void placeBlock(int x, int y, Recipe recipe, int rotation){ - player.addBuildRequest(new BuildRequest(x, y, rotation, recipe)); + public void placeBlock(int x, int y, Block block, int rotation){ + player.addBuildRequest(new BuildRequest(x, y, rotation, block)); } public void breakBlock(int x, int y){ diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index ec4eb82b68..d2a0963c49 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -30,9 +30,9 @@ import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult; import io.anuke.mindustry.input.PlaceUtils.NormalizeResult; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.*; @@ -72,7 +72,7 @@ public class MobileInput extends InputHandler implements GestureListener{ /** Current place mode. */ private PlaceMode mode = none; /** Whether no recipe was available when switching to break mode. */ - private Recipe lastRecipe; + private Block lastBlock; /** Last placed request. Used for drawing block overlay. */ private PlaceRequest lastPlaced; @@ -120,8 +120,8 @@ public class MobileInput extends InputHandler implements GestureListener{ if(other == null || req.remove) continue; - r1.setSize(req.recipe.result.size * tilesize); - r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset()); + r1.setSize(req.block.size * tilesize); + r1.setCenter(other.worldx() + req.block.offset(), other.worldy() + req.block.offset()); if(r2.overlaps(r1)){ return true; @@ -141,8 +141,8 @@ public class MobileInput extends InputHandler implements GestureListener{ if(other == null) continue; if(!req.remove){ - r1.setSize(req.recipe.result.size * tilesize); - r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset()); + r1.setSize(req.block.size * tilesize); + r1.setCenter(other.worldx() + req.block.offset(), other.worldy() + req.block.offset()); if(r2.overlaps(r1)){ return req; @@ -170,18 +170,16 @@ public class MobileInput extends InputHandler implements GestureListener{ if(!request.remove){ //draw placing request - float offset = request.recipe.result.offset(); - TextureRegion[] regions = request.recipe.result.getBlockIcon(); + float offset = request.block.offset(); + TextureRegion region = request.block.icon(Icon.full); Draw.alpha(Mathf.clamp((1f - request.scale) / 0.5f)); Draw.tint(Color.WHITE, Palette.breakInvalid, request.redness); - for(TextureRegion region : regions){ - Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset, - region.getWidth() * request.scale * Draw.scl, - region.getHeight() * request.scale * Draw.scl, - request.recipe.result.rotate ? request.rotation * 90 : 0); - } + Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset, + region.getWidth() * request.scale * Draw.scl, + region.getHeight() * request.scale * Draw.scl, + request.block.rotate ? request.rotation * 90 : 0); }else{ float rad = (tile.block().size * tilesize / 2f - 1) * request.scale; Draw.alpha(0f); @@ -220,8 +218,8 @@ public class MobileInput extends InputHandler implements GestureListener{ table.left().margin(0f).defaults().size(48f); table.addImageButton("icon-break", "clear-toggle-partial", 16 * 2f, () -> { - mode = mode == breaking ? recipe == null ? none : placing : breaking; - lastRecipe = recipe; + mode = mode == breaking ? block == null ? none : placing : breaking; + lastBlock = block; if(mode == breaking){ showGuide("deconstruction"); } @@ -231,13 +229,13 @@ public class MobileInput extends InputHandler implements GestureListener{ table.addImageButton("icon-cancel", "clear-partial", 16 * 2f, () -> { player.clearBuilding(); mode = none; - recipe = null; - }).visible(() -> player.isBuilding() || recipe != null || mode == breaking); + block = null; + }).visible(() -> player.isBuilding() || block != null || mode == breaking); //rotate button table.addImageButton("icon-arrow", "clear-partial", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4)) .update(i -> i.getImage().setRotationOrigin(rotation * 90, Align.center)) - .visible(() -> recipe != null && recipe.result.rotate); + .visible(() -> block != null && block.rotate); //confirm button table.addImageButton("icon-check", "clear-partial", 16 * 2f, () -> { @@ -248,10 +246,10 @@ public class MobileInput extends InputHandler implements GestureListener{ if(tile != null){ if(!request.remove){ rotation = request.rotation; - Recipe before = recipe; - recipe = request.recipe; + Block before = block; + block = request.block; tryPlaceBlock(tile.x, tile.y); - recipe = before; + block = before; }else{ tryBreakBlock(tile.x, tile.y); } @@ -300,7 +298,7 @@ public class MobileInput extends InputHandler implements GestureListener{ if(tile == null) continue; - if((!request.remove && validPlace(tile.x, tile.y, request.recipe.result, request.rotation)) + if((!request.remove && validPlace(tile.x, tile.y, request.block, request.rotation)) || (request.remove && validBreak(tile.x, tile.y))){ request.scale = Mathf.lerpDelta(request.scale, 1f, 0.2f); request.redness = Mathf.lerpDelta(request.redness, 0f, 0.2f); @@ -313,8 +311,8 @@ public class MobileInput extends InputHandler implements GestureListener{ drawRequest(request); //draw last placed request - if(!request.remove && request == lastPlaced && request.recipe != null){ - request.recipe.result.drawPlace(tile.x, tile.y, rotation, validPlace(tile.x, tile.y, request.recipe.result, rotation)); + if(!request.remove && request == lastPlaced && request.block != null){ + request.block.drawPlace(tile.x, tile.y, rotation, validPlace(tile.x, tile.y, request.block, rotation)); } } @@ -328,34 +326,32 @@ public class MobileInput extends InputHandler implements GestureListener{ int tileY = tileY(Core.input.mouseY()); //draw placing - if(mode == placing && recipe != null){ - NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(recipe.result, lineStartX, lineStartY, tileX, tileY, true, maxLength, lineScale); + if(mode == placing && block != null){ + NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(block, lineStartX, lineStartY, tileX, tileY, true, maxLength, lineScale); Lines.rect(dresult.x, dresult.y, dresult.x2 - dresult.x, dresult.y2 - dresult.y); NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tileX, tileY, rotation, true, maxLength); //go through each cell and draw the block to place if valid - for(int i = 0; i <= result.getLength(); i += recipe.result.size){ + for(int i = 0; i <= result.getLength(); i += block.size){ int x = lineStartX + i * Mathf.sign(tileX - lineStartX) * Mathf.num(result.isX()); int y = lineStartY + i * Mathf.sign(tileY - lineStartY) * Mathf.num(!result.isX()); - if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){ + if(!checkOverlapPlacement(x, y, block) && validPlace(x, y, block, result.rotation)){ Draw.color(); - TextureRegion[] regions = recipe.result.getBlockIcon(); + TextureRegion region = block.icon(Icon.full); - for(TextureRegion region : regions){ - Draw.rect(region, x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), - region.getWidth() * lineScale * Draw.scl, - region.getHeight() * lineScale * Draw.scl, - recipe.result.rotate ? result.rotation * 90 : 0); - } + Draw.rect(region, x * tilesize + block.offset(), y * tilesize + block.offset(), + region.getWidth() * lineScale * Draw.scl, + region.getHeight() * lineScale * Draw.scl, + block.rotate ? result.rotation * 90 : 0); }else{ Draw.color(Palette.removeBack); - Lines.square(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset() - 1, recipe.result.size * tilesize / 2f); + Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset() - 1, block.size * tilesize / 2f); Draw.color(Palette.remove); - Lines.square(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), recipe.result.size * tilesize / 2f); + Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset(), block.size * tilesize / 2f); } } @@ -444,7 +440,7 @@ public class MobileInput extends InputHandler implements GestureListener{ int tileX = tileX(screenX); int tileY = tileY(screenY); - if(mode == placing && recipe != null){ + if(mode == placing && block != null){ //normalize area NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tileX, tileY, rotation, true, 100); @@ -452,12 +448,12 @@ public class MobileInput extends InputHandler implements GestureListener{ rotation = result.rotation; //place blocks on line - for(int i = 0; i <= result.getLength(); i += recipe.result.size){ + for(int i = 0; i <= result.getLength(); i += block.size){ int x = lineStartX + i * Mathf.sign(tileX - lineStartX) * Mathf.num(result.isX()); int y = lineStartY + i * Mathf.sign(tileY - lineStartY) * Mathf.num(!result.isX()); - if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){ - PlaceRequest request = new PlaceRequest(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), recipe, result.rotation); + if(!checkOverlapPlacement(x, y, block) && validPlace(x, y, block, result.rotation)){ + PlaceRequest request = new PlaceRequest(x * tilesize + block.offset(), y * tilesize + block.offset(), block, result.rotation); request.scale = 1f; selection.add(request); } @@ -520,8 +516,8 @@ public class MobileInput extends InputHandler implements GestureListener{ if(mode == breaking){ Effects.effect(Fx.tapBlock, cursor.worldx(), cursor.worldy(), 1f); - }else if(recipe != null){ - Effects.effect(Fx.tapBlock, cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe.result.size); + }else if(block != null){ + Effects.effect(Fx.tapBlock, cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block.size); } return false; @@ -544,9 +540,9 @@ public class MobileInput extends InputHandler implements GestureListener{ //remove if request present if(hasRequest(cursor)){ removeRequest(getRequest(cursor)); - }else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, recipe.result, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, recipe.result)){ + }else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, block, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, block)){ //add to selection queue if it's a valid place position - selection.add(lastPlaced = new PlaceRequest(cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe, rotation)); + selection.add(lastPlaced = new PlaceRequest(cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block, rotation)); }else if(mode == breaking && validBreak(cursor.target().x, cursor.target().y) && !hasRequest(cursor.target())){ //add to selection queue if it's a valid BREAK position cursor = cursor.target(); @@ -593,27 +589,27 @@ public class MobileInput extends InputHandler implements GestureListener{ selection.clear(); } - if(lineMode && mode == placing && recipe == null){ + if(lineMode && mode == placing && block == null){ lineMode = false; } //if there is no mode and there's a recipe, switch to placing - if(recipe != null && mode == none){ + if(block != null && mode == none){ mode = placing; } - if(recipe != null){ + if(block != null){ showGuide("construction"); } - if(recipe == null && mode == placing){ + if(block == null && mode == placing){ mode = none; } //automatically switch to placing after a new recipe is selected - if(lastRecipe != recipe && mode == breaking && recipe != null){ + if(lastBlock != block && mode == breaking && block != null){ mode = placing; - lastRecipe = recipe; + lastBlock = block; } if(lineMode){ @@ -715,7 +711,7 @@ public class MobileInput extends InputHandler implements GestureListener{ class PlaceRequest{ float x, y; - Recipe recipe; + Block block; int rotation; boolean remove; @@ -723,10 +719,10 @@ public class MobileInput extends InputHandler implements GestureListener{ float scale; float redness; - PlaceRequest(float x, float y, Recipe recipe, int rotation){ + PlaceRequest(float x, float y, Block block, int rotation){ this.x = x; this.y = y; - this.recipe = recipe; + this.block = block; this.rotation = rotation; this.remove = false; } @@ -738,7 +734,7 @@ public class MobileInput extends InputHandler implements GestureListener{ } Tile tile(){ - return world.tileWorld(x - (recipe == null ? 0 : recipe.result.offset()), y - (recipe == null ? 0 : recipe.result.offset())); + return world.tileWorld(x - (block == null ? 0 : block.offset()), y - (block == null ? 0 : block.offset())); } } } diff --git a/core/src/io/anuke/mindustry/io/SaveFileVersion.java b/core/src/io/anuke/mindustry/io/SaveFileVersion.java index 31def1d304..b7f3c2784e 100644 --- a/core/src/io/anuke/mindustry/io/SaveFileVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveFileVersion.java @@ -9,12 +9,14 @@ import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.entities.traits.SaveTrait; import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.game.Content; -import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.MappableContent; +import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.gen.Serialization; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.BlockPart; +import io.anuke.mindustry.world.blocks.storage.CoreBlock; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -33,11 +35,11 @@ public abstract class SaveFileVersion{ long time = stream.readLong(); long playtime = stream.readLong(); int build = stream.readInt(); - byte mode = stream.readByte(); + + Rules rules = Serialization.readRules(stream); String map = stream.readUTF(); int wave = stream.readInt(); - byte difficulty = stream.readByte(); - return new SaveMeta(version, time, playtime, build, mode, map, wave, Difficulty.values()[difficulty]); + return new SaveMeta(version, time, playtime, build, map, wave, rules); } public void writeMap(DataOutputStream stream) throws IOException{ @@ -99,7 +101,7 @@ public abstract class SaveFileVersion{ Tile tile = new Tile(x, y, floorid, wallid); - if(wallid == Blocks.blockpart.id){ + if(wallid == Blocks.part.id){ tile.link = stream.readByte(); }else if(tile.entity != null){ byte tr = stream.readByte(); @@ -122,7 +124,7 @@ public abstract class SaveFileVersion{ tile.entity.readConfig(stream); tile.entity.read(stream); - if(tile.block() == Blocks.core){ + if(tile.block() instanceof CoreBlock){ state.teams.get(t).cores.add(tile); } }else if(wallid == 0){ diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index 2248d056c4..10846a4268 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -43,7 +43,7 @@ public class SaveIO{ } } - public static void loadFromSlot(int slot){ + public static void loadFromSlot(int slot) throws SaveException{ load(fileFor(slot)); } @@ -117,40 +117,41 @@ public class SaveIO{ } } - public static void load(FileHandle file){ + public static void load(FileHandle file) throws SaveException{ try{ + //try and load; if any exception at all occurs load(new InflaterInputStream(file.read())); - }catch(RuntimeException e){ + }catch(SaveException e){ e.printStackTrace(); FileHandle backup = file.sibling(file.name() + "-backup." + file.extension()); if(backup.exists()){ load(new InflaterInputStream(backup.read())); }else{ - throw new RuntimeException(e); + throw new SaveException(e.getCause()); } } } - public static void load(InputStream is){ - logic.reset(); - - DataInputStream stream; - - try{ - stream = new DataInputStream(is); + public static void load(InputStream is) throws SaveException{ + try(DataInputStream stream = new DataInputStream(is)){ + logic.reset(); int version = stream.readInt(); SaveFileVersion ver = versions.get(version); ver.read(stream); - - stream.close(); }catch(Exception e){ content.setTemporaryMapper(null); - throw new RuntimeException(e); + throw new SaveException(e); } } public static SaveFileVersion getVersion(){ return versionArray.peek(); } + + public static class SaveException extends RuntimeException{ + public SaveException(Throwable throwable){ + super(throwable); + } + } } diff --git a/core/src/io/anuke/mindustry/io/SaveMeta.java b/core/src/io/anuke/mindustry/io/SaveMeta.java index c733752cc1..cfe0be8231 100644 --- a/core/src/io/anuke/mindustry/io/SaveMeta.java +++ b/core/src/io/anuke/mindustry/io/SaveMeta.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.io; -import io.anuke.mindustry.game.Difficulty; +import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.maps.Map; import static io.anuke.mindustry.Vars.world; @@ -12,15 +12,15 @@ public class SaveMeta{ public long timePlayed; public Map map; public int wave; - public Difficulty difficulty; + public Rules rules; - public SaveMeta(int version, long timestamp, long timePlayed, int build, int mode, String map, int wave, Difficulty difficulty){ + public SaveMeta(int version, long timestamp, long timePlayed, int build, String map, int wave, Rules rules){ this.version = version; this.build = build; this.timestamp = timestamp; this.timePlayed = timePlayed; this.map = world.maps.getByName(map); this.wave = wave; - this.difficulty = difficulty; + this.rules = rules; } } diff --git a/core/src/io/anuke/mindustry/io/TypeIO.java b/core/src/io/anuke/mindustry/io/TypeIO.java index 5ae705a176..0d87fb38f3 100644 --- a/core/src/io/anuke/mindustry/io/TypeIO.java +++ b/core/src/io/anuke/mindustry/io/TypeIO.java @@ -1,8 +1,11 @@ package io.anuke.mindustry.io; -import io.anuke.arc.graphics.Color; import io.anuke.annotations.Annotations.ReadClass; import io.anuke.annotations.Annotations.WriteClass; +import io.anuke.arc.entities.Effects; +import io.anuke.arc.entities.Effects.Effect; +import io.anuke.arc.entities.Entities; +import io.anuke.arc.graphics.Color; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.bullet.Bullet; @@ -12,7 +15,6 @@ import io.anuke.mindustry.entities.traits.CarriableTrait; import io.anuke.mindustry.entities.traits.CarryTrait; import io.anuke.mindustry.entities.traits.ShooterTrait; import io.anuke.mindustry.entities.units.BaseUnit; -import io.anuke.mindustry.entities.units.UnitCommand; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.net.Packets.AdminAction; import io.anuke.mindustry.net.Packets.KickReason; @@ -20,9 +22,6 @@ import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Pos; import io.anuke.mindustry.world.Tile; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; -import io.anuke.arc.entities.Entities; import java.io.DataInput; import java.io.DataOutput; @@ -173,7 +172,7 @@ public class TypeIO{ buffer.put(request.breaking ? (byte) 1 : 0); buffer.putInt(Pos.get(request.x, request.y)); if(!request.breaking){ - buffer.put(request.recipe.id); + buffer.put(request.block.id); buffer.put((byte) request.rotation); } } @@ -191,9 +190,9 @@ public class TypeIO{ if(type == 1){ //remove currentRequest = new BuildRequest(Pos.x(position), Pos.y(position)); }else{ //place - byte recipe = buffer.get(); + byte block = buffer.get(); byte rotation = buffer.get(); - currentRequest = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.recipe(recipe)); + currentRequest = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.block(block)); } reqs[i] = (currentRequest); @@ -232,16 +231,6 @@ public class TypeIO{ return AdminAction.values()[buffer.get()]; } - @WriteClass(UnitCommand.class) - public static void writeCommand(ByteBuffer buffer, UnitCommand reason){ - buffer.put((byte) reason.ordinal()); - } - - @ReadClass(UnitCommand.class) - public static UnitCommand readCommand(ByteBuffer buffer){ - return UnitCommand.values()[buffer.get()]; - } - @WriteClass(Effect.class) public static void writeEffect(ByteBuffer buffer, Effect effect){ buffer.putShort((short) effect.id); @@ -313,16 +302,6 @@ public class TypeIO{ return id == -1 ? null : content.item(id); } - @WriteClass(Recipe.class) - public static void writeRecipe(ByteBuffer buffer, Recipe recipe){ - buffer.put(recipe.id); - } - - @ReadClass(Recipe.class) - public static Recipe readRecipe(ByteBuffer buffer){ - return content.recipe(buffer.get()); - } - @WriteClass(String.class) public static void writeString(ByteBuffer buffer, String string){ if(string != null){ diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index afc9b633c9..3735f3c17c 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -5,6 +5,8 @@ import io.anuke.mindustry.game.Version; import io.anuke.mindustry.gen.Serialization; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.maps.Map; +import io.anuke.mindustry.type.ContentType; +import io.anuke.mindustry.type.Zone; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -26,6 +28,10 @@ public class Save16 extends SaveFileVersion{ //general state state.rules = Serialization.readRules(stream); + //load zone spawn patterns if applicable + if(content.getByID(ContentType.zone, state.rules.zone) != null){ + state.rules.spawns = content.getByID(ContentType.zone, state.rules.zone).rules.get().spawns; + } String mapname = stream.readUTF(); Map map = world.maps.getByName(mapname); if(map == null) map = new Map("unknown", 1, 1); @@ -36,13 +42,11 @@ public class Save16 extends SaveFileVersion{ state.wave = wave; state.wavetime = wavetime; + state.stats = Serialization.readStats(stream); content.setTemporaryMapper(readContentHeader(stream)); - world.spawner.read(stream); - readEntities(stream); - readMap(stream); } @@ -61,9 +65,9 @@ public class Save16 extends SaveFileVersion{ stream.writeInt(state.wave); //wave stream.writeFloat(state.wavetime); //wave countdown - writeContentHeader(stream); + Serialization.writeStats(stream, state.stats); - world.spawner.write(stream); //spawnes + writeContentHeader(stream); //--ENTITIES-- diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index 6af98f428e..51f8b85ec6 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -63,14 +63,7 @@ public class Maps implements Disposable{ FileHandle file = Core.files.internal("maps/" + name + "." + mapExtension); try(DataInputStream ds = new DataInputStream(file.read())) { - MapMeta meta = MapIO.readMapMeta(ds); - Map map = new Map(name, meta, false, file::read); - - if (!headless){ - map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true))); - } - - return map; + return new Map(name, MapIO.readMapMeta(ds), false, file::read); }catch(IOException e){ throw new RuntimeException(e); } diff --git a/core/src/io/anuke/mindustry/maps/generators/BasicGenerator.java b/core/src/io/anuke/mindustry/maps/generators/BasicGenerator.java index 7348825262..948272bb68 100644 --- a/core/src/io/anuke/mindustry/maps/generators/BasicGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generators/BasicGenerator.java @@ -53,7 +53,7 @@ public class BasicGenerator extends RandomGenerator{ } if(rocks > 0.64){ - block = Blocks.rocksSmall; + block = Blocks.rocks; } } } diff --git a/core/src/io/anuke/mindustry/maps/generators/Generator.java b/core/src/io/anuke/mindustry/maps/generators/Generator.java index 1f818fc499..dac0b08093 100644 --- a/core/src/io/anuke/mindustry/maps/generators/Generator.java +++ b/core/src/io/anuke/mindustry/maps/generators/Generator.java @@ -12,5 +12,9 @@ public abstract class Generator{ public Generator(){} + public void init(){ + + } + public abstract void generate(Tile[][] tiles); } diff --git a/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java b/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java index 0c9274c0b1..f2ba259c82 100644 --- a/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java @@ -1,16 +1,39 @@ package io.anuke.mindustry.maps.generators; +import io.anuke.arc.collection.Array; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.math.geom.Point2; +import io.anuke.arc.util.noise.Simplex; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.storage.CoreBlock; -import static io.anuke.mindustry.Vars.world; +import static io.anuke.mindustry.Vars.*; public class MapGenerator extends Generator{ - private final Map map; + private Map map; + private String mapName; + + /**How much the landscape is randomly distorted.*/ + public float distortion = 3; + + /**The amount of final enemy spawns used. -1 to use everything in the map. + * This amount of enemy spawns is selected randomly from the map.*/ + public int enemySpawns = -1; public MapGenerator(String mapName){ + this.mapName = mapName; + } + + public MapGenerator(String mapName, int enemySpawns){ + this.mapName = mapName; + this.enemySpawns = enemySpawns; + } + + @Override + public void init(){ map = world.maps.loadInternalMap(mapName); width = map.meta.width; height = map.meta.height; @@ -22,15 +45,60 @@ public class MapGenerator extends Generator{ data.position(0, 0); TileDataMarker marker = data.newDataMarker(); + Array players = new Array<>(); + Array enemies = new Array<>(); for(int y = 0; y < data.height(); y++){ for(int x = 0; x < data.width(); x++){ data.read(marker); - tiles[x][y] = new Tile(x, y, marker.floor, marker.wall == Blocks.blockpart.id ? 0 : marker.wall, marker.rotation, marker.team); + if(content.block(marker.wall) instanceof CoreBlock){ + players.add(new Point2(x, y)); + marker.wall = 0; + } + + if(enemySpawns != -1 && content.block(marker.wall) == Blocks.spawn){ + enemies.add(new Point2(x, y)); + marker.wall = 0; + } + + tiles[x][y] = new Tile(x, y, marker.floor, marker.wall == Blocks.part.id ? 0 : marker.wall, marker.rotation, marker.team); } } + Simplex simplex = new Simplex(Mathf.random(99999)); + + for(int x = 0; x < data.width(); x++){ + for(int y = 0; y < data.height(); y++){ + final double scl = 10; + int newX = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x, y) * distortion + x), 0, data.width()-1); + int newY = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x + 9999, y + 9999) * distortion + y), 0, data.height()-1); + if(tiles[newX][newY].block() != Blocks.spawn && !tiles[x][y].block().synthetic()&& !tiles[newX][newY].block().synthetic()){ + tiles[x][y].setBlock(tiles[newX][newY].block()); + } + } + } + + if(enemySpawns > enemies.size){ + throw new IllegalArgumentException("Enemy spawn pool greater than map spawn number."); + } + + if(enemySpawns != -1){ + enemies.shuffle(); + for(int i = 0; i < enemySpawns; i++){ + Point2 point = enemies.get(i); + tiles[point.x][point.y].setBlock(Blocks.spawn); + } + } + + Point2 core = players.random(); + if(core == null){ + throw new IllegalArgumentException("All zone maps must have a core."); + } + + //TODO set specific core block? + tiles[core.x][core.y].setBlock(Blocks.core, defaultTeam); + world.prepareTiles(tiles); world.setMap(map); } diff --git a/core/src/io/anuke/mindustry/type/ContentType.java b/core/src/io/anuke/mindustry/type/ContentType.java index eb16e9fc95..1e775dc7e3 100644 --- a/core/src/io/anuke/mindustry/type/ContentType.java +++ b/core/src/io/anuke/mindustry/type/ContentType.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.type; /**Do not rearrange, ever!*/ public enum ContentType { item, - recipe, block, mech, bullet, diff --git a/core/src/io/anuke/mindustry/type/Item.java b/core/src/io/anuke/mindustry/type/Item.java index b4e461d4ff..47bf130f3e 100644 --- a/core/src/io/anuke/mindustry/type/Item.java +++ b/core/src/io/anuke/mindustry/type/Item.java @@ -30,7 +30,7 @@ public class Item extends UnlockableContent implements Comparable{ public float fluxiness = 0f; /**drill hardness of the item*/ public int hardness = 0; - /**the burning color of this item*/ + /**the burning color of this item. TODO unused; implement*/ public Color flameColor = Palette.darkFlame.cpy(); /** * base material cost of this item, used for calculating place times @@ -49,7 +49,7 @@ public class Item extends UnlockableContent implements Comparable{ if(!Core.bundle.has("item." + this.name + ".name")){ Log.err("Warning: item '" + name + "' is missing a localized name. Add the following to bundle.properties:"); - Log.err("item." + this.name + ".name=" + Strings.capitalize(name.replace('-', '_'))); + Log.err("item." + this.name + ".name = " + Strings.capitalize(name.replace('-', '_'))); } } @@ -97,11 +97,8 @@ public class Item extends UnlockableContent implements Comparable{ return ContentType.item; } + /**Allocates a new array containing all items the generate ores.*/ public static Array getAllOres(){ - Array arr = new Array<>(); - for(Item item : Vars.content.items()){ - if(item.genOre) arr.add(item); - } - return arr; + return Vars.content.items().select(i -> i.genOre); } } diff --git a/core/src/io/anuke/mindustry/type/Recipe.java b/core/src/io/anuke/mindustry/type/Recipe.java deleted file mode 100644 index 3cea86d00b..0000000000 --- a/core/src/io/anuke/mindustry/type/Recipe.java +++ /dev/null @@ -1,169 +0,0 @@ -package io.anuke.mindustry.type; - -import io.anuke.arc.Core; -import io.anuke.arc.collection.Array; -import io.anuke.arc.collection.ObjectMap; -import io.anuke.arc.collection.OrderedMap; -import io.anuke.arc.graphics.g2d.TextureRegion; -import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.arc.util.Log; -import io.anuke.arc.util.Strings; -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.game.UnlockableContent; -import io.anuke.mindustry.ui.ContentDisplay; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.meta.BlockStat; -import io.anuke.mindustry.world.meta.ContentStatValue; -import io.anuke.mindustry.world.meta.StatValue; - -import java.util.Arrays; - -import static io.anuke.mindustry.Vars.*; - -public class Recipe extends UnlockableContent{ - private static ObjectMap recipeMap = new ObjectMap<>(); - private static Array returnArray = new Array<>(); - - public final Block result; - public final ItemStack[] requirements; - public final Category category; - public final float cost; - - public RecipeVisibility visibility = RecipeVisibility.all; - public boolean hidden; - public boolean alwaysUnlocked; - - public Recipe(Category category, Block result, ItemStack... requirements){ - this.result = result; - this.requirements = requirements; - this.category = category; - - Arrays.sort(requirements, (a, b) -> Integer.compare(a.item.id, b.item.id)); - - float timeToPlace = 0f; - for(ItemStack stack : requirements){ - timeToPlace += stack.amount * stack.item.cost; - } - - this.cost = timeToPlace; - - recipeMap.put(result, this); - } - - /**Returns all non-hidden recipes in a category.*/ - public static Array getByCategory(Category category){ - returnArray.clear(); - for(Recipe recipe : content.recipes()){ - if(recipe.category == category && recipe.visibility.shown()){ - returnArray.add(recipe); - } - } - return returnArray; - } - - public static Recipe getByResult(Block block){ - return recipeMap.get(block); - } - - public Recipe setVisible(RecipeVisibility visibility){ - this.visibility = visibility; - return this; - } - - public Recipe setHidden(boolean hidden){ - this.hidden = hidden; - return this; - } - - public Recipe setAlwaysUnlocked(boolean unlocked){ - this.alwaysUnlocked = unlocked; - return this; - } - - @Override - public boolean alwaysUnlocked(){ - return alwaysUnlocked; - } - - @Override - public boolean isHidden(){ - return !visibility.shown() || hidden; - } - - @Override - public void displayInfo(Table table){ - ContentDisplay.displayRecipe(table, this); - } - - @Override - public String localizedName(){ - return result.formalName; - } - - @Override - public TextureRegion getContentIcon(){ - return result.getEditorIcon(); - } - - @Override - public void init(){ - if(!Core.bundle.has("block." + result.name + ".name")){ - Log.err("WARNING: Recipe block '{0}' does not have a formal name defined. Add the following to bundle.properties:", result.name); - Log.err("block.{0}.name={1}", result.name, Strings.capitalize(result.name.replace('-', '_'))); - }/*else if(result.fullDescription == null){ - Log.err("WARNING: Recipe block '{0}' does not have a description defined.", result.name); - }*/ - } - - @Override - public String getContentName(){ - return result.name; - } - - @Override - public ContentType getContentType(){ - return ContentType.recipe; - } - - @Override - public void onUnlock(){ - for(OrderedMap map : result.stats.toMap().values()){ - for(StatValue value : map.values()){ - if(value instanceof ContentStatValue){ - ContentStatValue stat = (ContentStatValue) value; - UnlockableContent[] content = stat.getValueContent(); - for(UnlockableContent c : content){ - data.unlockContent(c); - } - } - } - } - } - - public enum RecipeVisibility{ - mobileOnly(true, false), - desktopOnly(false, true), - all(true, true), - sandboxOnly(true, true){ - @Override - public boolean usable(){ - return state.rules.infiniteResources; - } - }; - - public final boolean mobile, desktop; - - RecipeVisibility(boolean mobile, boolean desktop){ - this.mobile = mobile; - this.desktop = desktop; - } - - public boolean usable(){ - return true; - } - - public boolean shown(){ - return usable() && ((Vars.mobile && mobile) || (!Vars.mobile && desktop)); - } - } -} diff --git a/core/src/io/anuke/mindustry/type/Zone.java b/core/src/io/anuke/mindustry/type/Zone.java index 5a943029ce..dabee32514 100644 --- a/core/src/io/anuke/mindustry/type/Zone.java +++ b/core/src/io/anuke/mindustry/type/Zone.java @@ -7,19 +7,42 @@ import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.maps.generators.Generator; +import io.anuke.mindustry.world.Block; + +import static io.anuke.mindustry.Vars.state; public class Zone extends UnlockableContent{ public final String name; public final Generator generator; public ItemStack[] deployCost = {}; public ItemStack[] startingItems = {}; + public Block[] blockRequirements = {}; + public ItemStack[] itemRequirements = {}; + public Zone[] zoneRequirements = {}; public Supplier rules = Rules::new; + public boolean alwaysUnlocked; + public int conditionWave = Integer.MAX_VALUE; public Zone(String name, Generator generator){ this.name = name; this.generator = generator; } + /**Whether this zone has met its condition; if true, the player can leave.*/ + public boolean metCondition(){ + return state.wave >= conditionWave; + } + + @Override + public void init(){ + generator.init(); + } + + @Override + public boolean alwaysUnlocked(){ + return alwaysUnlocked; + } + @Override public boolean isHidden(){ return true; @@ -46,4 +69,5 @@ public class Zone extends UnlockableContent{ public ContentType getContentType(){ return ContentType.zone; } + } diff --git a/core/src/io/anuke/mindustry/ui/Bar.java b/core/src/io/anuke/mindustry/ui/Bar.java new file mode 100644 index 0000000000..bf24bd03f6 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/Bar.java @@ -0,0 +1,82 @@ +package io.anuke.mindustry.ui; + +import io.anuke.arc.Core; +import io.anuke.arc.function.FloatProvider; +import io.anuke.arc.function.Supplier; +import io.anuke.arc.graphics.Color; +import io.anuke.arc.graphics.g2d.BitmapFont; +import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.graphics.g2d.GlyphLayout; +import io.anuke.arc.graphics.g2d.ScissorStack; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.math.geom.Rectangle; +import io.anuke.arc.scene.Element; +import io.anuke.arc.scene.style.Drawable; +import io.anuke.arc.util.pooling.Pools; + +public class Bar extends Element{ + private static Rectangle scissor = new Rectangle(); + + private FloatProvider fraction; + private String name = ""; + private float value, lastValue, blink; + private Color blinkColor = new Color(); + + public Bar(String name, Color color, FloatProvider fraction){ + this.fraction = fraction; + this.name = Core.bundle.get(name); + this.blinkColor.set(color); + lastValue = value = fraction.get(); + setColor(color); + } + + public Bar(Supplier name, Supplier color, FloatProvider fraction){ + this.fraction = fraction; + update(() -> { + this.name = name.get(); + setColor(color.get()); + }); + } + + public Bar blink(Color color){ + blinkColor.set(color); + return this; + } + + @Override + public void draw(){ + if(!Mathf.isEqual(lastValue, fraction.get())){ + blink = 1f; + lastValue = fraction.get(); + } + + blink = Mathf.lerpDelta(blink, 0f, 0.2f); + value = Mathf.lerpDelta(value, fraction.get(), 0.15f); + + Draw.colorl(0.1f); + Draw.drawable("bar", x, y, width, height); + Draw.color(color, blinkColor, blink); + + Drawable top = Core.scene.skin.getDrawable("bar-top"); + float topWidth = width * value; + + if(topWidth > Core.atlas.find("bar-top").getWidth()){ + top.draw(x, y, topWidth, height); + }else{ + if(ScissorStack.pushScissors(scissor.set(x, y, topWidth, height))){ + top.draw(x, y, Core.atlas.find("bar-top").getWidth(), height); + ScissorStack.popScissors(); + } + } + + Draw.color(); + + BitmapFont font = Core.scene.skin.getFont("default-font"); + GlyphLayout lay = Pools.obtain(GlyphLayout.class, GlyphLayout::new); + lay.setText(font, name); + + font.draw(name, x + width/2f - lay.width/2f, y + height/2f + lay.height/2f + 1); + + Pools.free(lay); + } +} diff --git a/core/src/io/anuke/mindustry/ui/ContentDisplay.java b/core/src/io/anuke/mindustry/ui/ContentDisplay.java index 4859846196..ec7a43fe52 100644 --- a/core/src/io/anuke/mindustry/ui/ContentDisplay.java +++ b/core/src/io/anuke/mindustry/ui/ContentDisplay.java @@ -10,8 +10,8 @@ import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.Mech; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.BlockStats; import io.anuke.mindustry.world.meta.StatCategory; @@ -19,19 +19,18 @@ import io.anuke.mindustry.world.meta.StatValue; public class ContentDisplay{ - public static void displayRecipe(Table table, Recipe recipe){ - Block block = recipe.result; + public static void displayBlock(Table table, Block block){ table.table(title -> { int size = 8 * 6; - title.addImage(Core.atlas.find("block-icon-" + block.name)).size(size); + title.addImage(block.icon(Icon.large)).size(size); title.add("[accent]" + block.formalName).padLeft(5); }); table.row(); - table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(15).padLeft(0).padRight(0).fillX(); + table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(8).padLeft(0).padRight(0).fillX(); table.row(); @@ -39,7 +38,7 @@ public class ContentDisplay{ table.add(block.fullDescription).padLeft(5).padRight(5).width(400f).wrap().fillX(); table.row(); - table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(15).padLeft(0).padRight(0).fillX(); + table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(8).padLeft(0).padRight(0).fillX(); table.row(); } diff --git a/core/src/io/anuke/mindustry/ui/ImageStack.java b/core/src/io/anuke/mindustry/ui/ImageStack.java deleted file mode 100644 index 7552ceccd0..0000000000 --- a/core/src/io/anuke/mindustry/ui/ImageStack.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.anuke.mindustry.ui; - -import io.anuke.arc.graphics.g2d.TextureRegion; -import io.anuke.arc.scene.ui.Image; -import io.anuke.arc.scene.ui.layout.Stack; - -public class ImageStack extends Stack{ - - public ImageStack(TextureRegion... regions){ - for(TextureRegion region : regions){ - add(new Image(region)); - } - } -} diff --git a/core/src/io/anuke/mindustry/ui/TreeLayout.java b/core/src/io/anuke/mindustry/ui/TreeLayout.java new file mode 100644 index 0000000000..209e3a5110 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/TreeLayout.java @@ -0,0 +1,310 @@ + + +package io.anuke.mindustry.ui; + +import io.anuke.arc.collection.FloatArray; +import io.anuke.arc.math.geom.Rectangle; + +/** + * Algorithm taken from TreeLayout. + */ +public class TreeLayout{ + public TreeLocation rootLocation = TreeLocation.top; + public TreeAlignment alignment = TreeAlignment.awayFromRoot; + public float gapBetweenLevels = 10; + public float gapBetweenNodes = 10f; + + private final FloatArray sizeOfLevel = new FloatArray(); + private float boundsLeft = Float.MAX_VALUE; + private float boundsRight = Float.MIN_VALUE; + private float boundsTop = Float.MAX_VALUE; + private float boundsBottom = Float.MIN_VALUE; + + public void layout(TreeNode root){ + firstWalk(root, null); + calcSizeOfLevels(root, 0); + secondWalk(root, -root.prelim, 0, 0); + } + + private float getWidthOrHeightOfNode(TreeNode treeNode, boolean returnWidth){ + return returnWidth ? treeNode.width : treeNode.height; + } + + private float getNodeThickness(TreeNode treeNode){ + return getWidthOrHeightOfNode(treeNode, !isLevelChangeInYAxis()); + } + + private float getNodeSize(TreeNode treeNode){ + return getWidthOrHeightOfNode(treeNode, isLevelChangeInYAxis()); + } + + private boolean isLevelChangeInYAxis(){ + return rootLocation == TreeLocation.top || rootLocation == TreeLocation.bottom; + } + + private int getLevelChangeSign(){ + return rootLocation == TreeLocation.bottom || rootLocation == TreeLocation.right ? -1 : 1; + } + + private void updateBounds(TreeNode node, float centerX, float centerY){ + float width = node.width; + float height = node.height; + float left = centerX - width / 2; + float right = centerX + width / 2; + float top = centerY - height / 2; + float bottom = centerY + height / 2; + if(boundsLeft > left){ + boundsLeft = left; + } + if(boundsRight < right){ + boundsRight = right; + } + if(boundsTop > top){ + boundsTop = top; + } + if(boundsBottom < bottom){ + boundsBottom = bottom; + } + } + + public Rectangle getBounds(){ + return new Rectangle(boundsLeft, boundsBottom, boundsRight - boundsLeft, boundsTop - boundsBottom); + } + + private void calcSizeOfLevels(TreeNode node, int level){ + float oldSize; + if(sizeOfLevel.size <= level){ + sizeOfLevel.add(0); + oldSize = 0; + }else{ + oldSize = sizeOfLevel.get(level); + } + + float size = getNodeThickness(node); + if(oldSize < size){ + sizeOfLevel.set(level, size); + } + + if(!node.isLeaf()){ + for(TreeNode child : node.children){ + calcSizeOfLevels(child, level + 1); + } + } + } + + public int getLevelCount(){ + return sizeOfLevel.size; + } + + public float getGapBetweenNodes(TreeNode a, TreeNode b){ + return gapBetweenNodes; + } + + public float getSizeOfLevel(int level){ + if(!(level >= 0)) throw new IllegalArgumentException("level must be >= 0"); + if(!(level < getLevelCount())) throw new IllegalArgumentException("level must be < levelCount"); + + return sizeOfLevel.get(level); + } + + private TreeNode getAncestor(TreeNode node){ + return node.ancestor != null ? node.ancestor : node; + } + + private float getDistance(TreeNode v, TreeNode w){ + float sizeOfNodes = getNodeSize(v) + getNodeSize(w); + + return sizeOfNodes / 2 + getGapBetweenNodes(v, w); + } + + private TreeNode nextLeft(TreeNode v){ + return v.isLeaf() ? v.thread : v.children[0]; + } + + private TreeNode nextRight(TreeNode v){ + return v.isLeaf() ? v.thread : v.children[v.children.length - 1]; + } + + private int getNumber(TreeNode node, TreeNode parentNode){ + if(node.number == -1){ + int number = 1; + for(TreeNode child : parentNode.children){ + child.number = number++; + } + } + return node.number; + } + + private TreeNode ancestor(TreeNode vIMinus, TreeNode parentOfV, TreeNode defaultAncestor){ + TreeNode ancestor = getAncestor(vIMinus); + return ancestor.parent == parentOfV ? ancestor : defaultAncestor; + } + + private void moveSubtree(TreeNode wMinus, TreeNode wPlus, TreeNode parent, float shift){ + int subtrees = getNumber(wPlus, parent) - getNumber(wMinus, parent); + wPlus.change = wPlus.change - shift / subtrees; + wPlus.shift = wPlus.shift + shift; + wMinus.change = wMinus.change + shift / subtrees; + wPlus.prelim = wPlus.prelim + shift; + wPlus.mode = wPlus.mode + shift; + } + + private TreeNode apportion(TreeNode v, TreeNode defaultAncestor, + TreeNode leftSibling, TreeNode parentOfV){ + if(leftSibling == null){ + return defaultAncestor; + } + + TreeNode vOPlus = v; + TreeNode vIPlus = v; + TreeNode vIMinus = leftSibling; + + TreeNode vOMinus = parentOfV.children[0]; + + float sIPlus = (vIPlus).mode; + float sOPlus = (vOPlus).mode; + float sIMinus = (vIMinus).mode; + float sOMinus = (vOMinus).mode; + + TreeNode nextRightVIMinus = nextRight(vIMinus); + TreeNode nextLeftVIPlus = nextLeft(vIPlus); + + while(nextRightVIMinus != null && nextLeftVIPlus != null){ + vIMinus = nextRightVIMinus; + vIPlus = nextLeftVIPlus; + vOMinus = nextLeft(vOMinus); + vOPlus = nextRight(vOPlus); + vOPlus.ancestor = v; + float shift = (vIMinus.prelim + sIMinus) + - (vIPlus.prelim + sIPlus) + + getDistance(vIMinus, vIPlus); + + if(shift > 0){ + moveSubtree(ancestor(vIMinus, parentOfV, defaultAncestor), + v, parentOfV, shift); + sIPlus = sIPlus + shift; + sOPlus = sOPlus + shift; + } + sIMinus += vIMinus.mode; + sIPlus += vIPlus.mode; + sOMinus += vOMinus.mode; + sOPlus += vOPlus.mode; + + nextRightVIMinus = nextRight(vIMinus); + nextLeftVIPlus = nextLeft(vIPlus); + } + + if(nextRightVIMinus != null && nextRight(vOPlus) == null){ + vOPlus.thread = nextRightVIMinus; + vOPlus.mode += sIMinus - sOPlus; + } + + if(nextLeftVIPlus != null && nextLeft(vOMinus) == null){ + vOMinus.thread = nextLeftVIPlus; + vOMinus.mode += sIPlus - sOMinus; + defaultAncestor = v; + } + return defaultAncestor; + } + + private void executeShifts(TreeNode v){ + float shift = 0; + float change = 0; + + for(int i = v.children.length - 1; i >= 0; i --){ + TreeNode w = v.children[i]; + change = change + w.change; + w.prelim += shift; + w.mode += shift; + shift += w.shift + change; + } + } + + private void firstWalk(TreeNode v, TreeNode leftSibling){ + if(v.isLeaf()){ + if(leftSibling != null){ + v.prelim = leftSibling.prelim + getDistance(v, leftSibling); + } + + }else{ + TreeNode defaultAncestor = v.children[0]; + TreeNode previousChild = null; + for(TreeNode w : v.children){ + firstWalk(w, previousChild); + defaultAncestor = apportion(w, defaultAncestor, previousChild, + v); + previousChild = w; + } + executeShifts(v); + float midpoint = (v.children[0].prelim + v.children[v.children.length-1].prelim) / 2f; + TreeNode w = leftSibling; + if(w != null){ + v.prelim = w.prelim + getDistance(v, w); + v.mode = v.prelim - midpoint; + }else{ + v.prelim = midpoint; + } + } + } + + private void secondWalk(TreeNode v, float m, int level, float levelStart){ + float levelChangeSign = getLevelChangeSign(); + boolean levelChangeOnYAxis = isLevelChangeInYAxis(); + float levelSize = getSizeOfLevel(level); + + float x = v.prelim + m; + + float y; + if(alignment == TreeAlignment.center){ + y = levelStart + levelChangeSign * (levelSize / 2); + }else if(alignment == TreeAlignment.towardsRoot){ + y = levelStart + levelChangeSign * (getNodeThickness(v) / 2); + }else{ + y = levelStart + levelSize - levelChangeSign + * (getNodeThickness(v) / 2); + } + + if(!levelChangeOnYAxis){ + float t = x; + x = y; + y = t; + } + + v.x = x; + v.y = y; + updateBounds(v, x, y); + + if(!v.isLeaf()){ + float nextLevelStart = levelStart + + (levelSize + gapBetweenLevels) + * levelChangeSign; + for(TreeNode w : v.children){ + secondWalk(w, m + v.mode, level + 1, nextLevelStart); + } + } + } + + public enum TreeLocation{ + top, left, bottom, right + } + + public enum TreeAlignment{ + center, towardsRoot, awayFromRoot + } + + public static class TreeNode{ + public float width, height, x, y; + + //should be initialized by user + public TreeNode[] children; + public TreeNode parent; + + private float mode, prelim, change, shift; + private int number = -1; + private TreeNode thread, ancestor; + + boolean isLeaf(){ + return children == null || children.length == 0; + } + } +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java index cf77e3f0cd..a10edecfa0 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java @@ -48,7 +48,7 @@ public class AboutDialog extends FloatingDialog{ continue; } - Table table = new Table("underline-2"); + Table table = new Table("underline"); table.margin(0); table.table(img -> { img.addImage("white").height(h - 5).width(40f).color(link.color); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DatabaseDialog.java similarity index 93% rename from core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java rename to core/src/io/anuke/mindustry/ui/dialogs/DatabaseDialog.java index 8326d5a474..a4da5816f4 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/UnlocksDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DatabaseDialog.java @@ -15,10 +15,10 @@ import io.anuke.arc.scene.utils.UIUtils; import static io.anuke.mindustry.Vars.*; -public class UnlocksDialog extends FloatingDialog{ +public class DatabaseDialog extends FloatingDialog{ - public UnlocksDialog(){ - super("$unlocks"); + public DatabaseDialog(){ + super("database"); shouldPause = true; addCloseButton(); @@ -58,7 +58,7 @@ public class UnlocksDialog extends FloatingDialog{ if(unlock.isHidden()) continue; - Image image = data.isUnlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image("icon-locked"); + Image image = data.isUnlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image("icon-tree-locked"); image.addListener(new HandCursorListener()); list.add(image).size(size).pad(3); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java index 90c7d40f33..f5870712b7 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java @@ -1,12 +1,20 @@ package io.anuke.mindustry.ui.dialogs; +import io.anuke.arc.Core; import io.anuke.arc.collection.ObjectIntMap; +import io.anuke.arc.graphics.Color; +import io.anuke.arc.scene.ui.ScrollPane; +import io.anuke.arc.scene.ui.TextButton; import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.mindustry.Vars; +import io.anuke.mindustry.core.GameState.State; +import io.anuke.mindustry.game.Saves.SaveSlot; +import io.anuke.mindustry.io.SaveIO.SaveException; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.ItemType; import io.anuke.mindustry.type.Zone; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; import static io.anuke.mindustry.Vars.*; @@ -23,41 +31,192 @@ public class DeployDialog extends FloatingDialog{ cont.clear(); addCloseButton(); + buttons.addImageTextButton("$techtree", "icon-tree", 16 * 2, () -> ui.tech.show()).size(230f, 64f); cont.stack(new Table(){{ top().left().margin(10); ObjectIntMap items = data.items(); - for(Item item : Vars.content.items()){ + for(Item item : content.items()){ if(item.type == ItemType.material && data.isUnlocked(item)){ - add(items.get(item, 0) + "").left(); + label(() -> items.get(item, 0) + "").left(); addImage(item.region).size(8*4).pad(4); add("[LIGHT_GRAY]" + item.localizedName()).left(); row(); } } - }}, new Table(){{ + }}, new ScrollPane(new Table(){{ - for(Zone zone : Vars.content.zones()){ - if(data.isUnlocked(zone)){ + if(control.saves.getZoneSlot() == null){ + + int i = 0; + for(Zone zone : content.zones()){ table(t -> { - t.addButton(zone.localizedName(), () -> { - data.removeItems(zone.deployCost); - hide(); - world.playZone(zone); - }).size(150f)/*.disabled(b -> !data.hasItems(zone.deployCost))*/; - t.row(); - t.table(req -> { - req.left(); - for(ItemStack stack : zone.deployCost){ - req.addImage(stack.item.region).size(8*3); - req.add(stack.amount + "").left(); + TextButton button = t.addButton("", () -> { + if(!data.isUnlocked(zone)){ + data.removeItems(zone.itemRequirements); + data.unlockContent(zone); + setup(); + }else{ + data.removeItems(zone.deployCost); + hide(); + world.playZone(zone); } - }).pad(3).growX(); - }).pad(3); + }).size(250f).disabled(b -> !canUnlock(zone)).get(); + + button.clearChildren(); + + if(data.isUnlocked(zone)){ + button.table(title -> { + title.addImage("icon-zone").padRight(3); + title.add(zone.localizedName()); + }); + button.row(); + + if(data.getWaveScore(zone) > 0){ + button.add(Core.bundle.format("bestwave", data.getWaveScore(zone))); + } + + button.row(); + + button.add("$launch").color(Color.LIGHT_GRAY).pad(4); + button.row(); + button.table(req -> { + for(ItemStack stack : zone.deployCost){ + req.addImage(stack.item.region).size(8 * 3); + req.add(stack.amount + "").left(); + } + }).pad(3).growX(); + }else{ + button.addImage("icon-zone-locked"); + button.row(); + button.add("$locked").padBottom(6); + + if(!hidden(zone)){ + button.row(); + + button.table(req -> { + req.defaults().left(); + + if(zone.zoneRequirements.length > 0){ + req.table(r -> { + r.add("$complete").colspan(2).left(); + r.row(); + for(Zone other : zone.zoneRequirements){ + r.addImage("icon-zone").padRight(4); + r.add(other.localizedName()).color(Color.LIGHT_GRAY); + r.addImage(data.isCompleted(zone) ? "icon-check-2" : "icon-cancel-2") + .color(data.isCompleted(zone) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3); + r.row(); + } + }); + } + + req.row(); + + if(zone.itemRequirements.length > 0){ + req.table(r -> { + for(ItemStack stack : zone.itemRequirements){ + r.addImage(stack.item.region).size(8 * 3).padRight(4); + r.add(Math.min(data.getItem(stack.item), stack.amount) + "/" + stack.amount) + .color(stack.amount > data.getItem(stack.item) ? Color.SCARLET : Color.LIGHT_GRAY).left(); + r.row(); + } + }).padTop(10); + } + + req.row(); + + if(zone.blockRequirements.length > 0){ + req.table(r -> { + r.add("$research.list").colspan(2).left(); + r.row(); + for(Block block : zone.blockRequirements){ + r.addImage(block.icon(Icon.small)).size(8 * 3).padRight(4); + r.add(block.formalName).color(Color.LIGHT_GRAY); + r.addImage(data.isUnlocked(block) ? "icon-check-2" : "icon-cancel-2") + .color(data.isUnlocked(block) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3); + r.row(); + } + + }).padTop(10); + } + }).growX(); + } + } + }).pad(4); + + if(++i % 2 == 0){ + row(); + } } + }else{ + SaveSlot slot = control.saves.getZoneSlot(); + + TextButton b[] = {null}; + + TextButton button = addButton(Core.bundle.format("resume", slot.getZone().localizedName()), () -> { + if(b[0].childrenPressed()) return; + + hide(); + ui.loadAnd(() -> { + try{ + control.saves.getZoneSlot().load(); + state.set(State.playing); + }catch(SaveException e){ //make sure to handle any save load errors! + e.printStackTrace(); + if(control.saves.getZoneSlot() != null) control.saves.getZoneSlot().delete(); + ui.showInfo("$save.corrupted"); + show(); + } + }); + }).size(200f).get(); + b[0] = button; + + String color = "[lightgray]"; + + button.defaults().colspan(2); + button.row(); + button.add(Core.bundle.format("save.wave", color + slot.getWave())); + button.row(); + button.label(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime())); + button.row(); + button.add().grow(); + button.row(); + + button.addButton("$abandon", () -> { + ui.showConfirm("$warning", "$abandon.text", () -> { + slot.delete(); + setup(); + }); + }).growX().height(50f).pad(-12).padTop(10); } - }}).grow(); + }})).grow(); + } + + boolean hidden(Zone zone){ + for(Zone other : zone.zoneRequirements){ + if(!data.isUnlocked(other)){ + return true; + } + } + return false; + } + + boolean canUnlock(Zone zone){ + for(Zone other : zone.zoneRequirements){ + if(!data.isCompleted(other)){ + return false; + } + } + + for(Block other : zone.blockRequirements){ + if(!data.isUnlocked(other)){ + return false; + } + } + + return data.hasItems(zone.itemRequirements); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/GameOverDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/GameOverDialog.java new file mode 100644 index 0000000000..0d0dfb3d34 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/dialogs/GameOverDialog.java @@ -0,0 +1,87 @@ +package io.anuke.mindustry.ui.dialogs; + +import io.anuke.arc.Core; +import io.anuke.mindustry.core.GameState.State; +import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.type.Item; + +import static io.anuke.mindustry.Vars.*; + +public class GameOverDialog extends FloatingDialog{ + private Team winner; + + public GameOverDialog(){ + super("$gameover"); + setFillParent(false); + shown(this::rebuild); + } + + public void show(Team winner){ + this.winner = winner; + show(); + } + + void rebuild(){ + title.setText(state.launched ? "$launch.title" : "$gameover"); + buttons.clear(); + cont.clear(); + + buttons.margin(10); + + if(state.rules.pvp){ + cont.add(Core.bundle.format("gameover.pvp",winner.localized())).pad(6); + buttons.addButton("$menu", () -> { + hide(); + state.set(State.menu); + logic.reset(); + }).size(130f, 60f); + }else{ + if(control.isHighScore()){ + cont.add("$highscore").pad(6); + cont.row(); + } + + cont.table(t -> { + cont.left().defaults().left(); + cont.add(Core.bundle.format("stat.wave", state.stats.wavesLasted)); + cont.row(); + cont.add(Core.bundle.format("stat.enemiesDestroyed", state.stats.enemyUnitsDestroyed)); + cont.row(); + cont.add(Core.bundle.format("stat.built", state.stats.buildingsBuilt)); + cont.row(); + cont.add(Core.bundle.format("stat.destroyed", state.stats.buildingsDestroyed)); + cont.row(); + cont.add(Core.bundle.format("stat.deconstructed", state.stats.buildingsDeconstructed)); + cont.row(); + if(world.isZone() && !state.stats.itemsDelivered.isEmpty()){ + cont.add("$stat.delivered"); + cont.row(); + for(Item item : content.items()){ + if(state.stats.itemsDelivered.get(item, 0) > 0){ + cont.table(items -> { + items.add(" [LIGHT_GRAY]" + state.stats.itemsDelivered.get(item, 0)); + items.addImage(item.region).size(8 *3).pad(4); + }).left(); + cont.row(); + } + } + } + }).pad(12); + + if(world.isZone()){ + buttons.addButton("$continue", () -> { + hide(); + state.set(State.menu); + logic.reset(); + ui.deploy.show(); + }).size(130f, 60f); + }else{ + buttons.addButton("$menu", () -> { + hide(); + state.set(State.menu); + logic.reset(); + }).size(130f, 60f); + } + } + } +} diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java index 8f79f4703a..1bfccbc6df 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java @@ -14,6 +14,7 @@ import io.anuke.arc.scene.ui.TextButton; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.Log; import io.anuke.arc.util.Strings; +import io.anuke.mindustry.io.SaveIO.SaveException; import java.io.IOException; @@ -116,8 +117,6 @@ public class LoadDialog extends FloatingDialog{ button.row(); button.add(Core.bundle.format("save.wave", color + slot.getWave())); button.row(); - button.add(Core.bundle.format("save.difficulty", color + slot.getDifficulty())); - button.row(); button.label(() -> Core.bundle.format("save.autosave", color + Core.bundle.get(slot.isAutosave() ? "on" : "off"))); button.row(); button.label(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime())); @@ -175,7 +174,7 @@ public class LoadDialog extends FloatingDialog{ try{ slot.load(); state.set(State.playing); - }catch(Exception e){ + }catch(SaveException e){ Log.err(e); state.set(State.menu); logic.reset(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index abb038524d..b2b7068222 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -2,8 +2,6 @@ package io.anuke.mindustry.ui.dialogs; import io.anuke.arc.Core; import io.anuke.arc.input.KeyCode; -import io.anuke.arc.scene.style.Drawable; -import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.net.Net; @@ -12,12 +10,10 @@ import static io.anuke.mindustry.Vars.*; public class PausedDialog extends FloatingDialog{ private SaveDialog save = new SaveDialog(); private LoadDialog load = new LoadDialog(); - private Table missionTable; public PausedDialog(){ super("$menu"); shouldPause = true; - setup(); shown(this::rebuild); @@ -29,20 +25,14 @@ public class PausedDialog extends FloatingDialog{ } void rebuild(){ - missionTable.clear(); - missionTable.background((Drawable) null); - } + cont.clear(); - void setup(){ update(() -> { if(state.is(State.menu) && isShown()){ hide(); } }); - cont.table(t -> missionTable = t).colspan(mobile ? 3 : 2); - cont.row(); - if(!mobile){ float dw = 210f; cont.defaults().width(dw).height(50).pad(5f); @@ -50,12 +40,14 @@ public class PausedDialog extends FloatingDialog{ cont.addButton("$back", this::hide).colspan(2).width(dw*2 + 20f); cont.row(); - cont.addButton("$unlocks", ui.unlocks::show); + cont.addButton("database", ui.database::show); cont.addButton("$settings", ui.settings::show); - cont.row(); - cont.addButton("$savegame", save::show); - cont.addButton("$loadgame", load::show).disabled(b -> Net.active()); + if(!world.isZone()){ + cont.row(); + cont.addButton("$savegame", save::show); + cont.addButton("$loadgame", load::show).disabled(b -> Net.active()); + } cont.row(); @@ -77,11 +69,15 @@ public class PausedDialog extends FloatingDialog{ cont.addRowImageTextButton("$back", "icon-play-2", isize, this::hide); cont.addRowImageTextButton("$settings", "icon-tools", isize, ui.settings::show); - cont.addRowImageTextButton("$save", "icon-save", isize, save::show); - cont.row(); + if(!world.isZone()){ + cont.addRowImageTextButton("$save", "icon-save", isize, save::show); + + cont.row(); + + cont.addRowImageTextButton("$load", "icon-load", isize, load::show).disabled(b -> Net.active()); + } - cont.addRowImageTextButton("$load", "icon-load", isize, load::show).disabled(b -> Net.active()); cont.addRowImageTextButton("$hostserver.mobile", "icon-host", isize, ui.host::show).disabled(b -> Net.active()); cont.addRowImageTextButton("$quit", "icon-quit", isize, () -> { ui.showConfirm("$confirm", "$quit.confirm", () -> { diff --git a/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java deleted file mode 100644 index 094f6c9d08..0000000000 --- a/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.anuke.mindustry.ui.dialogs; - -import io.anuke.arc.Core; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.game.Team; - -import static io.anuke.mindustry.Vars.*; - -public class RestartDialog extends FloatingDialog{ - private Team winner; - - public RestartDialog(){ - super("$gameover"); - setFillParent(false); - shown(this::rebuild); - } - - public void show(Team winner){ - this.winner = winner; - show(); - } - - void rebuild(){ - buttons.clear(); - cont.clear(); - - buttons.margin(10); - - if(state.rules.pvp){ - cont.add(Core.bundle.format("gameover.pvp",winner.localized())).pad(6); - buttons.addButton("$menu", () -> { - hide(); - state.set(State.menu); - logic.reset(); - }).size(130f, 60f); - }else{ - if(control.isHighScore()){ - cont.add("$highscore").pad(6); - cont.row(); - } - cont.add(Core.bundle.format("wave.lasted", state.wave)).pad(12); - - buttons.addButton("$menu", () -> { - hide(); - state.set(State.menu); - logic.reset(); - }).size(130f, 60f); - } - } -} diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 7a06ff5240..c54b1c8b3f 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -126,7 +126,7 @@ public class SettingsMenuDialog extends SettingsDialog{ if(mobile){ game.checkPref("autotarget", true); } - game.sliderPref("saveinterval", 120, 10, 5 * 120, i -> Core.bundle.format("setting.seconds", i)); + game.sliderPref("saveinterval", 60, 10, 5 * 120, i -> Core.bundle.format("setting.seconds", i)); if(!mobile){ game.checkPref("crashreport", true); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java new file mode 100644 index 0000000000..66e67e6779 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java @@ -0,0 +1,284 @@ +package io.anuke.mindustry.ui.dialogs; + +import io.anuke.arc.Core; +import io.anuke.arc.collection.Array; +import io.anuke.arc.collection.ObjectSet; +import io.anuke.arc.graphics.Color; +import io.anuke.arc.graphics.g2d.Lines; +import io.anuke.arc.input.KeyCode; +import io.anuke.arc.math.Interpolation; +import io.anuke.arc.math.geom.Rectangle; +import io.anuke.arc.scene.Element; +import io.anuke.arc.scene.Group; +import io.anuke.arc.scene.actions.Actions; +import io.anuke.arc.scene.event.InputEvent; +import io.anuke.arc.scene.event.InputListener; +import io.anuke.arc.scene.event.Touchable; +import io.anuke.arc.scene.style.TextureRegionDrawable; +import io.anuke.arc.scene.ui.ImageButton; +import io.anuke.arc.scene.ui.layout.Table; +import io.anuke.arc.util.Align; +import io.anuke.arc.util.Log; +import io.anuke.arc.util.Structs; +import io.anuke.mindustry.content.TechTree; +import io.anuke.mindustry.content.TechTree.TechNode; +import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.ui.TreeLayout; +import io.anuke.mindustry.ui.TreeLayout.TreeNode; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; + +import static io.anuke.mindustry.Vars.*; + +public class TechTreeDialog extends FloatingDialog{ + private ObjectSet nodes = new ObjectSet<>(); + private TechTreeNode root = new TechTreeNode(TechTree.root, null); + private static final float nodeSize = 60f; + + public TechTreeDialog(){ + super(""); + + cont.setFillParent(true); + + TreeLayout layout = new TreeLayout(); + layout.gapBetweenLevels = 60f; + layout.gapBetweenNodes = 40f; + layout.layout(root); + + cont.add(new View()).grow(); + + { //debug code; TODO remove + ObjectSet used = new ObjectSet().select(t -> true); + for(TechTreeNode node : nodes){ + used.add(node.node.block); + } + Array recipes = content.blocks().select(r -> r.isVisible() && !used.contains(r)); + recipes.sort(Structs.comparing(r -> r.buildCost)); + + if(recipes.size > 0){ + Log.info("Recipe tree coverage: {0}%", (int)((float)nodes.size / content.blocks().select(Block::isVisible).size * 100)); + Log.info("Missing items: "); + recipes.forEach(r -> Log.info(" {0}", r)); + } + } + + shown(() -> checkNodes(root)); + addCloseButton(); + } + + @Override + protected void drawBackground(float x, float y){ + drawDefaultBackground(x, y); + } + + void checkNodes(TechTreeNode node){ + boolean locked = locked(node); + if(!locked) node.visible = true; + for(TreeNode child : node.children){ + TechTreeNode l = (TechTreeNode)child; + l.visible = !locked && l.node.block.isVisible(); + checkNodes(l); + } + } + + void showToast(String info){ + int maxIndex = 0; + + for(Element e : Core.scene.root.getChildren()){ + if("toast".equals(e.getName())){ + maxIndex = Math.max(maxIndex, (Integer)e.getUserObject() + 1); + } + } + + int m = maxIndex; + + Table table = new Table(); + table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor()); + table.top().add(info); + table.setName("toast"); + table.setUserObject(maxIndex); + table.update(() -> { + table.toFront(); + table.setPosition(Core.graphics.getWidth()/2f, Core.graphics.getHeight() - 21 - m*20f, Align.top); + }); + Core.scene.add(table); + } + + boolean locked(TreeNode node){ + return locked(((TechTreeNode)node).node); + } + + boolean locked(TechNode node){ + return !data.isUnlocked(node.block); + } + + class TechTreeNode extends TreeNode{ + final TechNode node; + boolean visible = true; + + public TechTreeNode(TechNode node, TreeNode parent){ + this.node = node; + this.parent = parent; + this.width = this.height = nodeSize; + nodes.add(this); + if(node.children != null){ + children = new TechTreeNode[node.children.size]; + for(int i = 0; i < children.length; i++){ + children[i] = new TechTreeNode(node.children.get(i), this); + } + } + } + } + + class View extends Group{ + float panX = 0, panY = -200; + boolean moved = false; + Rectangle clip = new Rectangle(); + ImageButton hoverNode; + Table infoTable = new Table(); + + { + infoTable.touchable(Touchable.enabled); + + for(TechTreeNode node : nodes){ + ImageButton button = new ImageButton(node.node.block.icon(Icon.medium), "node"); + button.clicked(() -> { + if(mobile){ + hoverNode = button; + rebuild(); + }else if(data.hasItems(node.node.requirements) && locked(node)){ + unlock(node.node); + } + }); + button.hovered(() -> { + if(!mobile && hoverNode != button && node.visible){ + hoverNode = button; + rebuild(); + } + }); + button.exited(() -> { + if(hoverNode == button && !infoTable.hasMouse() && !hoverNode.hasMouse()){ + hoverNode = null; + rebuild(); + } + }); + button.touchable(() -> !node.visible ? Touchable.disabled : Touchable.enabled); + button.setUserObject(node.node); + button.tapped(() -> moved = false); + button.setSize(nodeSize, nodeSize); + button.update(() -> { + button.setPosition(node.x + panX + width/2f, node.y + panY + height/2f, Align.center); + button.getStyle().up = Core.scene.skin.getDrawable(!locked(node) ? "content-background" : "content-background-locked"); + ((TextureRegionDrawable)button.getStyle().imageUp) + .setRegion(node.visible ? node.node.block.icon(Icon.medium) : Core.atlas.find("icon-tree-locked")); + button.getImage().setColor(!locked(node) ? Color.WHITE : Color.GRAY); + }); + addChild(button); + } + + addListener(new InputListener(){ + float lastX, lastY; + @Override + public void touchDragged(InputEvent event, float mx, float my, int pointer){ + panX -= lastX - mx; + panY -= lastY - my; + lastX = mx; + lastY = my; + moved = true; + } + + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ + lastX = x; + lastY = y; + return true; + } + }); + } + + void unlock(TechNode node){ + data.unlockContent(node.block); + data.removeItems(node.requirements); + showToast(Core.bundle.format("researched", node.block.formalName)); + checkNodes(root); + hoverNode = null; + rebuild(); + } + + void rebuild(){ + ImageButton button = hoverNode; + + infoTable.remove(); + infoTable.clear(); + infoTable.update(null); + + if(button == null) return; + + TechNode node = (TechNode)button.getUserObject(); + + infoTable.exited(() -> { + if(hoverNode == button && !infoTable.hasMouse() && !hoverNode.hasMouse()){ + hoverNode = null; + rebuild(); + } + }); + + infoTable.background("content-background"); + infoTable.update(() -> infoTable.setPosition(button.getX() + button.getWidth(), button.getY() + button.getHeight(), Align.topLeft)); + + infoTable.margin(0).left().defaults().left(); + + infoTable.addImageButton("icon-info", "node", 14*2, () -> ui.content.show(node.block)).growY().width(50f); + + infoTable.add().grow(); + + infoTable.table(desc -> { + desc.left().defaults().left(); + desc.add(node.block.formalName); + desc.row(); + if(locked(node)){ + desc.table(t -> { + t.left(); + for(ItemStack req : node.requirements){ + t.table(list -> { + list.left(); + list.addImage(req.item.getContentIcon()).size(8 * 3).padRight(3); + list.add(req.item.localizedName()).color(Color.LIGHT_GRAY); + list.add(" " + Math.min(data.items().get(req.item, 0), req.amount) + " / " + req.amount) + .color(data.has(req.item, req.amount) ? Color.LIGHT_GRAY : Color.SCARLET); + }).fillX().left(); + t.row(); + } + }); + }else{ + desc.add("$completed"); + } + }).pad(9); + + if(mobile && locked(node)){ + infoTable.row(); + infoTable.addImageTextButton("$research", "icon-check", "node", 16*2, () -> unlock(node)) + .disabled(b -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3); + } + + addChild(infoTable); + infoTable.pack(); + } + + @Override + public void draw(){ + float offsetX = panX + width/2f + x, offsetY = panY + height/2f + y; + + for(TreeNode node : nodes){ + for(TreeNode child : node.children){ + Lines.stroke(3f, locked(node) || locked(child) ? Palette.locked : Palette.accent); + + Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY); + } + } + + super.draw(); + } + } +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java deleted file mode 100644 index 95b5cb6ec9..0000000000 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockConsumeFragment.java +++ /dev/null @@ -1,131 +0,0 @@ -package io.anuke.mindustry.ui.fragments; - -import io.anuke.arc.Core; -import io.anuke.arc.collection.ObjectSet; -import io.anuke.arc.graphics.Color; -import io.anuke.arc.math.geom.Vector2; -import io.anuke.arc.scene.Element; -import io.anuke.arc.scene.Group; -import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.arc.util.Align; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.graphics.Palette; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.consumers.Consume; - -import static io.anuke.mindustry.Vars.*; - -public class BlockConsumeFragment extends Fragment{ - private Table table; - private Tile lastTile; - private boolean visible; - - @Override - public void build(Group parent){ - table = new Table(); - table.visible(() -> !state.is(State.menu) && visible); - table.setTransform(true); - - parent.addChild(new Element(){{update(() -> { - if(!Core.scene.hasMouse()){ - Tile tile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); - if(tile == null) return; - tile = tile.target(); - - if(tile != lastTile){ - if(tile.getTeam() == players[0].getTeam() && tile.block().consumes.hasAny()){ - show(tile); - }else if(visible){ - hide(); - } - lastTile = tile; - } - } - });}}); - - parent.setTransform(true); - parent.addChild(table); - } - - public void show(Tile tile){ - ObjectSet consumers = new ObjectSet<>(); - TileEntity entity = tile.entity; - Block block = tile.block(); - - table.clearChildren(); - - rebuild(block, entity); - visible = true; - - table.update(() -> { - - if(tile.entity == null || state.is(State.menu)){ - hide(); - return; - } - - boolean rebuild = false; - - for(Consume c : block.consumes.array()){ - boolean valid = c.isOptional() || c.valid(block, entity); - - if(consumers.contains(c) == valid){ - if(valid){ - consumers.remove(c); - }else{ - consumers.add(c); - } - rebuild = true; - } - } - - if(rebuild){ - rebuild(block, entity); - } - - Vector2 v = Core.input.mouseScreen(tile.drawx() - tile.block().size * tilesize / 2f + 0.25f, tile.drawy() + tile.block().size * tilesize / 2f); - table.pack(); - table.setPosition(v.x, v.y, Align.topRight); - }); - - table.act(Core.graphics.getDeltaTime()); - } - - public void hide(){ - table.clear(); - table.update(() -> {}); - visible = false; - } - - private void rebuild(Block block, TileEntity entity){ - table.clearChildren(); - table.left(); - - int scale = mobile ? 4 : 3; - - for(Consume c : block.consumes.array()){ - if(!c.isOptional() && !c.valid(block, entity)){ - boolean[] hovered = {false}; - - table.table("inventory", c::buildTooltip).visible(() -> hovered[0]).height(scale * 10 + 6).padBottom(-4).right().update(t -> { - if(t.getChildren().size == 0) t.remove(); - }).get().act(0); - - Table result = table.table(out -> { - out.addImage(c.getIcon()).size(10 * scale).color(Color.DARK_GRAY).padRight(-10 * scale).padBottom(-scale * 2); - out.addImage(c.getIcon()).size(10 * scale).color(Palette.accent); - out.addImage("icon-missing").size(10 * scale).color(Palette.remove).padLeft(-10 * scale); - }).size(10 * scale).get(); - - result.hovered(() -> hovered[0] = true); - if(!mobile){ - result.exited(() -> hovered[0] = false); - } - - table.row(); - } - } - } -} diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 5b8e23ebcf..ee0f2a0e29 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -4,7 +4,6 @@ import io.anuke.arc.Core; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.graphics.Color; -import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Interpolation; import io.anuke.arc.math.Mathf; import io.anuke.arc.scene.Element; @@ -13,7 +12,6 @@ import io.anuke.arc.scene.actions.Actions; import io.anuke.arc.scene.event.Touchable; import io.anuke.arc.scene.ui.Image; import io.anuke.arc.scene.ui.ImageButton; -import io.anuke.arc.scene.ui.Label; import io.anuke.arc.scene.ui.TextButton; import io.anuke.arc.scene.ui.layout.Stack; import io.anuke.arc.scene.ui.layout.Table; @@ -24,12 +22,12 @@ import io.anuke.arc.util.Time; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.StateChangeEvent; import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Packets.AdminAction; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.ui.IntFormat; import io.anuke.mindustry.ui.dialogs.FloatingDialog; @@ -76,7 +74,7 @@ public class HudFragment extends Fragment{ if(Net.active()){ i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-players"); }else{ - i.setDisabled(Net.active()); + i.setDisabled(false); i.getStyle().imageUp = Core.scene.skin.getDrawable(state.is(State.paused) ? "icon-play" : "icon-pause"); } }).get(); @@ -89,7 +87,7 @@ public class HudFragment extends Fragment{ ui.chatfrag.toggle(); } }else{ - ui.unlocks.show(); + ui.database.show(); } }).update(i -> { if(Net.active() && mobile){ @@ -131,7 +129,6 @@ public class HudFragment extends Fragment{ //fps display infolabel = cont.table(t -> { IntFormat fps = new IntFormat("fps"); - IntFormat tps = new IntFormat("tps"); IntFormat ping = new IntFormat("ping"); t.label(() -> fps.get(Core.graphics.getFramesPerSecond())).padRight(10); t.row(); @@ -199,6 +196,9 @@ public class HudFragment extends Fragment{ .update(label -> label.getColor().set(Color.ORANGE).lerp(Color.SCARLET, Mathf.absin(Time.time(), 2f, 1f)))); }); + parent.fill(t -> t.top().right().addRowImageTextButton("$launch", "icon-arrow-up", 8*3, () -> world.launchZone()) + .size(94f, 70f).visible(() -> world.isZone() && world.getZone().metCondition())); + //'saving' indicator parent.fill(t -> { t.bottom().visible(() -> !state.is(State.menu) && control.saves.isSaving()); @@ -230,7 +230,9 @@ public class HudFragment extends Fragment{ } /** Show unlock notification for a new recipe. */ - public void showUnlock(Recipe recipe){ + public void showUnlock(UnlockableContent content){ + //some content may not have icons... yet + if(content.getContentIcon() == null) return; //if there's currently no unlock notification... if(lastUnlockTable == null){ @@ -247,14 +249,10 @@ public class HudFragment extends Fragment{ Table in = new Table(); //create texture stack for displaying - Stack stack = new Stack(); - for(TextureRegion region : recipe.result.getCompactIcon()){ - Image image = new Image(region); - image.setScaling(Scaling.fit); - stack.add(image); - } + Image image = new Image(content.getContentIcon()); + image.setScaling(Scaling.fit); - in.add(stack).size(48f).pad(2); + in.add(image).size(48f).pad(2); //add to table table.add(in).padRight(8); @@ -290,11 +288,6 @@ public class HudFragment extends Fragment{ //get size of each element float size = 48f / Math.min(elements.size + 1, col); - //correct plurals if needed - if(esize == 1){ - ((Label) lastUnlockLayout.getParent().find(e -> e instanceof Label)).setText("$unlocked.plural"); - } - lastUnlockLayout.clearChildren(); lastUnlockLayout.defaults().size(size).pad(2); @@ -309,14 +302,10 @@ public class HudFragment extends Fragment{ //if there's space, add it if(esize < cap){ - Stack stack = new Stack(); - for(TextureRegion region : recipe.result.getCompactIcon()){ - Image image = new Image(region); - image.setScaling(Scaling.fit); - stack.add(image); - } + Image image = new Image(content.getContentIcon()); + image.setScaling(Scaling.fit); - lastUnlockLayout.add(stack); + lastUnlockLayout.add(image); }else{ //else, add a specific icon to denote no more space lastUnlockLayout.addImage("icon-add"); } @@ -364,20 +353,32 @@ public class HudFragment extends Fragment{ IntFormat wavef = new IntFormat("wave"); IntFormat enemyf = new IntFormat("wave.enemy"); IntFormat enemiesf = new IntFormat("wave.enemies"); + IntFormat waitingf = new IntFormat("wave.waiting"); table.clearChildren(); table.touchable(Touchable.enabled); - table.labelWrap(() -> - (state.enemies() > 0 && !state.rules.waveTimer ? - wavef.get(state.wave) + "\n" + (state.enemies() == 1 ? - enemyf.get(state.enemies()) : - enemiesf.get(state.enemies())) : - wavef.get(state.wave) + "\n" + - (state.rules.waveTimer ? - Core.bundle.format("wave.waiting", (int)(state.wavetime/60)) : - Core.bundle.get("waiting"))) - ).growX().pad(8f); + StringBuilder builder = new StringBuilder(); + + table.labelWrap(() -> { + builder.setLength(0); + builder.append(wavef.get(state.wave)); + builder.append("\n"); + + if(state.enemies() > 0 && !state.rules.waveTimer){ + if(state.enemies() == 1){ + builder.append(enemyf.get(state.enemies())); + }else{ + builder.append(enemiesf.get(state.enemies())); + } + }else if(state.rules.waveTimer){ + builder.append(waitingf.get((int)(state.wavetime/60))); + }else{ + builder.append(Core.bundle.get("waiting")); + } + + return builder; + }).growX().pad(8f); table.setDisabled(true); table.visible(() -> state.rules.waves); diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index d925633ce6..f1bc3facb7 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -62,7 +62,7 @@ public class MenuFragment extends Fragment{ join = new MobileButton("icon-add", isize, "$joingame", ui.join::show), editor = new MobileButton("icon-editor", isize, "$editor", () -> ui.loadAnd(ui.editor::show)), tools = new MobileButton("icon-tools", isize, "$settings", ui.settings::show), - unlocks = new MobileButton("icon-unlocks", isize, "$unlocks", ui.unlocks::show), + unlocks = new MobileButton("icon-unlocks", isize, "database", ui.database::show), donate = new MobileButton("icon-donate", isize, "$donate", Platform.instance::openDonations); if(Core.graphics.getWidth() > Core.graphics.getHeight()){ @@ -127,12 +127,6 @@ public class MenuFragment extends Fragment{ out.row(); - out.add(new MenuButton("icon-menu", "$changelog.title", ui.changelog::show)); - - out.add(new MenuButton("icon-unlocks", "$unlocks", ui.unlocks::show)); - - out.row(); - out.add(new MenuButton("icon-exit", "$quit", Core.app::exit)).width(bw).colspan(2); }); } diff --git a/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java b/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java index 89ea27ab5e..f69986634d 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/OverlayFragment.java @@ -3,20 +3,16 @@ package io.anuke.mindustry.ui.fragments; import io.anuke.mindustry.input.InputHandler; import io.anuke.arc.scene.Group; -/** - * Fragment for displaying overlays such as block inventories. One is created for each input handler. - */ +/**Fragment for displaying overlays such as block inventories. One is created for each input handler.*/ public class OverlayFragment extends Fragment{ public final BlockInventoryFragment inv; public final BlockConfigFragment config; - public final BlockConsumeFragment consume; private Group group = new Group(); public OverlayFragment(InputHandler input){ inv = new BlockInventoryFragment(input); config = new BlockConfigFragment(input); - consume = new BlockConsumeFragment(); } @Override @@ -26,9 +22,6 @@ public class OverlayFragment extends Fragment{ inv.build(group); config.build(group); - consume.build(group); - - //input.buildUI(group); } public void remove(){ diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java index 77f7f464a8..32a3fa7ecb 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -22,9 +22,8 @@ import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.type.Category; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.type.Recipe; -import io.anuke.mindustry.ui.ImageStack; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Block.Icon; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.OreBlock; @@ -33,8 +32,10 @@ import static io.anuke.mindustry.Vars.*; public class PlacementFragment extends Fragment{ final int rowWidth = 4; - Category currentCategory = Category.turret; + Array returnArray = new Array<>(); + Category currentCategory = Category.distribution; Block hovered, lastDisplay; + Tile lastHover; Tile hoverTile; Table blockTable, toggler, topTable; boolean shown = true; @@ -68,8 +69,8 @@ public class PlacementFragment extends Fragment{ int i = 0; for(KeyCode key : inputCatGrid){ if(Core.input.keyDown(key)){ - input.recipe = Recipe.getByCategory(Category.values()[i]).first(); - currentCategory = input.recipe.category; + input.block = getByCategory(Category.values()[i]).first(); + currentCategory = input.block.buildCategory; } i++; } @@ -79,19 +80,19 @@ public class PlacementFragment extends Fragment{ if(tile != null){ tile = tile.target(); - Recipe tryRecipe = Recipe.getByResult(tile.block()); - if(tryRecipe != null && data.isUnlocked(tryRecipe)){ - input.recipe = tryRecipe; - currentCategory = input.recipe.category; + Block tryRecipe = tile.block(); + if(tryRecipe.isVisible() && data.isUnlocked(tryRecipe)){ + input.block = tryRecipe; + currentCategory = input.block.buildCategory; return true; } } }else{ //select block int i = 0; - Array recipes = Recipe.getByCategory(currentCategory); + Array recipes = getByCategory(currentCategory); for(KeyCode key : inputGrid){ if(Core.input.keyDown(key)) - input.recipe = (i < recipes.size && data.isUnlocked(recipes.get(i))) ? recipes.get(i) : null; + input.block = (i < recipes.size && data.isUnlocked(recipes.get(i))) ? recipes.get(i) : null; i++; } } @@ -117,7 +118,7 @@ public class PlacementFragment extends Fragment{ ButtonGroup group = new ButtonGroup<>(); group.setMinCheckCount(0); - for(Recipe recipe : Recipe.getByCategory(currentCategory)){ + for(Block block : getByCategory(currentCategory)){ if(index++ % rowWidth == 0){ blockTable.row(); @@ -126,17 +127,17 @@ public class PlacementFragment extends Fragment{ boolean[] unlocked = {false}; ImageButton button = blockTable.addImageButton("icon-locked", "select", 8 * 4, () -> { - if(data.isUnlocked(recipe)){ - input.recipe = input.recipe == recipe ? null : recipe; + if(data.isUnlocked(block)){ + input.block = input.block == block ? null : block; } }).size(46f).group(group).get(); button.update(() -> { //color unplacable things gray - boolean ulock = data.isUnlocked(recipe); + boolean ulock = data.isUnlocked(block); TileEntity core = players[0].getClosestCore(); - Color color = core != null && (core.items.has(recipe.requirements) || state.rules.infiniteResources) ? Color.WHITE : ulock ? Color.GRAY : Color.WHITE; + Color color = core != null && (core.items.has(block.buildRequirements) || state.rules.infiniteResources) ? Color.WHITE : ulock ? Color.GRAY : Color.WHITE; button.forEach(elem -> elem.setColor(color)); - button.setChecked(input.recipe == recipe); + button.setChecked(input.block == block); if(ulock == unlocked[0]) return; unlocked[0] = ulock; @@ -144,13 +145,13 @@ public class PlacementFragment extends Fragment{ if(!ulock){ button.replaceImage(new Image("icon-locked")); }else{ - button.replaceImage(new ImageStack(recipe.result.getCompactIcon())); + button.replaceImage(new Image(block.icon(Icon.medium))); } }); - button.hovered(() -> hovered = recipe.result); + button.hovered(() -> hovered = block); button.exited(() -> { - if(hovered == recipe.result){ + if(hovered == block){ hovered = null; } }); @@ -162,25 +163,29 @@ public class PlacementFragment extends Fragment{ frame.table("button-edge-2", top -> { topTable = top; top.add(new Table()).growX().update(topTable -> { - if((tileDisplayBlock() == null && lastDisplay == getSelected() && !lastGround) || (tileDisplayBlock() != null && lastDisplay == tileDisplayBlock() && lastGround)) + //don't refresh unnecessarily + if((tileDisplayBlock() == null && lastDisplay == getSelected() && !lastGround) + || (tileDisplayBlock() != null && lastHover == hoverTile && lastGround)) return; topTable.clear(); topTable.top().left().margin(5); + lastHover = hoverTile; lastDisplay = getSelected(); lastGround = tileDisplayBlock() != null; if(lastDisplay != null){ //show selected recipe + lastGround = false; + topTable.table(header -> { header.left(); - header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8 * 4); - header.labelWrap(() -> - !data.isUnlocked(Recipe.getByResult(lastDisplay)) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName) + header.add(new Image(lastDisplay.icon(Icon.medium))).size(8 * 4); + header.labelWrap(() -> !data.isUnlocked(lastDisplay) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName) .left().width(190f).padLeft(5); header.add().growX(); - if(data.isUnlocked(Recipe.getByResult(lastDisplay))){ - header.addButton("?", "clear-partial", () -> ui.content.show(Recipe.getByResult(lastDisplay))) + if(data.isUnlocked(lastDisplay)){ + header.addButton("?", "clear-partial", () -> ui.content.show(lastDisplay)) .size(8 * 5).padTop(-5).padRight(-5).right().grow(); } }).growX().left(); @@ -189,7 +194,7 @@ public class PlacementFragment extends Fragment{ topTable.table(req -> { req.top().left(); - for(ItemStack stack : Recipe.getByResult(lastDisplay).requirements){ + for(ItemStack stack : lastDisplay.buildRequirements){ req.table(line -> { line.left(); line.addImage(stack.item.region).size(8 * 2); @@ -210,8 +215,18 @@ public class PlacementFragment extends Fragment{ }else if(tileDisplayBlock() != null){ //show selected tile lastDisplay = tileDisplayBlock(); - topTable.add(new ImageStack(lastDisplay.getDisplayIcon(hoverTile))).size(8 * 4); - topTable.labelWrap(lastDisplay.getDisplayName(hoverTile)).left().width(190f).padLeft(5); + topTable.table(t -> { + t.left(); + t.add(new Image(lastDisplay.getDisplayIcon(hoverTile))).size(8 * 4); + t.labelWrap(lastDisplay.getDisplayName(hoverTile)).left().width(190f).padLeft(5); + }).growX().left(); + if(hoverTile.getTeam() == players[0].getTeam()){ + topTable.row(); + topTable.table(t -> { + t.left().defaults().left(); + lastDisplay.display(hoverTile, t); + }).left().growX(); + } } }); }).colspan(3).fillX().visible(() -> getSelected() != null || tileDisplayBlock() != null).touchable(Touchable.enabled); @@ -230,7 +245,7 @@ public class PlacementFragment extends Fragment{ ButtonGroup group = new ButtonGroup<>(); for(Category cat : Category.values()){ - if(Recipe.getByCategory(cat).isEmpty()) continue; + if(getByCategory(cat).isEmpty()) continue; categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16 * 2, () -> { currentCategory = cat; @@ -248,6 +263,16 @@ public class PlacementFragment extends Fragment{ }); }); } + + Array getByCategory(Category cat){ + returnArray.clear(); + for(Block block : content.blocks()){ + if(block.buildCategory == cat && block.isVisible()){ + returnArray.add(block); + } + } + return returnArray; + } /** Returns the currently displayed block in the top box. */ Block getSelected(){ @@ -268,8 +293,8 @@ public class PlacementFragment extends Fragment{ } //block currently selected - if(control.input(0).recipe != null){ - toDisplay = control.input(0).recipe.result; + if(control.input(0).block != null){ + toDisplay = control.input(0).block; } //block hovered on in build menu diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 61ea19280d..e84613a38a 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -6,6 +6,7 @@ import io.anuke.arc.Graphics.Cursor.SystemCursor; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.EnumSet; import io.anuke.arc.collection.IntArray; +import io.anuke.arc.function.BooleanProvider; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; @@ -20,20 +21,27 @@ import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.effect.Puddle; import io.anuke.mindustry.entities.effect.RubbleDecal; -import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.graphics.CacheLayer; import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.type.Category; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.ui.Bar; +import io.anuke.mindustry.ui.ContentDisplay; import io.anuke.mindustry.world.consumers.ConsumePower; -import io.anuke.mindustry.world.meta.*; +import io.anuke.mindustry.world.meta.BlockFlag; +import io.anuke.mindustry.world.meta.BlockGroup; +import io.anuke.mindustry.world.meta.BlockStat; +import io.anuke.mindustry.world.meta.StatUnit; + +import java.util.Arrays; import static io.anuke.mindustry.Vars.*; -public class Block extends BaseBlock { +public class Block extends BlockStorage{ /** internal name */ public final String name; /** display name */ @@ -58,10 +66,8 @@ public class Block extends BaseBlock { public int health = -1; /** base block explosiveness */ public float baseExplosiveness = 0f; - /** whether this block can be placed on liquids. */ + /** whether this block can be placed on edges of liquids. */ public boolean floating = false; - /** stuff that drops when broken */ - public ItemStack drops = null; /** multiblock size */ public int size = 1; /** Whether to draw this block in the expanded draw range. */ @@ -80,34 +86,33 @@ public class Block extends BaseBlock { public boolean instantTransfer = false; /** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */ public BlockGroup group = BlockGroup.none; - /** List of block stats. */ - public BlockStats stats = new BlockStats(this); /** List of block flags. Used for AI indexing. */ public EnumSet flags; - /** Whether to automatically set the entity to 'sleeping' when created. */ - public boolean autoSleep; /** Whether the block can be tapped and selected to configure. */ public boolean configurable; /** Whether this block consumes touchDown events when tapped. */ public boolean consumesTap; /** The color of this block when displayed on the minimap or map preview. */ public Color minimapColor = Color.CLEAR; - /** View range of this block type. Use a value < 0 to disable. */ - public float viewRange = 10; - /**Whether the top icon is outlined, like a turret.*/ - public boolean turretIcon = false; /**Whether units target this block.*/ public boolean targetable = true; /**Whether the overdrive core has any effect on this block.*/ public boolean canOverdrive = true; - protected Array tempTiles = new Array<>(); - protected TextureRegion[] blockIcon; - protected TextureRegion[] icon; - protected TextureRegion[] compactIcon; - protected TextureRegion editorIcon; + /**Cost of constructing this block.*/ + public ItemStack[] buildRequirements = new ItemStack[]{}; + /**Category in place menu.*/ + public Category buildCategory = Category.distribution; + /**Cost of building this block; do not modify directly!*/ + public float buildCost; + /**Whether this block is visible and can currently be built.*/ + public BooleanProvider buildVisibility = () -> false; + public boolean alwaysUnlocked = false; - public TextureRegion region; + protected Array tempTiles = new Array<>(); + protected TextureRegion[] icons = new TextureRegion[Icon.values().length]; + protected TextureRegion[] generatedIcons; + protected TextureRegion region; public Block(String name){ this.name = name; @@ -116,24 +121,10 @@ public class Block extends BaseBlock { this.solid = false; } - /**Populates the array with all blocks that produce this content.*/ - public static void getByProduction(Array arr, Content result){ - arr.clear(); - for(Block block : content.blocks()){ - if(block.produces.get() == result){ - arr.add(block); - } - } - } - public boolean canBreak(Tile tile){ return true; } - public boolean dropsItem(Item item){ - return drops != null && drops.item == item; - } - public void onProximityRemoved(Tile tile){ if(tile.entity.power != null){ tile.block().powerGraphRemoved(tile); @@ -210,6 +201,14 @@ public class Block extends BaseBlock { public void drawPlace(int x, int y, int rotation, boolean valid){ } + public void draw(Tile tile){ + Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.getRotation() * 90 : 0); + } + + public void drawShadow(Tile tile){ + draw(tile); + } + /** Called after the block is placed by this client. */ public void playerPlaced(Tile tile){ } @@ -237,6 +236,21 @@ public class Block extends BaseBlock { } } + @Override + public String localizedName(){ + return formalName; + } + + @Override + public TextureRegion getContentIcon(){ + return icon(Icon.medium); + } + + @Override + public void displayInfo(Table table){ + ContentDisplay.displayBlock(table, this); + } + @Override public ContentType getContentType(){ return ContentType.block; @@ -255,6 +269,11 @@ public class Block extends BaseBlock { health = size * size * 40; } + buildCost = 0f; + for(ItemStack stack : buildRequirements){ + buildCost += stack.amount * stack.item.cost; + } + setStats(); consumes.checkRequired(this); @@ -314,7 +333,7 @@ public class Block extends BaseBlock { } public boolean synthetic(){ - return update || destructible || solid; + return update || destructible; } public void drawConfigure(Tile tile){ @@ -335,10 +354,6 @@ public class Block extends BaseBlock { if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity, StatUnit.items); } - public String name(){ - return name; - } - public boolean isSolidFor(Tile tile){ return false; } @@ -445,55 +460,51 @@ public class Block extends BaseBlock { } public TextureRegion getDisplayIcon(Tile tile){ - return getEditorIcon(); + return icon(Icon.medium); } - public TextureRegion getEditorIcon(){ - if(editorIcon == null){ - editorIcon = Core.atlas.find("block-icon-" + name, Core.atlas.find("clear")); + public void display(Tile tile, Table table){ + TileEntity entity = tile.entity; + + if(entity != null){ + table.table(bars -> { + bars.defaults().growX().height(18f).pad(4); + + displayBars(tile, bars); + }).growX(); + + table.marginBottom(-5); } - return editorIcon; } - /** Returns the icon used for displaying this block in the place menu */ - public TextureRegion[] getIcon(){ - if(icon == null){ - if(Core.atlas.has(name + "-icon")){ - icon = new TextureRegion[]{Core.atlas.find(name + "-icon")}; - }else if(Core.atlas.has(name)){ - icon = new TextureRegion[]{Core.atlas.find(name)}; - }else if(Core.atlas.has(name + "1")){ - icon = new TextureRegion[]{Core.atlas.find(name + "1")}; - }else{ - icon = new TextureRegion[]{}; - } + public void displayBars(Tile tile, Table bars){ + TileEntity entity = tile.entity; + + bars.add(new Bar("blocks.health", Palette.health, entity::healthf).blink(Color.WHITE)); + bars.row(); + + if(entity.liquids != null){ + bars.add(new Bar(() -> entity.liquids.current().localizedName(), () -> entity.liquids.current().color, () -> entity.liquids.total() / liquidCapacity)).growX(); + bars.row(); } - - return icon; } - /** Returns a list of regions that represent this block in the world */ - public TextureRegion[] getBlockIcon(){ - return getIcon(); - } - - /** Returns a list of icon regions that have been cropped to 8x8 */ - public TextureRegion[] getCompactIcon(){ - if(compactIcon == null){ - compactIcon = new TextureRegion[getIcon().length]; - for(int i = 0; i < compactIcon.length; i++){ - compactIcon[i] = iconRegion(getIcon()[i]); - } + public TextureRegion icon(Icon icon){ + if(icons[icon.ordinal()] == null){ + icons[icon.ordinal()] = Core.atlas.find(name + "-icon-" + icon.name()); } - return compactIcon; + return icons[icon.ordinal()]; } - /** Crops a regionto 8x8 */ - protected TextureRegion iconRegion(TextureRegion src){ - TextureRegion region = new TextureRegion(src); - region.setWidth((int)(8 / Draw.scl)); - region.setHeight((int)(8 / Draw.scl)); - return region; + protected TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name)}; + } + + public TextureRegion[] getGeneratedIcons(){ + if(generatedIcons == null){ + generatedIcons = generateIcons(); + } + return generatedIcons; } public boolean hasEntity(){ @@ -504,14 +515,6 @@ public class Block extends BaseBlock { return new TileEntity(); } - public void draw(Tile tile){ - Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.getRotation() * 90 : 0); - } - - public void drawShadow(Tile tile){ - draw(tile); - } - /** Offset for placing and drawing multiblocks. */ public float offset(){ return ((size + 1) % 2) * tilesize / 2f; @@ -521,18 +524,44 @@ public class Block extends BaseBlock { return size > 1; } - public Array getDebugInfo(Tile tile){ - return Array.with( - "block", tile.block().name, - "floor", tile.floor().name, - "x", tile.x, - "y", tile.y, - "entity.name", tile.entity.getClass(), - "entity.x", tile.entity.x, - "entity.y", tile.entity.y, - "entity.id", tile.entity.id, - "entity.items.total", hasItems ? tile.entity.items.total() : null, - "entity.graph", tile.entity.power != null && tile.entity.power.graph != null ? tile.entity.power.graph.getID() : null - ); + public boolean isVisible(){ + return buildVisibility.get() && !isHidden(); + } + + @Override + public boolean alwaysUnlocked(){ + return alwaysUnlocked; + } + + protected void requirements(Category cat, ItemStack[] stacks, boolean unlocked){ + requirements(cat, () -> true, stacks); + this.alwaysUnlocked = unlocked; + } + + protected void requirements(Category cat, ItemStack[] stacks){ + requirements(cat, () -> true, stacks); + } + + /**Sets up requirements. Use only this method to set up requirements.*/ + protected void requirements(Category cat, BooleanProvider visible, ItemStack[] stacks){ + this.buildCategory = cat; + this.buildRequirements = stacks; + this.buildVisibility = visible; + + Arrays.sort(buildRequirements, (a, b) -> Integer.compare(a.item.id, b.item.id)); + } + + public enum Icon{ + small(8 * 3), + medium(8 * 4), + large(8 * 6), + /**uses whatever the size of the block is*/ + full(0); + + public final int size; + + Icon(int size){ + this.size = size; + } } } diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BlockStorage.java similarity index 96% rename from core/src/io/anuke/mindustry/world/BaseBlock.java rename to core/src/io/anuke/mindustry/world/BlockStorage.java index cc9d0a7223..573aad8593 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BlockStorage.java @@ -10,15 +10,16 @@ import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.effect.Puddle; -import io.anuke.mindustry.game.MappableContent; +import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.consumers.ConsumeItem; import io.anuke.mindustry.world.consumers.ConsumeLiquid; import io.anuke.mindustry.world.consumers.Consumers; +import io.anuke.mindustry.world.meta.BlockStats; import io.anuke.mindustry.world.meta.Producers; -public abstract class BaseBlock extends MappableContent{ +public abstract class BlockStorage extends UnlockableContent{ public boolean hasItems; public boolean hasLiquids; public boolean hasPower; @@ -32,6 +33,7 @@ public abstract class BaseBlock extends MappableContent{ public float liquidCapacity = 10f; public float liquidFlowFactor = 4.9f; + public BlockStats stats = new BlockStats(); public Consumers consumes = new Consumers(); public Producers produces = new Producers(); @@ -269,4 +271,9 @@ public abstract class BaseBlock extends MappableContent{ } return false; } + + /** Returns whether this block's inventory has space and is ready for production.*/ + public boolean canProduce(Tile tile){ + return true; + } } diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java index c65cd729db..1e8a5eac5b 100644 --- a/core/src/io/anuke/mindustry/world/Build.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -11,7 +11,6 @@ import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.game.EventType.BlockBuildBeginEvent; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.type.ContentType; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity; import static io.anuke.mindustry.Vars.*; @@ -64,8 +63,8 @@ public class Build{ } /**Places a BuildBlock at this location.*/ - public static void beginPlace(Team team, int x, int y, Recipe recipe, int rotation){ - if(!validPlace(team, x, y, recipe.result, rotation)){ + public static void beginPlace(Team team, int x, int y, Block result, int rotation){ + if(!validPlace(team, x, y, result, rotation)){ return; } @@ -74,13 +73,12 @@ public class Build{ //just in case if(tile == null) return; - Block result = recipe.result; Block previous = tile.block(); Block sub = content.getByName(ContentType.block, "build" + result.size); tile.setBlock(sub, rotation); - tile.entity().setConstruct(previous, recipe); + tile.entity().setConstruct(previous, result); tile.setTeam(team); if(result.isMultiblock()){ @@ -107,9 +105,7 @@ public class Build{ /**Returns whether a tile can be placed at this location by this team.*/ public static boolean validPlace(Team team, int x, int y, Block type, int rotation){ - Recipe recipe = Recipe.getByResult(type); - - if(recipe == null || (!recipe.visibility.usable())){ + if(!type.isVisible() || type.isHidden()){ return false; } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index e9a80f3a74..7ce5e6453f 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -212,9 +212,9 @@ public class Tile implements Position, TargetTrait{ return link != 0; } - /** Sets this to a linked tile, which sets the block to a blockpart. dx and dy can only be -8-7. */ + /** Sets this to a linked tile, which sets the block to a part. dx and dy can only be -8-7. */ public void setLinked(byte dx, byte dy){ - setBlock(Blocks.blockpart); + setBlock(Blocks.part); link = Pack.byteByte((byte)(dx + 8), (byte)(dy + 8)); } @@ -418,7 +418,7 @@ public class Tile implements Position, TargetTrait{ Block block = block(); Block floor = floor(); - return floor.name() + ":" + block.name() + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) + + return floor.name + ":" + block.name + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) + (link != 0 ? " link=[" + (Pack.leftByte(link) - 8) + ", " + (Pack.rightByte(link) - 8) + "]" : ""); } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/blocks/BlockPart.java b/core/src/io/anuke/mindustry/world/blocks/BlockPart.java index 476829489e..2e06d62177 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BlockPart.java +++ b/core/src/io/anuke/mindustry/world/blocks/BlockPart.java @@ -6,17 +6,16 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; /** - * Used for multiblocks. Each block that is not the center of the multiblock is a blockpart. + * Used for multiblocks. Each block that is not the center of the multiblock is a part. * Think of these as delegates to the actual block; all events are passed to the target block. * They are made to share all properties from the linked tile/block. */ public class BlockPart extends Block{ public BlockPart(){ - super("blockpart"); + super("part"); solid = false; hasPower = hasItems = hasLiquids = true; - viewRange = -1; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java index 5e2ac59189..a6ca205ce3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.world.blocks; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; +import io.anuke.arc.Events; import io.anuke.arc.Graphics.Cursor; import io.anuke.arc.Graphics.Cursor.SystemCursor; import io.anuke.arc.entities.Effects; @@ -15,13 +16,13 @@ import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.effect.RubbleDecal; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; +import io.anuke.mindustry.game.EventType.BlockBuildEndEvent; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.modules.ItemModule; @@ -46,8 +47,10 @@ public class BuildBlock extends Block{ @Remote(called = Loc.server) public static void onDeconstructFinish(Tile tile, Block block){ + Team team = tile.getTeam(); Effects.effect(Fx.breakBlock, tile.drawx(), tile.drawy(), block.size); world.removeBlock(tile); + Events.fire(new BlockBuildEndEvent(tile, team, true)); } @Remote(called = Loc.server) @@ -64,24 +67,25 @@ public class BuildBlock extends Block{ //event first before they can recieve the placed() event modification results Core.app.post(() -> tile.block().playerPlaced(tile)); } + Core.app.post(() -> Events.fire(new BlockBuildEndEvent(tile, team, false))); } @Override public String getDisplayName(Tile tile){ BuildEntity entity = tile.entity(); - return Core.bundle.format("block.constructing", entity.recipe == null ? entity.previous.formalName : entity.recipe.result.formalName); + return Core.bundle.format("block.constructing", entity.block == null ? entity.previous.formalName : entity.block.formalName); } @Override public TextureRegion getDisplayIcon(Tile tile){ BuildEntity entity = tile.entity(); - return (entity.recipe == null ? entity.previous : entity.recipe.result).getEditorIcon(); + return (entity.block == null ? entity.previous : entity.block).icon(Icon.full); } @Override public boolean isSolidFor(Tile tile){ BuildEntity entity = tile.entity(); - return entity == null || (entity.recipe != null && entity.recipe.result.solid) || entity.previous == null || entity.previous.solid; + return entity == null || (entity.block != null && entity.block.solid) || entity.previous == null || entity.previous.solid; } @Override @@ -94,9 +98,9 @@ public class BuildBlock extends Block{ BuildEntity entity = tile.entity(); //if the target is constructible, begin constructing - if(entity.recipe != null){ + if(entity.block != null){ player.clearBuilding(); - player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.getRotation(), entity.recipe)); + player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.getRotation(), entity.block)); } } @@ -114,15 +118,13 @@ public class BuildBlock extends Block{ BuildEntity entity = tile.entity(); //When breaking, don't draw the previous block... since it's the thing you were breaking - if(entity.recipe != null && entity.previous == entity.recipe.result){ + if(entity.block != null && entity.previous == entity.block){ return; } if(entity.previous == null) return; - for(TextureRegion region : entity.previous.getBlockIcon()){ - Draw.rect(region, tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0); - } + Draw.rect(entity.previous.icon(Icon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0); } @Override @@ -132,11 +134,11 @@ public class BuildBlock extends Block{ Shaders.blockbuild.color = Palette.accent; - Block target = entity.recipe == null ? entity.previous : entity.recipe.result; + Block target = entity.block == null ? entity.previous : entity.block; if(target == null) return; - for(TextureRegion region : target.getBlockIcon()){ + for(TextureRegion region : target.getGeneratedIcons()){ Shaders.blockbuild.region = region; Shaders.blockbuild.progress = entity.progress; @@ -148,6 +150,7 @@ public class BuildBlock extends Block{ @Override public void drawShadow(Tile tile){ //don't + //TODO maybe do } @Override @@ -160,7 +163,7 @@ public class BuildBlock extends Block{ * The recipe of the block that is being constructed. * If there is no recipe for this block, as is the case with rocks, 'previous' is used. */ - public Recipe recipe; + public Block block; public float progress = 0; public float buildCost; @@ -175,16 +178,16 @@ public class BuildBlock extends Block{ private float[] totalAccumulator; public void construct(Unit builder, TileEntity core, float amount){ - if(recipe == null){ + if(block == null){ damage(99999); return; } float maxProgress = checkRequired(core.items, amount, false); - for(int i = 0; i < recipe.requirements.length; i++){ - accumulator[i] += Math.min(recipe.requirements[i].amount * maxProgress, recipe.requirements[i].amount - totalAccumulator[i] + 0.00001f); //add min amount progressed to the accumulator - totalAccumulator[i] = Math.min(totalAccumulator[i] + recipe.requirements[i].amount * maxProgress, recipe.requirements[i].amount); + for(int i = 0; i < block.buildRequirements.length; i++){ + accumulator[i] += Math.min(block.buildRequirements[i].amount * maxProgress, block.buildRequirements[i].amount - totalAccumulator[i] + 0.00001f); //add min amount progressed to the accumulator + totalAccumulator[i] = Math.min(totalAccumulator[i] + block.buildRequirements[i].amount * maxProgress, block.buildRequirements[i].amount); } maxProgress = checkRequired(core.items, maxProgress, true); @@ -196,24 +199,23 @@ public class BuildBlock extends Block{ } if(progress >= 1f || state.rules.infiniteResources){ - Call.onConstructFinish(tile, recipe.result, builderID, tile.getRotation(), builder.getTeam()); + Call.onConstructFinish(tile, block, builderID, tile.getRotation(), builder.getTeam()); } } public void deconstruct(Unit builder, TileEntity core, float amount){ - Recipe recipe = Recipe.getByResult(previous); - if(recipe != null){ - ItemStack[] requirements = recipe.requirements; + if(block != null){ + ItemStack[] requirements = block.buildRequirements; if(requirements.length != accumulator.length || totalAccumulator.length != requirements.length){ setDeconstruct(previous); } for(int i = 0; i < requirements.length; i++){ - accumulator[i] += Math.min(requirements[i].amount * amount / 2f, requirements[i].amount/2f - totalAccumulator[i]); //add scaled amount progressed to the accumulator + accumulator[i] += Math.min(requirements[i].amount * amount / 2f, requirements[i].amount / 2f - totalAccumulator[i]); //add scaled amount progressed to the accumulator totalAccumulator[i] = Math.min(totalAccumulator[i] + requirements[i].amount * amount / 2f, requirements[i].amount); - int accumulated = (int) (accumulator[i]); //get amount + int accumulated = (int)(accumulator[i]); //get amount if(amount > 0 && accumulated > 0){ //if it's positive, add it to the core int accepting = core.tile.block().acceptStack(requirements[i].item, accumulated, core.tile, builder); @@ -227,21 +229,21 @@ public class BuildBlock extends Block{ progress = Mathf.clamp(progress - amount); if(progress <= 0 || state.rules.infiniteResources){ - Call.onDeconstructFinish(tile, this.recipe == null ? previous : this.recipe.result); + Call.onDeconstructFinish(tile, this.block == null ? previous : this.block); } } private float checkRequired(ItemModule inventory, float amount, boolean remove){ float maxProgress = amount; - for(int i = 0; i < recipe.requirements.length; i++){ + for(int i = 0; i < block.buildRequirements.length; i++){ int required = (int) (accumulator[i]); //calculate items that are required now - if(inventory.get(recipe.requirements[i].item) == 0){ + if(inventory.get(block.buildRequirements[i].item) == 0){ maxProgress = 0f; }else if(required > 0){ //if this amount is positive... //calculate how many items it can actually use - int maxUse = Math.min(required, inventory.get(recipe.requirements[i].item)); + int maxUse = Math.min(required, inventory.get(block.buildRequirements[i].item)); //get this as a fraction float fraction = maxUse / (float) required; @@ -252,7 +254,7 @@ public class BuildBlock extends Block{ //remove stuff that is actually used if(remove){ - inventory.remove(recipe.requirements[i].item, maxUse); + inventory.remove(block.buildRequirements[i].item, maxUse); } } //else, no items are required yet, so just keep going @@ -265,24 +267,24 @@ public class BuildBlock extends Block{ return progress; } - public void setConstruct(Block previous, Recipe recipe){ - this.recipe = recipe; + public void setConstruct(Block previous, Block block){ + this.block = block; this.previous = previous; - this.accumulator = new float[recipe.requirements.length]; - this.totalAccumulator = new float[recipe.requirements.length]; - this.buildCost = recipe.cost; + this.accumulator = new float[block.buildRequirements.length]; + this.totalAccumulator = new float[block.buildRequirements.length]; + this.buildCost = block.buildCost; } public void setDeconstruct(Block previous){ this.previous = previous; this.progress = 1f; - if(Recipe.getByResult(previous) != null){ - this.recipe = Recipe.getByResult(previous); - this.accumulator = new float[Recipe.getByResult(previous).requirements.length]; - this.totalAccumulator = new float[Recipe.getByResult(previous).requirements.length]; - this.buildCost = Recipe.getByResult(previous).cost; + if(previous.buildCost > 1f){ + this.block = previous; + this.accumulator = new float[previous.buildRequirements.length]; + this.totalAccumulator = new float[previous.buildRequirements.length]; + this.buildCost = previous.buildCost; }else{ - this.buildCost = 20f; //default no-recipe build cost is 20 + this.buildCost = 20f; //default no-requirement build cost is 20 } } @@ -290,7 +292,7 @@ public class BuildBlock extends Block{ public void write(DataOutput stream) throws IOException{ stream.writeFloat(progress); stream.writeShort(previous == null ? -1 : previous.id); - stream.writeShort(recipe == null ? -1 : recipe.result.id); + stream.writeShort(block == null ? -1 : block.id); if(accumulator == null){ stream.writeByte(-1); @@ -320,10 +322,10 @@ public class BuildBlock extends Block{ } if(pid != -1) previous = content.block(pid); - if(rid != -1) recipe = Recipe.getByResult(content.block(rid)); + if(rid != -1) block = content.block(rid); - if(recipe != null){ - buildCost = recipe.cost; + if(block != null){ + buildCost = block.buildCost; }else{ buildCost = 20f; } diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index 52cb877db8..247320b172 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -2,22 +2,18 @@ package io.anuke.mindustry.world.blocks; import io.anuke.arc.Core; import io.anuke.arc.entities.Effects.Effect; -import io.anuke.arc.function.Predicate; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; -import io.anuke.arc.math.geom.Geometry; -import io.anuke.arc.math.geom.Vector2; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.content.StatusEffects; +import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -import static io.anuke.mindustry.Vars.tilesize; - public class Floor extends Block{ /** number of different variant regions to use */ public int variants; @@ -43,18 +39,15 @@ public class Floor extends Block{ public Color liquidColor; /** liquids that drop from this block, used for pumps */ public Liquid liquidDrop = null; + /** item that drops from this block, used for drills */ + public Item itemDrop = null; /** Whether ores generate on this block. */ public boolean hasOres = false; /** whether this block can be drowned in */ public boolean isLiquid; - /** if true, this block cannot be mined by players. useful for annoying things like stone. */ + /** if true, this block cannot be mined by players. useful for annoying things like sand. */ public boolean playerUnmineable = false; - protected TextureRegion edgeRegion; - protected TextureRegion[] edgeRegions; protected TextureRegion[] variantRegions; - protected Vector2[] offsets; - protected Predicate blends = block -> block != this && !block.blendOverride(this); - protected boolean blend = true; public Floor(String name){ super(name); @@ -65,36 +58,6 @@ public class Floor extends Block{ public void load(){ super.load(); - if(blend){ - edgeRegion = Core.atlas.has(name + "edge") ? Core.atlas.find(name + "edge") : Core.atlas.find(edge + "edge"); - edgeRegions = new TextureRegion[8]; - offsets = new Vector2[8]; - - for(int i = 0; i < 8; i++){ - int dx = Geometry.d8[i].x, dy = Geometry.d8[i].y; - - TextureRegion result = new TextureRegion(); - - int padSize = (int)(tilesize/Draw.scl/2); - int texSize = (int)(tilesize/Draw.scl); - int totSize = padSize + texSize; - - int sx = -dx * texSize + padSize/2, sy = -dy * texSize + padSize/2; - int x = Mathf.clamp(sx, 0, totSize); - int y = Mathf.clamp(sy, 0, totSize); - int w = Mathf.clamp(sx + texSize, 0, totSize) - x, h = Mathf.clamp(sy + texSize, 0, totSize) - y; - - float rx = Mathf.clamp(dx * texSize, 0, texSize - w); - float ry = Mathf.clamp(dy * texSize, 0, texSize - h); - - result.setTexture(edgeRegion.getTexture()); - result.set(edgeRegion.getX() + x, edgeRegion.getY() + y + h, w, -h); - - edgeRegions[i] = result; - offsets[i] = new Vector2(-padSize + rx, -padSize + ry); - } - } - //load variant regions for drawing if(variants > 0){ variantRegions = new TextureRegion[variants]; @@ -124,34 +87,11 @@ public class Floor extends Block{ Mathf.random.setSeed(tile.pos()); Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy()); - - /* - if(tile.hasCliffs() && cliffRegions != null){ - for(int i = 0; i < 4; i++){ - if((tile.getCliffs() & (1 << i * 2)) != 0){ - Draw.colorl(i > 1 ? 0.6f : 1f); - - boolean above = (tile.getCliffs() & (1 << ((i + 1) % 4) * 2)) != 0, below = (tile.getCliffs() & (1 << (Mathf.mod(i - 1, 4)) * 2)) != 0; - - if(above && below){ - Draw.rect(cliffRegions[0], tile.worldx(), tile.worldy(), i * 90); - }else if(above){ - Draw.rect(cliffRegions[1], tile.worldx(), tile.worldy(), i * 90); - }else if(below){ - Draw.rect(cliffRegions[2], tile.worldx(), tile.worldy(), i * 90); - }else{ - Draw.rect(cliffRegions[3], tile.worldx(), tile.worldy(), i * 90); - } - } - } - } - Draw.reset(); - - drawEdges(tile, false);*/ } - public boolean blendOverride(Block block){ - return false; + @Override + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(Core.atlas.has(name) ? name : name + "1")}; } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java b/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java index 939da4b122..9cb743e41e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/LiquidBlock.java @@ -30,8 +30,8 @@ public class LiquidBlock extends Block{ } @Override - public TextureRegion[] getIcon(){ - return new TextureRegion[]{Core.atlas.find(name() + "-bottom"), Core.atlas.find(name() + "-top")}; + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name + "-top")}; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java index 247162d8fc..3d64d8509a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java @@ -2,10 +2,8 @@ package io.anuke.mindustry.world.blocks; import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.graphics.g2d.Draw; -import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -17,7 +15,7 @@ public class OreBlock extends Floor{ public OreBlock(Item ore, Floor base){ super("ore-" + ore.name + "-" + base.name); this.formalName = ore.localizedName() + " " + base.formalName; - this.drops = new ItemStack(ore, 1); + this.itemDrop = ore; this.base = base; this.variants = 3; this.minimapColor = ore.color; @@ -28,15 +26,7 @@ public class OreBlock extends Floor{ @Override public String getDisplayName(Tile tile){ - return drops.item.localizedName(); - } - - @Override - public TextureRegion getEditorIcon(){ - if(editorIcon == null){ - editorIcon = variantRegions[0]; - } - return editorIcon; + return itemDrop.localizedName(); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/Rock.java b/core/src/io/anuke/mindustry/world/blocks/Rock.java index 57680e6b75..65c68a2c27 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Rock.java +++ b/core/src/io/anuke/mindustry/world/blocks/Rock.java @@ -19,11 +19,18 @@ public class Rock extends Block{ @Override public void draw(Tile tile){ + Draw.colorl(1f - tile.getRotation() / 4f); if(variants > 0){ Draw.rect(regions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, regions.length - 1))], tile.worldx(), tile.worldy()); }else{ Draw.rect(region, tile.worldx(), tile.worldy()); } + Draw.color(); + } + + @Override + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name + "1")}; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/StaticWall.java b/core/src/io/anuke/mindustry/world/blocks/StaticWall.java new file mode 100644 index 0000000000..df881c880b --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/StaticWall.java @@ -0,0 +1,13 @@ +package io.anuke.mindustry.world.blocks; + +import io.anuke.mindustry.graphics.CacheLayer; + +public class StaticWall extends Rock{ + + public StaticWall(String name){ + super(name); + breakable = alwaysReplace = false; + solid = true; + cacheLayer = CacheLayer.walls; + } +} diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java index 47fe135c5a..f2f41708aa 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -14,7 +14,7 @@ import java.io.DataOutput; import java.io.IOException; public class ItemTurret extends CooledTurret{ - protected int maxAmmo = 50; + protected int maxAmmo = 30; protected ObjectMap ammo = new ObjectMap<>(); public ItemTurret(String name){ diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java index 6a07a00846..5b6e97a40f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java @@ -83,7 +83,6 @@ public abstract class Turret extends Block{ solid = true; layer = Layer.turret; group = BlockGroup.turrets; - turretIcon = true; flags = EnumSet.of(BlockFlag.turret); } @@ -92,11 +91,6 @@ public abstract class Turret extends Block{ return false; } - @Override - public void init(){ - super.init(); - viewRange = range; - } @Override public void load(){ @@ -110,10 +104,6 @@ public abstract class Turret extends Block{ @Override public void setStats(){ super.setStats(); - /* - if(ammo != null) stats.add("ammo", ammo); - if(ammo != null) stats.add("ammocapacity", maxAmmo); - if(ammo != null) stats.add("ammoitem", ammoMultiplier);*/ stats.add(BlockStat.shootRange, range, StatUnit.blocks); stats.add(BlockStat.inaccuracy, (int) inaccuracy, StatUnit.degrees); @@ -142,19 +132,8 @@ public abstract class Turret extends Block{ } @Override - public TextureRegion[] getBlockIcon(){ - if(blockIcon == null){ - blockIcon = new TextureRegion[]{Core.atlas.find("block-icon-" + name)}; - } - return blockIcon; - } - - @Override - public TextureRegion[] getCompactIcon(){ - if(compactIcon == null){ - compactIcon = new TextureRegion[]{iconRegion(Core.atlas.find("block-icon-" + name))}; - } - return compactIcon; + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find("block-" + size), Core.atlas.find(name)}; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java index 24c318b2bd..0115340429 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java @@ -101,11 +101,8 @@ public class Conduit extends LiquidBlock{ } @Override - public TextureRegion[] getIcon(){ - if(icon == null){ - icon = new TextureRegion[]{Core.atlas.find("conduit-bottom"), Core.atlas.find(name + "-top-0")}; - } - return icon; + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find("conduit-bottom"), Core.atlas.find(name + "-top-0")}; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java index 939a3bbe8e..814352f1bd 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.world.blocks.distribution; import io.anuke.arc.Core; -import io.anuke.arc.collection.Array; import io.anuke.arc.collection.LongArray; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; @@ -48,7 +47,6 @@ public class Conveyor extends Block{ layer = Layer.overlay; group = BlockGroup.transportation; hasItems = true; - autoSleep = true; itemCapacity = 4; } @@ -122,11 +120,8 @@ public class Conveyor extends Block{ } @Override - public TextureRegion[] getIcon(){ - if(icon == null){ - icon = new TextureRegion[]{Core.atlas.find(name + "-0-0")}; - } - return super.getIcon(); + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name + "-0-0")}; } @Override @@ -208,8 +203,6 @@ public class Conveyor extends Block{ pos.x = 0f; } pos.x = Mathf.lerpDelta(pos.x, 0, 0.1f); - }else{ - pos.x = Mathf.lerpDelta(pos.x, pos.seed / offsetScl, 0.1f); } pos.y = Mathf.clamp(pos.y); @@ -294,7 +287,7 @@ public class Conveyor extends Block{ ConveyorEntity entity = tile.entity(); for(int i = amount - 1; i >= 0; i--){ - long result = ItemPos.packItem(item, 0f, i * itemSpace, (byte) Mathf.random(255)); + long result = ItemPos.packItem(item, 0f, i * itemSpace); entity.convey.insert(0, result); entity.items.add(item, 1); } @@ -322,7 +315,7 @@ public class Conveyor extends Block{ ConveyorEntity entity = tile.entity(); entity.noSleep(); - long result = ItemPos.packItem(item, y * 0.9f, pos, (byte) Mathf.random(255)); + long result = ItemPos.packItem(item, y * 0.9f, pos); tile.entity.items.add(item, 1); @@ -339,17 +332,6 @@ public class Conveyor extends Block{ entity.lastInserted = (byte)(entity.convey.size-1); } - @Override - public Array getDebugInfo(Tile tile){ - ConveyorEntity entity = tile.entity(); - Array arr = super.getDebugInfo(tile); - arr.addAll(Array.with( - "clogHeat", entity.clogHeat, - "sleeping", entity.isSleeping() - )); - return arr; - } - @Override public TileEntity newEntity(){ return new ConveyorEntity(); @@ -399,17 +381,15 @@ public class Conveyor extends Block{ Item item; float x, y; - byte seed; private ItemPos(){ } - static long packItem(Item item, float x, float y, byte seed){ + static long packItem(Item item, float x, float y){ short[] shorts = packShorts; shorts[0] = (short) item.id; shorts[1] = (short) (x * Short.MAX_VALUE); shorts[2] = (short) ((y - 1f) * Short.MAX_VALUE); - shorts[3] = seed; return Pack.longShorts(shorts); } @@ -419,13 +399,11 @@ public class Conveyor extends Block{ short itemid = values[0]; float x = values[1] / (float) Short.MAX_VALUE; float y = ((float) values[2]) / Short.MAX_VALUE + 1f; - byte seed = (byte) values[3]; byte[] bytes = writeByte; bytes[0] = (byte) itemid; bytes[1] = (byte) (x * 127); bytes[2] = (byte) (y * 255 - 128); - bytes[3] = seed; return Pack.intBytes(bytes); } @@ -436,13 +414,11 @@ public class Conveyor extends Block{ byte itemid = values[0]; float x = values[1] / 127f; float y = ((int) values[2] + 128) / 255f; - byte seed = values[3]; short[] shorts = writeShort; shorts[0] = (short) itemid; shorts[1] = (short) (x * Short.MAX_VALUE); shorts[2] = (short) ((y - 1f) * Short.MAX_VALUE); - shorts[3] = seed; return Pack.longShorts(shorts); } @@ -456,12 +432,11 @@ public class Conveyor extends Block{ x = values[1] / (float) Short.MAX_VALUE; y = ((float) values[2]) / Short.MAX_VALUE + 1f; - seed = (byte) values[3]; return this; } long pack(){ - return packItem(item, x, y, seed); + return packItem(item, x, y); } } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java index 040f0efda8..49ab325cd2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java @@ -23,11 +23,11 @@ public class LiquidJunction extends LiquidBlock{ @Override public void draw(Tile tile){ - Draw.rect(name(), tile.worldx(), tile.worldy()); + Draw.rect(name, tile.worldx(), tile.worldy()); } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name)}; } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java index e890f4bfd4..fc24bb7d42 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -109,11 +109,8 @@ public class MassDriver extends Block{ } @Override - public TextureRegion[] getBlockIcon(){ - if(blockIcon == null){ - blockIcon = new TextureRegion[]{region, turretRegion}; - } - return super.getBlockIcon(); + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-turret")}; } @Override @@ -130,13 +127,6 @@ public class MassDriver extends Block{ stats.add(BlockStat.powerShot, consumes.get(ConsumePower.class).powerCapacity * powerPercentageUsed, StatUnit.powerUnits); } - @Override - public void init(){ - super.init(); - - viewRange = range; - } - @Override public void update(Tile tile){ MassDriverEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java index 22310893d2..77d36761cd 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java @@ -96,7 +96,7 @@ public class FusionReactor extends PowerGenerator{ } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name), Core.atlas.find(name + "-top")}; } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java index 658a6926dc..fd7a51833a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java @@ -17,7 +17,7 @@ public class LiquidHeatGenerator extends ItemLiquidGenerator{ super.setStats(); stats.remove(BlockStat.basePowerGeneration); - // Right now, Lava is the only thing that can be used. + // right now, Lava is the only thing that can be used. stats.add(BlockStat.basePowerGeneration, powerProduction * getLiquidEfficiency(Liquids.slag) / maxLiquidGenerate * 60f, StatUnit.powerSecond); } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java b/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java index 4690981ed6..0144971bfe 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java @@ -43,7 +43,7 @@ public class Compressor extends PowerCrafter{ } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")}; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java index 323586d846..59cd3d8da9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java @@ -92,7 +92,7 @@ public class Cultivator extends Drill{ } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top"),}; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java index 1b5c76547d..61600aa5fe 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -11,12 +11,11 @@ import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; -import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.content.Fx; +import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeLiquid; @@ -114,10 +113,15 @@ public class Drill extends Block{ } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")}; } + @Override + public boolean canProduce(Tile tile){ + return tile.entity.items.total() < itemCapacity; + } + @Override public void setStats(){ super.setStats(); @@ -137,7 +141,7 @@ public class Drill extends Block{ table.addImage(item.name + "1").size(8 * 3).padRight(2).padLeft(2).padTop(3).padBottom(3); table.add(item.localizedName()); if(i != list.size - 1){ - table.add("/"); + table.add("/").padLeft(5).padRight(5); } } }); @@ -239,13 +243,13 @@ public class Drill extends Block{ } public Item getDrop(Tile tile){ - return tile.floor().drops.item; + return tile.floor().itemDrop; } public boolean isValid(Tile tile){ if(tile == null) return false; - ItemStack drops = tile.floor().drops; - return drops != null && drops.item.hardness <= tier; + Item drops = tile.floor().itemDrop; + return drops != null && drops.hardness <= tier; } public static class DrillEntity extends TileEntity{ diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java index efebd3c73f..cc1e4c4830 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java @@ -48,7 +48,7 @@ public class Fracker extends SolidPump{ } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")}; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java index 21bcebe89c..eab07cc6c4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java @@ -1,7 +1,10 @@ package io.anuke.mindustry.world.blocks.production; -import io.anuke.arc.Core; -import io.anuke.arc.graphics.g2d.TextureRegion; +import io.anuke.arc.entities.Effects; +import io.anuke.arc.entities.Effects.Effect; +import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Item; @@ -10,11 +13,6 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeItem; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; -import io.anuke.arc.util.Time; -import io.anuke.arc.graphics.g2d.Draw; -import io.anuke.arc.math.Mathf; import java.io.DataInput; import java.io.DataOutput; @@ -52,7 +50,7 @@ public class GenericCrafter extends Block{ @Override public void draw(Tile tile){ - Draw.rect(name(), tile.drawx(), tile.drawy()); + Draw.rect(name, tile.drawx(), tile.drawy()); if(!hasLiquids) return; @@ -62,11 +60,6 @@ public class GenericCrafter extends Block{ Draw.color(); } - @Override - public TextureRegion[] getIcon(){ - return new TextureRegion[]{Core.atlas.find(name)}; - } - @Override public void update(Tile tile){ GenericCrafterEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java b/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java index 31eb976ff3..2881afc5a6 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java @@ -27,11 +27,8 @@ public class PhaseWeaver extends PowerSmelter{ } @Override - public TextureRegion[] getIcon(){ - if(icon == null){ - icon = new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)}; - } - return icon; + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)}; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java index 4f3889eca5..787b705453 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java @@ -60,6 +60,17 @@ public class PowerCrafter extends Block{ } } + @Override + public boolean canProduce(Tile tile){ + if(outputItem != null && tile.entity.items.get(outputItem) >= itemCapacity){ + return false; + } + if(outputLiquid != null && tile.entity.liquids.get(outputLiquid) >= liquidCapacity - 0.01f){ + return false; + } + return true; + } + @Override public void update(Tile tile){ GenericCrafterEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Pulverizer.java b/core/src/io/anuke/mindustry/world/blocks/production/Pulverizer.java index 8ec2e1409e..d15d024647 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Pulverizer.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Pulverizer.java @@ -29,7 +29,7 @@ public class Pulverizer extends GenericCrafter{ } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator")}; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Pump.java b/core/src/io/anuke/mindustry/world/blocks/production/Pump.java index 21b5c830c9..75c168cc74 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Pump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Pump.java @@ -47,7 +47,7 @@ public class Pump extends LiquidBlock{ @Override public void draw(Tile tile){ - Draw.rect(name(), tile.drawx(), tile.drawy()); + Draw.rect(name, tile.drawx(), tile.drawy()); Draw.color(tile.entity.liquids.current().color); Draw.alpha(tile.entity.liquids.total() / liquidCapacity); @@ -56,7 +56,7 @@ public class Pump extends LiquidBlock{ } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name)}; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java index 434a5011e3..89d0635583 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java @@ -56,7 +56,7 @@ public class SolidPump extends Pump{ } @Override - public TextureRegion[] getIcon(){ + public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")}; } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index d91b70b777..a62b7e30f3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -14,36 +14,29 @@ import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.Unit; -import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.traits.SpawnerTrait; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.ItemType; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockFlag; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - import static io.anuke.mindustry.Vars.*; -public class CoreBlock extends StorageBlock{ - protected TextureRegion openRegion; +public class CoreBlock extends LaunchPad{ protected TextureRegion topRegion; + protected int launchThreshold; + protected int launchChunkSize; public CoreBlock(String name){ super(name); - solid = false; - solidifes = true; + solid = true; update = true; - size = 3; hasItems = true; - viewRange = 200f; + size = 3; flags = EnumSet.of(BlockFlag.resupplyPoint, BlockFlag.target); } @@ -53,11 +46,12 @@ public class CoreBlock extends StorageBlock{ CoreEntity entity = tile.entity(); Effects.effect(Fx.spawn, entity); - entity.solid = false; entity.progress = 0; + entity.currentUnit.onRespawn(tile); entity.currentUnit = player; entity.currentUnit.heal(); entity.currentUnit.rotation = 90f; + entity.currentUnit.applyImpulse(0, 8f); entity.currentUnit.setNet(tile.drawx(), tile.drawy()); entity.currentUnit.add(); entity.currentUnit = null; @@ -67,18 +61,6 @@ public class CoreBlock extends StorageBlock{ } } - @Remote(called = Loc.server) - public static void setCoreSolid(Tile tile, boolean solid){ - if(tile == null) return; - CoreEntity entity = tile.entity(); - if(entity != null) entity.solid = solid; - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - return item.type == ItemType.material && super.acceptItem(item, tile, source); - } - @Override public int getMaximumAccepted(Tile tile, Item item){ return itemCapacity * state.teams.get(tile.getTeam()).cores.size; @@ -118,7 +100,6 @@ public class CoreBlock extends StorageBlock{ public void load(){ super.load(); - openRegion = Core.atlas.find(name + "-open"); topRegion = Core.atlas.find(name + "-top"); } @@ -126,7 +107,7 @@ public class CoreBlock extends StorageBlock{ public void draw(Tile tile){ CoreEntity entity = tile.entity(); - Draw.rect(entity.solid ? region : openRegion, tile.drawx(), tile.drawy()); + Draw.rect(region, tile.drawx(), tile.drawy()); Draw.alpha(entity.heat); Draw.rect(topRegion, tile.drawx(), tile.drawy()); @@ -158,13 +139,6 @@ public class CoreBlock extends StorageBlock{ } } - @Override - public boolean isSolidFor(Tile tile){ - CoreEntity entity = tile.entity(); - - return entity.solid; - } - @Override public void handleItem(Item item, Tile tile, Tile source){ if(Net.server() || !Net.active()) super.handleItem(item, tile, source); @@ -174,8 +148,13 @@ public class CoreBlock extends StorageBlock{ public void update(Tile tile){ CoreEntity entity = tile.entity(); - if(!entity.solid && !Units.anyEntities(tile)){ - Call.setCoreSolid(tile, true); + for(Item item : Vars.content.items()){ + if(entity.items.get(item) >= launchThreshold + launchChunkSize && entity.timer.get(timerLaunch, launchTime)){ + //TODO play animation of some sort + Effects.effect(Fx.dooropenlarge, tile); + data.addItem(item, launchChunkSize); + entity.items.remove(item, launchChunkSize); + } } if(entity.currentUnit != null){ @@ -200,7 +179,6 @@ public class CoreBlock extends StorageBlock{ public class CoreEntity extends TileEntity implements SpawnerTrait{ public Unit currentUnit; - boolean solid = true; float progress; float time; float heat; @@ -218,15 +196,5 @@ public class CoreBlock extends StorageBlock{ public float getSpawnProgress(){ return progress; } - - @Override - public void write(DataOutput stream) throws IOException{ - stream.writeBoolean(solid); - } - - @Override - public void read(DataInput stream) throws IOException{ - solid = stream.readBoolean(); - } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java b/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java index 65e67d7b94..5647974149 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java @@ -6,12 +6,11 @@ import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemType; -import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.data; -public class LaunchPad extends Block{ +public class LaunchPad extends StorageBlock{ protected final int timerLaunch = timers++; /**Time inbetween launches.*/ protected float launchTime; @@ -19,14 +18,13 @@ public class LaunchPad extends Block{ public LaunchPad(String name){ super(name); update = true; - hasPower = true; hasItems = true; solid = true; } @Override public boolean acceptItem(Item item, Tile tile, Tile source){ - return item.type == ItemType.material && tile.entity.items.get(item) < getMaximumAccepted(tile, item); + return item.type == ItemType.material && super.acceptItem(item, tile, source); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java index 8d1bc3713f..e8d6a7f1e3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java @@ -94,11 +94,8 @@ public class UnitFactory extends Block{ } @Override - public TextureRegion[] getIcon(){ - return new TextureRegion[]{ - Core.atlas.find(name), - Core.atlas.find(name + "-top") - }; + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")}; } @Override @@ -106,7 +103,7 @@ public class UnitFactory extends Block{ UnitFactoryEntity entity = tile.entity(); TextureRegion region = type.iconRegion; - Draw.rect(name(), tile.drawx(), tile.drawy()); + Draw.rect(name, tile.drawx(), tile.drawy()); Shaders.build.region = region; Shaders.build.progress = entity.buildTime / produceTime; diff --git a/core/src/io/anuke/mindustry/world/meta/BlockStats.java b/core/src/io/anuke/mindustry/world/meta/BlockStats.java index e89bfcf837..9dcd09db5e 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockStats.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockStats.java @@ -7,7 +7,6 @@ import io.anuke.arc.util.Log; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Liquid; -import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.values.*; import java.util.Locale; @@ -17,13 +16,8 @@ public class BlockStats{ private static final boolean errorWhenMissing = false; private final OrderedMap> map = new OrderedMap<>(); - private final Block block; private boolean dirty; - public BlockStats(Block block){ - this.block = block; - } - /**Adds a single float value with this stat, formatted to 2 decimal places.*/ public void add(BlockStat stat, float value, StatUnit unit){ add(stat, new NumberValue(value, unit)); @@ -73,7 +67,7 @@ public class BlockStats{ } if(map.containsKey(stat.category) && map.get(stat.category).containsKey(stat)){ - throw new RuntimeException("Duplicate stat entry: \"" + stat + "\" in block '" + block.name + "'"); + throw new RuntimeException("Duplicate stat entry: \"" + stat + "\" in block."); } if(!map.containsKey(stat.category)){ @@ -88,7 +82,7 @@ public class BlockStats{ /**Removes a stat, if it exists.*/ public void remove(BlockStat stat){ if(!map.containsKey(stat.category) || !map.get(stat.category).containsKey(stat)){ - throw new RuntimeException("No stat entry found: \"" + stat + "\" in block '" + block.name + "'!"); + throw new RuntimeException("No stat entry found: \"" + stat + "\" in block."); } map.get(stat.category).remove(stat); diff --git a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java index 40d06f6853..68f8585b55 100644 --- a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java +++ b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java @@ -9,9 +9,11 @@ import java.io.IOException; public class ConsumeModule extends BlockModule{ private boolean valid; + private TileEntity entity; public void update(TileEntity entity){ - boolean prevValid = valid; + this.entity = entity; + boolean prevValid = valid(); valid = true; for(Consume cons : entity.tile.block().consumes.all()){ @@ -26,7 +28,7 @@ public class ConsumeModule extends BlockModule{ } public boolean valid(){ - return valid; + return valid && (entity == null || entity.tile.block().canProduce(entity.tile)); } @Override diff --git a/gradle.properties b/gradle.properties index d8e2a1210f..e08bde78fc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,4 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms512m -Xmx1536m -android.enableAapt2=true android.injected.build.model.only.versioned=3 -android.enableD8=true +android.enableD8=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 29953ea141..457aad0d98 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e0b3fb8d70..290541c738 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d517..af6708ff22 100755 --- a/gradlew +++ b/gradlew @@ -28,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index e95643d6a2..0f8d5937c4 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index a0acd29484..8717c54f44 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -26,10 +26,8 @@ import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Packets.KickReason; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemType; -import io.anuke.mindustry.world.Tile; import java.io.IOException; -import java.lang.StringBuilder; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Scanner; @@ -565,33 +563,6 @@ public class ServerControl implements ApplicationListener{ Events.fire(new GameOverEvent(Team.red)); }); - handler.register("traceblock", " ", "Prints debug info about a block", arg -> { - try{ - int x = Integer.parseInt(arg[0]); - int y = Integer.parseInt(arg[1]); - Tile tile = world.tile(x, y); - if(tile != null){ - if(tile.entity != null){ - Array arr = tile.block().getDebugInfo(tile); - StringBuilder result = new StringBuilder(); - for(int i = 0; i < arr.size / 2; i++){ - result.append(arr.get(i * 2)); - result.append(": "); - result.append(arr.get(i * 2 + 1)); - result.append("\n"); - } - info("&ly{0}", result); - }else{ - info("No tile entity for that block."); - } - }else{ - info("No tile at that location."); - } - }catch(NumberFormatException e){ - err("Invalid coordinates passed."); - } - }); - handler.register("info", "", "Find player info(s). Can optionally check for all names or IPs a player has had.", arg -> { ObjectSet infos = netServer.admins.findByName(arg[0]); diff --git a/tests/src/test/java/ApplicationTests.java b/tests/src/test/java/ApplicationTests.java index 8dc44fecc8..0c90191680 100644 --- a/tests/src/test/java/ApplicationTests.java +++ b/tests/src/test/java/ApplicationTests.java @@ -22,7 +22,6 @@ import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Edges; import io.anuke.mindustry.world.Tile; @@ -34,6 +33,7 @@ import static io.anuke.mindustry.Vars.*; import static org.junit.jupiter.api.Assertions.*; public class ApplicationTests{ + static Map testMap; @BeforeAll static void launchApplication(){ @@ -51,17 +51,19 @@ public class ApplicationTests{ BundleLoader.load(); content.load(); - content.initialize(Content::init); add(logic = new Logic()); add(world = new World()); add(netServer = new NetServer()); + + content.initialize(Content::init); } @Override public void init(){ super.init(); begins[0] = true; + testMap = world.maps.loadInternalMap("groundZero"); } }; @@ -105,12 +107,12 @@ public class ApplicationTests{ void playMap(){ assertTrue(world.maps.all().size > 0); - world.loadMap(world.maps.all().first()); + world.loadMap(testMap); } @Test void spawnWaves(){ - world.loadMap(world.maps.all().first()); + world.loadMap(testMap); logic.runWave(); unitGroups[waveTeam.ordinal()].updateEvents(); assertFalse(unitGroups[waveTeam.ordinal()].isEmpty()); @@ -143,7 +145,7 @@ public class ApplicationTests{ if(x == bx && by == y){ assertEquals(world.tile(x, y).block(), Blocks.core); }else{ - assertTrue(world.tile(x, y).block() == Blocks.blockpart && world.tile(x, y).getLinked() == world.tile(bx, by)); + assertTrue(world.tile(x, y).block() == Blocks.part && world.tile(x, y).getLinked() == world.tile(bx, by)); } } } @@ -176,7 +178,7 @@ public class ApplicationTests{ void save(){ assertTrue(world.maps.all().size > 0); - world.loadMap(world.maps.all().first()); + world.loadMap(testMap); SaveIO.saveToSlot(0); } @@ -184,14 +186,14 @@ public class ApplicationTests{ void load(){ assertTrue(world.maps.all().size > 0); - world.loadMap(world.maps.all().first()); + world.loadMap(testMap); Map map = world.getMap(); SaveIO.saveToSlot(0); resetWorld(); SaveIO.loadFromSlot(0); - assertEquals(world.getMap(), map); + assertEquals(world.getMap().name, map.name); assertEquals(world.width(), map.meta.width); assertEquals(world.height(), map.meta.height); } @@ -225,8 +227,8 @@ public class ApplicationTests{ d1.set(10f, 20f); d2.set(10f, 20f); - d1.addBuildRequest(new BuildRequest(0, 0, 0, Recipe.getByResult(Blocks.copperWallLarge))); - d2.addBuildRequest(new BuildRequest(1, 1, 0, Recipe.getByResult(Blocks.copperWallLarge))); + d1.addBuildRequest(new BuildRequest(0, 0, 0, Blocks.copperWallLarge)); + d2.addBuildRequest(new BuildRequest(1, 1, 0, Blocks.copperWallLarge)); Time.setDeltaProvider(() -> 9999999f); d1.updateBuilding(d1); @@ -234,7 +236,7 @@ public class ApplicationTests{ assertEquals(Blocks.copperWallLarge, world.tile(0, 0).block()); assertEquals(Blocks.air, world.tile(2, 2).block()); - assertEquals(Blocks.blockpart, world.tile(1, 1).block()); + assertEquals(Blocks.part, world.tile(1, 1).block()); } @Test @@ -247,7 +249,7 @@ public class ApplicationTests{ d1.set(10f, 20f); d2.set(10f, 20f); - d1.addBuildRequest(new BuildRequest(0, 0, 0, Recipe.getByResult(Blocks.copperWallLarge))); + d1.addBuildRequest(new BuildRequest(0, 0, 0, Blocks.copperWallLarge)); d2.addBuildRequest(new BuildRequest(1, 1)); Time.setDeltaProvider(() -> 3f); diff --git a/tools/build.gradle b/tools/build.gradle index beca6be546..e0a9db056c 100644 --- a/tools/build.gradle +++ b/tools/build.gradle @@ -11,6 +11,63 @@ import java.awt.image.BufferedImage def outFolder = "../core/assets-raw/sprites_out/" def genFolder = "../core/assets-raw/sprites_out/generated/" +def antialias = {File file -> + def image = ImageIO.read(file) + def out = ImageIO.read(file) + def getRGB = { int ix, int iy -> + return image.getRGB(Math.max(Math.min(ix, image.width - 1), 0), Math.max(Math.min(iy, image.height - 1), 0)) + } + + def color = new Color() + def sum = new Color() + + for (int x = 0; x < image.getWidth(); x++){ + for(int y = 0; y < image.getHeight(); y++){ + int A = + getRGB(x - 1, y + 1), + B = getRGB(x, y + 1), + C = getRGB(x + 1, y + 1), + D = getRGB(x - 1, y), + E = getRGB(x, y), + F = getRGB(x + 1, y), + G = getRGB(x - 1, y - 1), + H = getRGB(x, y - 1), + I = getRGB(x + 1, y - 1) + + int p1=E, p2=E, p3=E, p4=E, p5=E, p6=E, p7=E, p8=E, p9=E + if (D==B && D!=H && B!=F) p1=D + if ((D==B && D!=H && B!=F && E!=C) || (B==F && B!=D && F!=H && E!=A)) p2=B + if (B==F && B!=D && F!=H) p3=F + if ((H==D && H!=F && D!=B && E!=A) || (D==B && D!=H && B!=F && E!=G)) p4=D + p5=E + if ((B==F && B!=D && F!=H && E!=I) || (F==H && F!=B && H!=D && E!=C)) p6=F + if (H==D && H!=F && D!=B) p7=D + if ((F==H && F!=B && H!=D && E!=G) || (H==D && H!=F && D!=B && E!=I)) p8=H + if (F==H && F!=B && H!=D) p9=F + + int total = 0 + + [p1, p2, p3, p4, p5, p6, p7, p8, p9].each{ val -> + Color.argb8888ToColor(color, val) + + if(color.a > 0.1){ + sum.r += color.r + sum.g += color.g + sum.b += color.b + sum.a += color.a + total++ + } + } + + sum.mul((float)(1f / total)) + int result = Color.argb8888(sum) + out.setRGB(x, y, result) + sum.set(0) + } + } + + ImageIO.write(out, "png", file) +} task swapColors(){ doLast{ @@ -48,7 +105,7 @@ task swapColors(){ task scaleSprites4x(){ doLast{ fileTree(dir: '../core/assets-raw/sprites_out/', include: "**/*.png").visit { file -> - if(file.isDirectory() || file.toString().contains("/ui/")) return; + if(file.isDirectory() || file.toString().contains("/ui/")) return for(int iteration in 0..1) { def image = ImageIO.read(file.file) @@ -91,6 +148,8 @@ task scaleSprites4x(){ ImageIO.write(scaled, "png", file.file) } + + antialias(file.file) } } } @@ -98,18 +157,27 @@ task scaleSprites4x(){ task scaleSprites(){ finalizedBy 'genSprites' + + doLast{ + copy{ + from "../core/assets-raw/sprites_replacement/" + into "../core/assets-raw/sprites_out/" + } + } + dependsOn 'scaleSprites4x' } task pack(){ dependsOn 'cleanSprites', 'scaleSprites' - finalizedBy 'cleanup' + //finalizedBy 'cleanup' doLast{ - copy{ - from "../core/assets-raw/sprites_replacement/" - into "../core/assets-raw/sprites_out/" + fileTree(dir: '../core/assets-raw/sprites_out/', include: "**/*.png").visit{ file -> + if(file.isDirectory() || file.toString().contains("/ui/")) return + + antialias(file.file) } TexturePacker.process("core/assets-raw/sprites_out/", "core/assets/sprites/", "sprites.atlas") @@ -127,6 +195,7 @@ task cleanup(){ } task cleanSprites(){ + doLast{ delete{ delete "../core/assets-raw/sprites_out/" @@ -141,7 +210,17 @@ task cleanSprites(){ } } +task antialiasGen(){ + doLast{ + fileTree(dir: '../core/assets-raw/sprites_out/generated/', include: "**/*.png").visit{ file -> + antialias(file.file) + } + } +} + task genSprites(dependsOn: classes, type: JavaExec) { + finalizedBy 'antialiasGen' + main = "io.anuke.mindustry.ImagePacker" classpath = sourceSets.main.runtimeClasspath standardInput = System.in diff --git a/tools/src/io/anuke/mindustry/Generators.java b/tools/src/io/anuke/mindustry/Generators.java index d6e4f16e02..cac0ece66d 100644 --- a/tools/src/io/anuke/mindustry/Generators.java +++ b/tools/src/io/anuke/mindustry/Generators.java @@ -1,14 +1,14 @@ package io.anuke.mindustry; -import io.anuke.arc.Core; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.TextureRegion; +import io.anuke.arc.util.Log; import io.anuke.mindustry.entities.units.UnitType; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Mech; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.blocks.Floor; +import io.anuke.mindustry.world.Block.Icon; import io.anuke.mindustry.world.blocks.OreBlock; import static io.anuke.mindustry.Vars.content; @@ -20,33 +20,31 @@ public class Generators { ImagePacker.generate("block-icons", () -> { for(Block block : content.blocks()){ - TextureRegion[] regions = block.getBlockIcon(); + TextureRegion[] regions = block.getGeneratedIcons(); if(regions.length == 0){ continue; } - if(block.turretIcon){ - - Image image = ImagePacker.get(block.name); - - Image read = ImagePacker.create(image.width(), image.height()); - read.draw(image); - - Image base = ImagePacker.get("block-" + block.size); - - base.draw(image); - - base.save("block-icon-" + block.name); - }else { - + try{ Image image = ImagePacker.get(regions[0]); - for (TextureRegion region : regions) { + for(TextureRegion region : regions){ image.draw(region); } - image.save("block-icon-" + block.name); + image.save(block.name + "-icon-full"); + + for(Icon icon : Icon.values()){ + if(icon.size == 0) continue; + Image scaled = new Image(icon.size, icon.size); + scaled.drawScaled(image); + scaled.save(block.name + "-icon-" + icon.name()); + } + }catch(IllegalArgumentException e){ + Log.info("Skipping &ly'{0}'", block.name); + }catch(NullPointerException e){ + Log.err("Block &ly'{0}'&lr has an null region!"); } } }); @@ -104,39 +102,12 @@ public class Generators { } }); - ImagePacker.generate("block-edges", () -> { - for(Block block : content.blocks()){ - if(!(block instanceof Floor)) continue; - Floor floor = (Floor)block; - if(floor.getIcon().length > 0 && !Core.atlas.has(floor.name + "-cliff-side")){ - Image floori = ImagePacker.get(floor.getIcon()[0]); - Color color = floori.getColor(0, 0).mul(1.3f, 1.3f, 1.3f, 1f); - - String[] names = {"cliff-edge-2", "cliff-edge", "cliff-edge-1", "cliff-side"}; - for(String str : names){ - Image image = ImagePacker.get("generic-" + str); - - for(int x = 0; x < image.width(); x++){ - for(int y = 0; y < image.height(); y++){ - Color other = image.getColor(x, y); - if(other.a > 0){ - image.draw(x, y, color); - } - } - } - - image.save(floor.name + "-" + str); - } - } - } - }); - ImagePacker.generate("ore-icons", () -> { for(Block block : content.blocks()){ if(!(block instanceof OreBlock)) continue; OreBlock ore = (OreBlock)block; - Item item = ore.drops.item; + Item item = ore.itemDrop; Block base = ore.base; for (int i = 0; i < 3; i++) { @@ -160,8 +131,16 @@ public class Generators { image.draw(ImagePacker.get(item.name + (i+1))); image.save("ore-" + item.name + "-" + base.name + (i+1)); - } + //save icons + image.save(block.name + "-icon-full"); + for(Icon icon : Icon.values()){ + if(icon.size == 0) continue; + Image scaled = new Image(icon.size, icon.size); + scaled.drawScaled(image); + scaled.save(block.name + "-icon-" + icon.name()); + } + } } }); } diff --git a/tools/src/io/anuke/mindustry/Image.java b/tools/src/io/anuke/mindustry/Image.java index 03a67539cf..e97babec9b 100644 --- a/tools/src/io/anuke/mindustry/Image.java +++ b/tools/src/io/anuke/mindustry/Image.java @@ -77,6 +77,10 @@ class Image { draw(region, (width() - region.getWidth())/2, (height() - region.getHeight())/2, flipx, flipy); } + void drawScaled(Image image){ + graphics.drawImage(image.image.getScaledInstance(width(), height(), java.awt.Image.SCALE_AREA_AVERAGING), 0, 0, width(), height(), null); + } + /**Draws an image at the top left corner.*/ void draw(Image image){ draw(image, 0, 0); diff --git a/tools/src/io/anuke/mindustry/ImagePacker.java b/tools/src/io/anuke/mindustry/ImagePacker.java index 250304dc7c..2b696bbea5 100644 --- a/tools/src/io/anuke/mindustry/ImagePacker.java +++ b/tools/src/io/anuke/mindustry/ImagePacker.java @@ -8,6 +8,7 @@ import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.util.Log; import io.anuke.arc.util.Log.LogHandler; import io.anuke.arc.util.Log.NoopLogHandler; +import io.anuke.arc.util.Strings; import io.anuke.arc.util.Time; import io.anuke.mindustry.core.ContentLoader; @@ -117,8 +118,7 @@ public class ImagePacker{ } static void err(String message, Object... args){ - Log.err(message, args); - System.exit(-1); + throw new IllegalArgumentException(Strings.formatArgs(message, args)); } static class GenRegion extends AtlasRegion{