diff --git a/build.gradle b/build.gradle index 82b5254689..1b90d98ad0 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ allprojects { appName = "Mindustry" gdxVersion = '1.9.8' aiVersion = '1.8.1' - uCoreVersion = '5e4e43ed39'; + uCoreVersion = '713d187'; } repositories { diff --git a/core/assets-raw/sprites/blocks/weaponfactory-icon.png b/core/assets-raw/sprites/blocks/weaponfactory-icon.png new file mode 100644 index 0000000000..27065c56af Binary files /dev/null and b/core/assets-raw/sprites/blocks/weaponfactory-icon.png differ diff --git a/core/assets-raw/sprites/blocks/weaponfactory.png b/core/assets-raw/sprites/blocks/weaponfactory.png new file mode 100644 index 0000000000..0938f64971 Binary files /dev/null and b/core/assets-raw/sprites/blocks/weaponfactory.png differ diff --git a/core/assets-raw/sprites/weapons/beam.png b/core/assets-raw/sprites/weapons/beam.png new file mode 100644 index 0000000000..e7bf82c60f Binary files /dev/null and b/core/assets-raw/sprites/weapons/beam.png differ diff --git a/core/assets-raw/sprites/weapons/clustergun.png b/core/assets-raw/sprites/weapons/clustergun.png new file mode 100644 index 0000000000..1f76fcf8be Binary files /dev/null and b/core/assets-raw/sprites/weapons/clustergun.png differ diff --git a/core/assets-raw/sprites/weapons/flamer.png b/core/assets-raw/sprites/weapons/flamer.png deleted file mode 100644 index 0686fee7e1..0000000000 Binary files a/core/assets-raw/sprites/weapons/flamer.png and /dev/null differ diff --git a/core/assets-raw/sprites/weapons/multigun.png b/core/assets-raw/sprites/weapons/multigun.png deleted file mode 100644 index f7ac8b5a21..0000000000 Binary files a/core/assets-raw/sprites/weapons/multigun.png and /dev/null differ diff --git a/core/assets-raw/sprites/weapons/railgun.png b/core/assets-raw/sprites/weapons/railgun.png deleted file mode 100644 index 98f694eb92..0000000000 Binary files a/core/assets-raw/sprites/weapons/railgun.png and /dev/null differ diff --git a/core/assets-raw/sprites/weapons/mortar.png b/core/assets-raw/sprites/weapons/shockgun.png similarity index 100% rename from core/assets-raw/sprites/weapons/mortar.png rename to core/assets-raw/sprites/weapons/shockgun.png diff --git a/core/assets-raw/sprites/weapons/triblaster.png b/core/assets-raw/sprites/weapons/triblaster.png index a7702e702c..1b6e1db871 100644 Binary files a/core/assets-raw/sprites/weapons/triblaster.png and b/core/assets-raw/sprites/weapons/triblaster.png differ diff --git a/core/assets-raw/sprites/weapons/vulcan.png b/core/assets-raw/sprites/weapons/vulcan.png new file mode 100644 index 0000000000..a4632649f9 Binary files /dev/null and b/core/assets-raw/sprites/weapons/vulcan.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 9d8444d0c4..fe2a9272cf 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -122,7 +122,7 @@ text.settings.game=Game text.settings.sound=Sound text.settings.graphics=Graphics text.upgrades=Upgrades -text.purchased=[LIME]Purchased! +text.purchased=[LIME]Created! text.weapons=Weapons text.paused=Paused text.respawn=Respawning in @@ -166,6 +166,11 @@ text.blocks.health=Health text.blocks.inaccuracy=Health text.blocks.shots=Shots text.blocks.shotssecond=Shots/second +text.blocks.fuel=Fuel +text.blocks.fuelduration=Fuel Duration +text.blocks.maxoutputsecond=Max output/second +text.blocks.inputcapacity=Input capacity +text.blocks.outputcapacity=Output capacity text.placemode=Place Mode text.breakmode=Break Mode text.health=health @@ -266,18 +271,20 @@ keybind.weapon_6.name=weapon_6 mode.waves.name=waves mode.sandbox.name=sandbox mode.freebuild.name=freebuild -weapon.blaster.name=blaster -weapon.blaster.description=Shoots a slow, weak bullet. -weapon.triblaster.name=triblaster -weapon.triblaster.description=Shoots 3 bullets in a spread. -weapon.multigun.name=multigun -weapon.multigun.description=Shoots inaccurate bullets with a high\nrate of fire. -weapon.flamer.name=flamer -weapon.flamer.description=Shoots a stream of fire. -weapon.railgun.name=railgun -weapon.railgun.description=Shoots one long-range bullet. -weapon.mortar.name=mortar -weapon.mortar.description=Shoots a slow, but damaging shell. +upgrade.standard.name=standard +upgrade.standard.description=The standard mech. +upgrade.blaster.name=blaster +upgrade.blaster.description=Shoots a slow, weak bullet. +upgrade.triblaster.name=triblaster +upgrade.triblaster.description=Shoots 3 bullets in a spread. +upgrade.clustergun.name=clustergun +upgrade.clustergun.description=Shoots an inaccurate spread of explosive grenades. +upgrade.beam.name=beam cannon +upgrade.beam.description=Shoots a long-range piercing laser beam. +upgrade.vulcan.name=vulcan +upgrade.vulcan.description=Shoots a barrage of fast bullets. +upgrade.shockgun.name=shockgun +upgrade.shockgun.description=Shoots a devastating blast of charged shrapnel. item.stone.name=stone item.iron.name=iron item.coal.name=coal @@ -289,6 +296,7 @@ liquid.water.name=water liquid.plasma.name=plasma liquid.lava.name=lava liquid.oil.name=oil +block.weaponfactory.name=weapon factory block.air.name=air block.blockpart.name=blockpart block.deepwater.name=deepwater @@ -338,25 +346,20 @@ block.titaniumshieldwall.name=shielded wall block.titaniumshieldwall.fulldescription=A strong defensive block, with an extra built-in shield. Requires power. Uses energy to absorb enemy bullets. It is recommended to use power boosters to provide energy to this block. block.repairturret.name=repair turret block.repairturret.fulldescription=Repairs nearby damaged blocks in range at a slow rate. Uses small amounts of power. -block.repairturret.description=[powerinfo]Uses power[white]\nRepairs nearby blocks. block.megarepairturret.name=repair turret II block.megarepairturret.fulldescription=Repairs nearby damaged blocks in range at a decent rate. Uses power. -block.megarepairturret.description=[powerinfo]Uses power[white]\nRepairs nearby blocks. block.shieldgenerator.name=shield generator block.shieldgenerator.fulldescription=An advanced defensive block. Shields all the blocks in a radius from attack. Uses power at a slow rate when idle, but drains energy quickly on bullet contact. block.door.name=door block.door.fulldescription=A block than can be opened and closed by tapping it. -block.door.description=Opens and closes.\n[interact]Tap to toggle block.door-large.name=large door block.door-large.fulldescription=A block than can be opened and closed by tapping it. -block.door-large.description=Opens and closes.\n[interact]Tap to toggle block.conduit.name=conduit block.conduit.fulldescription=Basic liquid transport block. Works like a conveyor, but with liquids. Best used with pumps or other conduits. Can be used as a bridge over liquids for enemies and players. block.pulseconduit.name=pulse conduit block.pulseconduit.fulldescription=Advanced liquid transport block. Transports liquids faster and stores more than standard conduits. block.liquidrouter.name=liquid router block.liquidrouter.fulldescription=Works similarly to a router. Accepts liquid input from one side and outputs it to the other sides. Useful for splitting liquid from a single conduit into multiple other conduits. -block.liquidrouter.description=Splits input liquid into 3 directions. block.conveyor.name=conveyor block.conveyor.fulldescription=Basic item transport block. Moves items forward and automatically deposits them into turrets or crafters. Rotatable. Can be used as a bridge over liquids for enemies and players. block.steelconveyor.name=steel conveyor @@ -365,131 +368,90 @@ block.poweredconveyor.name=pulse conveyor block.poweredconveyor.fulldescription=The ultimate item transport block. Moves items faster than steel conveyors. block.router.name=router block.router.fulldescription=Accepts items from one direction and outputs them to 3 other directions. Can also store a certain amount of items.Useful for splitting the materials from one drill into multiple turrets. -block.router.description=Split input materials into 3 directions. block.junction.name=junction block.junction.fulldescription=Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations. -block.junction.description=Serves as a conveyor junction. block.conveyortunnel.name=conveyor tunnel block.conveyortunnel.fulldescription=Transports item under blocks. To use, place one tunnel leading into the block to be tunneled under, and one on the other side. Make sure both tunnels face opposite directions, which is towards the blocks they are inputting or outputting to. -block.conveyortunnel.description=Transports items under blocks. block.liquidjunction.name=liquid junction block.liquidjunction.fulldescription=Acts as a bridge for two crossing conduits. Useful in situations with two different conduits carrying different liquids to different locations. block.liquiditemjunction.name=liquid-item junction block.liquiditemjunction.fulldescription=Acts as a bridge for crossing conduits and conveyors. -block.liquiditemjunction.description=Serves as a junction for items and liquids. block.powerbooster.name=power booster block.powerbooster.fulldescription=Distributes power to all blocks within its radius. -block.powerbooster.description=Distributes power within a radius. block.powerlaser.name=power laser block.powerlaser.fulldescription=Creates a laser that transmits power to the block in front of it. Does not generate any power itself. Best used with generators or other lasers. -block.powerlaser.description=Transmits power. block.powerlaserrouter.name=laser router block.powerlaserrouter.fulldescription=Laser that distributes power to three directions at once. Useful in situations where it is required to power multiple blocks from one generator. -block.powerlaserrouter.description=Splits input power into 3 lasers. block.powerlasercorner.name=laser corner block.powerlasercorner.fulldescription=Laser that distributes power to two directions at once. Useful in situations where it is required to power multiple blocks from one generator, and a router is imprecise. -block.powerlasercorner.description=Splits input power into 2 lasers. block.teleporter.name=teleporter block.teleporter.fulldescription=Advanced item transport block. Teleporters input items to other teleporters of the same color. Does nothing if no teleporters of the same color exist. If multiple teleporters exist of the same color, a random one is selected. Tap and click the arrows to change color. -block.teleporter.description=[interact]Tap block to config[] block.sorter.name=sorter block.sorter.fulldescription=Sorts item by material type. Material to accept is indicated by the color in the block. All items that match the sort material are outputted forward, everything else is outputted to the left and right. -block.sorter.description=[interact]Tap block to config[] block.core.name=core block.pump.name=pump block.pump.fulldescription=Pumps liquids from a source block- usually water, lava or oil. Outputs liquid into nearby conduits. -block.pump.description=Pumps liquids into nearby conduits. block.fluxpump.name=fluxpump block.fluxpump.fulldescription=An advanced version of the pump. Stores more liquid and pumps liquid faster. -block.fluxpump.description=Pumps liquids into nearby conduits. block.smelter.name=smelter block.smelter.fulldescription=The essential crafting block. When inputted 1x iron and 1x coal, outputs one steel. -block.smelter.description=Converts coal + iron to steel. block.crucible.name=crucible block.crucible.fulldescription=An advanced crafting block. When inputted 1x titanium and 1x steel, outputs one dirium. -block.crucible.description=Converts steel + titanium to dirium. block.coalpurifier.name=coal extractor block.coalpurifier.fulldescription=A basic extractor block. Outputs coal when supplied with large amounts of water and stone. -block.coalpurifier.description=Converts stone + water to coal. block.titaniumpurifier.name=titanium extractor block.titaniumpurifier.fulldescription=A standard extractor block. Outputs titanium when supplied with large amounts of water and iron. -block.titaniumpurifier.description=Converts iron + water to titanium. block.oilrefinery.name=oil refinery block.oilrefinery.fulldescription=Refines large amounts of oil into coal items. Useful for fueling coal-based turrets when coal veins are scarce. -block.oilrefinery.description=Converts oil to coal. block.stoneformer.name=stone former block.stoneformer.fulldescription=Soldifies liquid lava into stone. Useful for producing massive amounts of stone for coal purifiers. -block.stoneformer.description=Converts lava to stone. block.lavasmelter.name=lava smelter block.lavasmelter.fulldescription=Uses lava to convert iron to steel. An alternative to smelteries. Useful in situations where coal is scarce. -block.lavasmelter.description=Converts iron + lava to steel. block.stonedrill.name=stone drill block.stonedrill.fulldescription=The essential drill. When placed on stone tiles, outputs stone at a slow pace indefinitely. -block.stonedrill.description=Mines 1 stone every 4 seconds. block.irondrill.name=iron drill block.irondrill.fulldescription=A basic drill. When placed on iron ore tiles, outputs iron at a slow pace indefinitely. -block.irondrill.description=Mines 1 iron every 5 seconds. block.coaldrill.name=coal drill block.coaldrill.fulldescription=A basic drill. When placed on coal ore tiles, outputs coal at a slow pace indefinitely. -block.coaldrill.description=Mines 1 coal every 5 seconds. block.uraniumdrill.name=uranium drill block.uraniumdrill.fulldescription=An advanced drill. When placed on uranium ore tiles, outputs uranium at a slow pace indefinitely. -block.uraniumdrill.description=Mines 1 uranium every 7 seconds. block.titaniumdrill.name=titanium drill block.titaniumdrill.fulldescription=An advanced drill. When placed on titanium ore tiles, outputs titanium at a slow pace indefinitely. -block.titaniumdrill.description=Mines 1 titanium every 5 seconds. block.omnidrill.name=omnidrill block.omnidrill.fulldescription=The ultimate drill. Will mine any ore it is placed on at a rapid pace. -block.omnidrill.description=Mines 1 of any resource every 3 seconds. block.coalgenerator.name=coal generator block.coalgenerator.fulldescription=The essential generator. Generates power from coal. Outputs power as lasers to its 4 sides. -block.coalgenerator.description=Generates power from coal. block.thermalgenerator.name=thermal generator block.thermalgenerator.fulldescription=Generates power from lava. Outputs power as lasers to its 4 sides. -block.thermalgenerator.description=Generates power from lava. block.combustiongenerator.name=combustion generator block.combustiongenerator.fulldescription=Generates power from oil. Outputs power as lasers to its 4 sides. -block.combustiongenerator.description=Generates power from oil. block.rtgenerator.name=RTG generator block.rtgenerator.fulldescription=Generates small amounts of power from the radioactive decay of uranium. Outputs power as lasers to its 4 sides. -block.rtgenerator.description=Generates power from uranium. block.nuclearreactor.name=nuclear reactor block.nuclearreactor.fulldescription=An advanced version of the RTG Generator, and the ultimate power generator. Generates power from uranium. Requires constant water cooling. Highly volatile; will explode violently if insufficient amounts of coolant are supplied. block.turret.name=turret block.turret.fulldescription=A basic, cheap turret. Uses stone for ammo. Has slightly more range than the double-turret. -block.turret.description=[turretinfo]Ammo: stone block.doubleturret.name=double turret block.doubleturret.fulldescription=A slightly more powerful version of the turret. Uses stone for ammo. Does significantly more damage, but has a lower range. Shoots two bullets. -block.doubleturret.description=[turretinfo]Ammo: stone block.machineturret.name=gattling turret block.machineturret.fulldescription=A standard all-around turret. Uses iron for ammo. Has a fast fire rate with decent damage. -block.machineturret.description=[turretinfo]Ammo: iron block.shotgunturret.name=splitter turret block.shotgunturret.fulldescription=A standard turret. Uses iron for ammo. Shoots a spread of 7 bullets. Lower range, but higher damage output than the gattling turret. -block.shotgunturret.description=[turretinfo]Ammo: iron block.flameturret.name=flamer turret block.flameturret.fulldescription=Advanced close-range turret. Uses coal for ammo. Has very low range, but very high damage. Good for close quarters. Recommended to be used behind walls. -block.flameturret.description=[turretinfo]Ammo: coal block.sniperturret.name=railgun turret block.sniperturret.fulldescription=Advanced long-range turret. Uses steel for ammo. Very high damage, but low fire rate. Expensive to use, but can be placed far away from enemy lines due to its range. -block.sniperturret.description=[turretinfo]Ammo: steel block.mortarturret.name=flak turret block.mortarturret.fulldescription=Advanced splash-damage turret. Uses coal for ammo. Very slow fire rate and bullets, but very high single-target and splash damage. Useful for large crowds of enemies. -block.mortarturret.description=[turretinfo]Ammo: coal block.laserturret.name=laser turret block.laserturret.fulldescription=Advanced single-target turret. Uses power. Good medium-range all-around turret. Single-target only. Never misses. -block.laserturret.description=[turretinfo]Uses power. block.waveturret.name=tesla turret block.waveturret.fulldescription=Advanced multi-target turret. Uses power. Medium range. Never misses.Average to low damage, but can hit multiple enemies simultaneously with chain lighting. -block.waveturret.description=[turretinfo]Uses power. block.plasmaturret.name=plasma turret block.plasmaturret.fulldescription=Highly advanced version of the flamer turret. Uses coal as ammo. Very high damage, low to medium range. -block.plasmaturret.description=[turretinfo]Ammo: coal block.chainturret.name=chain turret block.chainturret.fulldescription=The ultimate rapid-fire turret. Uses uranium as ammo. Shoots large slugs at a high fire rate. Medium range. Spans multiple tiles. Extremely tough. -block.chainturret.description=[turretinfo]Ammo: uranium block.titancannon.name=titan cannon block.titancannon.fulldescription=The ultimate long-range turret. Uses uranium as ammo. Shoots large splash-damage shells at a medium rate of fire. Long range. Spans multiple tiles. Extremely tough. -block.titancannon.description=[turretinfo]Ammo: uranium block.playerspawn.name=playerspawn block.enemyspawn.name=enemyspawn \ No newline at end of file diff --git a/core/assets/shaders/outline.fragment b/core/assets/shaders/outline.fragment index 2ac6ef52be..49b799ae52 100644 --- a/core/assets/shaders/outline.fragment +++ b/core/assets/shaders/outline.fragment @@ -7,6 +7,7 @@ uniform sampler2D u_texture; uniform vec4 u_color; uniform vec2 u_texsize; +uniform float u_lighten; varying vec4 v_color; varying vec2 v_texCoord; @@ -30,6 +31,7 @@ void main() { if(any){ gl_FragColor = u_color; }else{ - gl_FragColor = texture2D(u_texture, T) * v_color; + vec4 c = texture2D(u_texture, T); + gl_FragColor = mix(c, vec4(1.0, 1.0, 1.0, c.a), u_lighten) * v_color; } } diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 99851e2016..1626056bfb 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -20,56 +20,56 @@ blank index: -1 blocks/blackrock1 rotate: false - xy: 521, 136 + xy: 172, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackrockshadow1 rotate: false - xy: 482, 95 + xy: 964, 473 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone1 rotate: false - xy: 868, 485 + xy: 974, 473 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone2 rotate: false - xy: 878, 485 + xy: 984, 473 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone3 rotate: false - xy: 888, 485 + xy: 994, 473 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock1 rotate: false - xy: 898, 485 + xy: 1004, 473 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock2 rotate: false - xy: 908, 485 + xy: 1014, 473 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock3 rotate: false - xy: 918, 485 + xy: 841, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -83,7 +83,7 @@ blocks/blackstoneedge index: -1 blocks/block rotate: false - xy: 938, 485 + xy: 861, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -104,7 +104,7 @@ blocks/block-3x3 index: -1 blocks/block-middle rotate: false - xy: 948, 485 + xy: 871, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -118,119 +118,119 @@ blocks/chainturret index: -1 blocks/chainturret-icon rotate: false - xy: 95, 21 + xy: 740, 369 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/coal1 rotate: false - xy: 968, 485 + xy: 901, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal2 rotate: false - xy: 978, 485 + xy: 911, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal3 rotate: false - xy: 988, 485 + xy: 921, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coaldrill rotate: false - xy: 998, 485 + xy: 931, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator rotate: false - xy: 1008, 485 + xy: 941, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator-top rotate: false - xy: 841, 473 + xy: 951, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalpurifier rotate: false - xy: 841, 463 + xy: 531, 136 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/combustiongenerator rotate: false - xy: 851, 473 + xy: 527, 126 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/compositewall rotate: false - xy: 851, 463 + xy: 172, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduit rotate: false - xy: 851, 453 + xy: 182, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitbottom rotate: false - xy: 861, 473 + xy: 192, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitliquid rotate: false - xy: 861, 463 + xy: 202, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduittop rotate: false - xy: 861, 453 + xy: 212, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyor rotate: false - xy: 871, 475 + xy: 222, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyormove rotate: false - xy: 871, 465 + xy: 232, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyortunnel rotate: false - xy: 881, 475 + xy: 242, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -244,42 +244,42 @@ blocks/core index: -1 blocks/cross rotate: false - xy: 871, 455 + xy: 252, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/crucible rotate: false - xy: 881, 465 + xy: 262, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/deepwater rotate: false - xy: 891, 475 + xy: 272, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt1 rotate: false - xy: 881, 455 + xy: 282, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt2 rotate: false - xy: 891, 465 + xy: 292, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt3 rotate: false - xy: 901, 475 + xy: 302, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -293,7 +293,7 @@ blocks/dirtedge index: -1 blocks/door rotate: false - xy: 891, 455 + xy: 312, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -307,7 +307,7 @@ blocks/door-large index: -1 blocks/door-large-icon rotate: false - xy: 901, 465 + xy: 322, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -321,21 +321,21 @@ blocks/door-large-open index: -1 blocks/door-open rotate: false - xy: 911, 475 + xy: 332, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/doubleturret rotate: false - xy: 123, 49 + xy: 740, 345 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/duriumwall rotate: false - xy: 901, 455 + xy: 342, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -349,266 +349,266 @@ blocks/duriumwall-large index: -1 blocks/duriumwall-large-icon rotate: false - xy: 911, 465 + xy: 352, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/enemyspawn rotate: false - xy: 921, 475 + xy: 362, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/flameturret rotate: false - xy: 95, 9 + xy: 740, 333 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/fluxpump rotate: false - xy: 921, 465 + xy: 372, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass1 rotate: false - xy: 931, 475 + xy: 382, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass2 rotate: false - xy: 921, 455 + xy: 392, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass3 rotate: false - xy: 931, 465 + xy: 402, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock1 rotate: false - xy: 941, 475 + xy: 412, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock2 rotate: false - xy: 931, 455 + xy: 422, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassedge rotate: false - xy: 140, 91 + xy: 95, 43 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/ice1 rotate: false - xy: 941, 465 + xy: 432, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice2 rotate: false - xy: 951, 475 + xy: 442, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice3 rotate: false - xy: 941, 455 + xy: 452, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iceedge rotate: false - xy: 154, 91 + xy: 111, 59 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/icerock1 rotate: false - xy: 951, 465 + xy: 462, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerock2 rotate: false - xy: 961, 475 + xy: 472, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow1 rotate: false - xy: 951, 455 + xy: 482, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow1 rotate: false - xy: 951, 455 + xy: 482, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow2 rotate: false - xy: 961, 465 + xy: 492, 94 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow2 rotate: false - xy: 961, 465 + xy: 492, 94 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron1 rotate: false - xy: 991, 465 + xy: 891, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron2 rotate: false - xy: 1001, 475 + xy: 901, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron3 rotate: false - xy: 991, 455 + xy: 911, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/irondrill rotate: false - xy: 1001, 465 + xy: 921, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ironwall rotate: false - xy: 1001, 455 + xy: 931, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/junction rotate: false - xy: 1011, 475 + xy: 941, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/laserturret rotate: false - xy: 410, 93 + xy: 1000, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/lava rotate: false - xy: 1011, 465 + xy: 951, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/lavaedge rotate: false - xy: 168, 91 + xy: 127, 75 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/lavasmelter rotate: false - xy: 1011, 455 + xy: 541, 140 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquiditemjunction rotate: false - xy: 492, 82 + xy: 527, 116 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidjunction rotate: false - xy: 502, 82 + xy: 524, 106 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidrouter rotate: false - xy: 512, 82 + xy: 696, 282 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/machineturret rotate: false - xy: 422, 93 + xy: 1012, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/megarepairturret rotate: false - xy: 434, 93 + xy: 844, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mortarturret rotate: false - xy: 446, 93 + xy: 856, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mossblock rotate: false - xy: 801, 443 + xy: 706, 285 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/mossstone rotate: false - xy: 801, 443 + xy: 706, 285 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -629,7 +629,7 @@ blocks/nuclearreactor-center index: -1 blocks/nuclearreactor-icon rotate: false - xy: 821, 445 + xy: 696, 272 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -650,336 +650,336 @@ blocks/nuclearreactor-small index: -1 blocks/oil rotate: false - xy: 831, 445 + xy: 706, 275 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/oiledge rotate: false - xy: 95, 61 + xy: 141, 75 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/oilrefinery rotate: false - xy: 841, 444 + xy: 740, 311 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/omnidrill rotate: false - xy: 851, 443 + xy: 734, 301 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/plasmaturret rotate: false - xy: 458, 93 + xy: 868, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/playerspawn rotate: false - xy: 861, 443 + xy: 744, 301 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerbooster rotate: false - xy: 871, 445 + xy: 750, 311 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyor rotate: false - xy: 881, 445 + xy: 754, 301 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyormove rotate: false - xy: 891, 445 + xy: 631, 194 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaser rotate: false - xy: 901, 445 + xy: 798, 393 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlasercorner rotate: false - xy: 911, 445 + xy: 537, 126 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaserrouter rotate: false - xy: 921, 445 + xy: 537, 116 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduit rotate: false - xy: 931, 445 + xy: 534, 106 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduitbottom rotate: false - xy: 941, 445 + xy: 302, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduittop rotate: false - xy: 951, 445 + xy: 312, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pump rotate: false - xy: 961, 445 + xy: 322, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/repairturret rotate: false - xy: 470, 93 + xy: 880, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/rock1 rotate: false - xy: 981, 445 + xy: 332, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rock2 rotate: false - xy: 991, 445 + xy: 342, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/router rotate: false - xy: 1001, 445 + xy: 352, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator rotate: false - xy: 1011, 445 + xy: 362, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator-top rotate: false - xy: 527, 126 + xy: 372, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand1 rotate: false - xy: 527, 116 + xy: 382, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand2 rotate: false - xy: 524, 106 + xy: 392, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand3 rotate: false - xy: 736, 381 + xy: 402, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock1 rotate: false - xy: 740, 371 + xy: 412, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock2 rotate: false - xy: 740, 361 + xy: 422, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock3 rotate: false - xy: 740, 351 + xy: 432, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandedge rotate: false - xy: 109, 75 + xy: 95, 15 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/shadow rotate: false - xy: 492, 92 + xy: 892, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shieldgenerator rotate: false - xy: 740, 331 + xy: 452, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shotgunturret rotate: false - xy: 504, 92 + xy: 904, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shrub rotate: false - xy: 302, 79 + xy: 492, 84 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shrubshadow rotate: false - xy: 312, 79 + xy: 502, 84 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter rotate: false - xy: 322, 79 + xy: 512, 84 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter-middle rotate: false - xy: 332, 79 + xy: 801, 443 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sniperturret rotate: false - xy: 516, 92 + xy: 916, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/snow1 rotate: false - xy: 342, 79 + xy: 811, 445 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow2 rotate: false - xy: 352, 79 + xy: 821, 445 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow3 rotate: false - xy: 362, 83 + xy: 831, 445 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock1 rotate: false - xy: 372, 83 + xy: 841, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock2 rotate: false - xy: 382, 83 + xy: 851, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock3 rotate: false - xy: 392, 83 + xy: 861, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowedge rotate: false - xy: 109, 61 + xy: 155, 75 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/sorter rotate: false - xy: 402, 83 + xy: 871, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyor rotate: false - xy: 412, 83 + xy: 881, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyormove rotate: false - xy: 422, 83 + xy: 891, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelwall rotate: false - xy: 432, 83 + xy: 901, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -993,98 +993,98 @@ blocks/steelwall-large index: -1 blocks/steelwall-large-icon rotate: false - xy: 442, 83 + xy: 911, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone1 rotate: false - xy: 452, 83 + xy: 921, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone2 rotate: false - xy: 462, 83 + xy: 931, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone3 rotate: false - xy: 472, 83 + xy: 941, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock1 rotate: false - xy: 482, 76 + xy: 951, 441 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock2 rotate: false - xy: 492, 72 + xy: 734, 291 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock3 rotate: false - xy: 502, 72 + xy: 744, 291 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonedrill rotate: false - xy: 512, 72 + xy: 754, 291 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneedge rotate: false - xy: 109, 47 + xy: 537, 150 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/stoneformer rotate: false - xy: 522, 72 + xy: 362, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonewall rotate: false - xy: 528, 96 + xy: 372, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter rotate: false - xy: 534, 106 + xy: 382, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter-top rotate: false - xy: 538, 96 + xy: 392, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/thermalgenerator rotate: false - xy: 532, 86 + xy: 402, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1098,56 +1098,56 @@ blocks/titancannon index: -1 blocks/titancannon-icon rotate: false - xy: 786, 391 + xy: 928, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/titanium1 rotate: false - xy: 532, 76 + xy: 412, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium2 rotate: false - xy: 542, 86 + xy: 422, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium3 rotate: false - xy: 542, 76 + xy: 432, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumdrill rotate: false - xy: 746, 381 + xy: 442, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumpurifier rotate: false - xy: 750, 371 + xy: 452, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumshieldwall rotate: false - xy: 750, 361 + xy: 462, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumwall rotate: false - xy: 750, 351 + xy: 472, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1161,77 +1161,91 @@ blocks/titaniumwall-large index: -1 blocks/titaniumwall-large-icon rotate: false - xy: 750, 341 + xy: 482, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/turret rotate: false - xy: 844, 483 + xy: 940, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/uranium1 rotate: false - xy: 740, 311 + xy: 512, 74 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium2 rotate: false - xy: 750, 311 + xy: 547, 183 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium3 rotate: false - xy: 734, 301 + xy: 557, 185 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uraniumdrill rotate: false - xy: 744, 301 + xy: 567, 185 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/water rotate: false - xy: 754, 301 + xy: 587, 187 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/wateredge rotate: false - xy: 123, 61 + xy: 736, 381 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/waveturret rotate: false - xy: 856, 483 + xy: 952, 471 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 +blocks/weaponfactory + rotate: false + xy: 646, 273 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +blocks/weaponfactory-icon + rotate: false + xy: 750, 386 + size: 8, 8 + orig: 8, 8 + offset: 0, 0 + index: -1 bullet rotate: false - xy: 958, 485 + xy: 881, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 chainbullet rotate: false - xy: 841, 454 + xy: 644, 236 size: 8, 7 orig: 8, 7 offset: 0, 0 @@ -1252,49 +1266,49 @@ circle2 index: -1 enemies/blastenemy-t1 rotate: false - xy: 646, 275 + xy: 664, 276 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/blastenemy-t2 rotate: false - xy: 646, 259 + xy: 646, 257 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/blastenemy-t3 rotate: false - xy: 580, 229 + xy: 680, 276 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t1 rotate: false - xy: 596, 232 + xy: 580, 229 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t2 rotate: false - xy: 612, 232 + xy: 596, 232 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/empenemy-t3 rotate: false - xy: 628, 236 + xy: 612, 232 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fastenemy-t1 rotate: false - xy: 646, 243 + xy: 628, 236 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1378,91 +1392,91 @@ enemies/healerenemy-t3 index: -1 enemies/mortarenemy-t1 rotate: false - xy: 738, 396 + xy: 786, 419 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t2 rotate: false - xy: 754, 414 + xy: 786, 403 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t3 rotate: false - xy: 754, 398 + xy: 92, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t1 rotate: false - xy: 770, 414 + xy: 108, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t2 rotate: false - xy: 770, 398 + xy: 124, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t3 rotate: false - xy: 786, 419 + xy: 140, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/standardenemy-t1 rotate: false - xy: 786, 403 + xy: 156, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/targetenemy-t1 rotate: false - xy: 786, 403 + xy: 156, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/standardenemy-t2 rotate: false - xy: 123, 75 + xy: 533, 178 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/standardenemy-t3 rotate: false - xy: 95, 33 + xy: 537, 164 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/tankenemy-t1 rotate: false - xy: 92, 89 + xy: 95, 73 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t2 rotate: false - xy: 108, 89 + xy: 95, 57 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t3 rotate: false - xy: 124, 89 + xy: 111, 73 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1490,70 +1504,70 @@ enemies/titanenemy-t3 index: -1 enemyarrow rotate: false - xy: 482, 86 + xy: 654, 236 size: 8, 7 orig: 8, 7 offset: 0, 0 index: -1 icon-coal rotate: false - xy: 971, 475 + xy: 502, 94 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-dirium rotate: false - xy: 961, 455 + xy: 512, 94 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-iron rotate: false - xy: 971, 465 + xy: 169, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-sand rotate: false - xy: 981, 475 + xy: 841, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-steel rotate: false - xy: 971, 455 + xy: 851, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-stone rotate: false - xy: 981, 465 + xy: 861, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-titanium rotate: false - xy: 991, 475 + xy: 871, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-uranium rotate: false - xy: 981, 455 + xy: 881, 451 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laser rotate: false - xy: 533, 178 + xy: 841, 477 size: 1, 12 orig: 1, 12 offset: 0, 0 @@ -1574,42 +1588,42 @@ laserfull index: -1 mechs/mech-standard rotate: false - xy: 95, 75 + xy: 95, 29 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mechs/ship-standard rotate: false - xy: 95, 47 + xy: 95, 1 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shell rotate: false - xy: 740, 341 + xy: 442, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot rotate: false - xy: 740, 321 + xy: 472, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot-long rotate: false - xy: 798, 393 + xy: 482, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanshell rotate: false - xy: 750, 331 + xy: 492, 74 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1708,7 +1722,7 @@ ui/check-over index: -1 ui/clear rotate: false - xy: 109, 35 + xy: 740, 357 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1743,7 +1757,7 @@ ui/icons/icon-add index: -1 ui/icons/icon-areaDelete rotate: false - xy: 536, 181 + xy: 740, 321 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1757,28 +1771,28 @@ ui/icons/icon-arrow index: -1 ui/icons/icon-arrow-down rotate: false - xy: 537, 169 + xy: 646, 245 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-arrow-left rotate: false - xy: 537, 157 + xy: 647, 224 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-arrow-right rotate: false - xy: 537, 145 + xy: 647, 212 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-arrow-up rotate: false - xy: 182, 85 + xy: 647, 200 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1799,7 +1813,7 @@ ui/icons/icon-cancel index: -1 ui/icons/icon-chat rotate: false - xy: 194, 85 + xy: 658, 245 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1834,21 +1848,21 @@ ui/icons/icon-close-over index: -1 ui/icons/icon-crafting rotate: false - xy: 206, 85 + xy: 786, 391 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-cursor rotate: false - xy: 218, 85 + xy: 659, 224 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-defense rotate: false - xy: 230, 85 + xy: 659, 212 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1862,7 +1876,7 @@ ui/icons/icon-discord index: -1 ui/icons/icon-distribution rotate: false - xy: 242, 85 + xy: 659, 200 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1932,14 +1946,14 @@ ui/icons/icon-grid index: -1 ui/icons/icon-hold rotate: false - xy: 254, 85 + xy: 844, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-holdDelete rotate: false - xy: 266, 85 + xy: 856, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1960,7 +1974,7 @@ ui/icons/icon-host index: -1 ui/icons/icon-info rotate: false - xy: 278, 85 + xy: 868, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1974,7 +1988,7 @@ ui/icons/icon-line index: -1 ui/icons/icon-load rotate: false - xy: 647, 227 + xy: 722, 411 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2002,21 +2016,21 @@ ui/icons/icon-loading index: -1 ui/icons/icon-menu rotate: false - xy: 290, 85 + xy: 880, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-none rotate: false - xy: 302, 89 + xy: 892, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-pause rotate: false - xy: 314, 89 + xy: 904, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2037,35 +2051,35 @@ ui/icons/icon-pick index: -1 ui/icons/icon-play rotate: false - xy: 326, 89 + xy: 916, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-play-2 rotate: false - xy: 647, 211 + xy: 722, 395 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-power rotate: false - xy: 338, 89 + xy: 928, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-production rotate: false - xy: 350, 89 + xy: 940, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-quit rotate: false - xy: 647, 195 + xy: 724, 365 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2079,7 +2093,7 @@ ui/icons/icon-redo index: -1 ui/icons/icon-rename rotate: false - xy: 631, 188 + xy: 724, 349 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2093,35 +2107,35 @@ ui/icons/icon-resize index: -1 ui/icons/icon-rotate rotate: false - xy: 647, 179 + xy: 724, 333 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-arrow rotate: false - xy: 722, 411 + xy: 724, 317 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-left rotate: false - xy: 722, 395 + xy: 738, 412 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-right rotate: false - xy: 724, 365 + xy: 738, 396 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-save rotate: false - xy: 724, 349 + xy: 754, 414 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2142,7 +2156,7 @@ ui/icons/icon-save-map index: -1 ui/icons/icon-settings rotate: false - xy: 362, 93 + xy: 952, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2156,35 +2170,35 @@ ui/icons/icon-terrain index: -1 ui/icons/icon-tools rotate: false - xy: 724, 333 + xy: 754, 398 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-touch rotate: false - xy: 374, 93 + xy: 964, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-touchDelete rotate: false - xy: 386, 93 + xy: 976, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-trash rotate: false - xy: 724, 317 + xy: 770, 414 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-tutorial rotate: false - xy: 738, 412 + xy: 770, 398 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2198,7 +2212,7 @@ ui/icons/icon-undo index: -1 ui/icons/icon-weapon rotate: false - xy: 398, 93 + xy: 988, 483 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2355,7 +2369,7 @@ ui/textfield-over index: -1 ui/white rotate: false - xy: 738, 391 + xy: 547, 178 size: 3, 3 orig: 3, 3 offset: 0, 0 @@ -2376,44 +2390,44 @@ ui/window-empty orig: 27, 61 offset: 0, 0 index: -1 +weapons/beam + rotate: false + xy: 521, 136 + size: 8, 8 + orig: 8, 8 + offset: 0, 0 + index: -1 weapons/blaster rotate: false - xy: 928, 485 + xy: 851, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 -weapons/flamer +weapons/clustergun rotate: false - xy: 911, 455 + xy: 891, 461 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 -weapons/mortar +weapons/shockgun rotate: false - xy: 522, 82 - size: 8, 8 - orig: 8, 8 - offset: 0, 0 - index: -1 -weapons/multigun - rotate: false - xy: 811, 445 - size: 8, 8 - orig: 8, 8 - offset: 0, 0 - index: -1 -weapons/railgun - rotate: false - xy: 971, 445 + xy: 462, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/triblaster rotate: false - xy: 750, 321 + xy: 502, 74 + size: 8, 8 + orig: 8, 8 + offset: 0, 0 + index: -1 +weapons/vulcan + rotate: false + xy: 577, 185 size: 8, 8 orig: 8, 8 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 05bdfbdeae..4482b6a672 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 2be67f3e86..46906b3fe7 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -140,7 +140,8 @@ public class Control extends Module{ "move_y", new Axis(Input.S, Input.W), "select", Input.MOUSE_LEFT, "break", Input.MOUSE_RIGHT, - "shootInternal", Input.MOUSE_LEFT, + "shoot", Input.MOUSE_LEFT, + "weapon_alt_select", Input.Q, "zoom_hold", Input.CONTROL_LEFT, "zoom", new Axis(Input.SCROLL), "menu", Gdx.app.getType() == ApplicationType.Android ? Input.BACK : Input.ESCAPE, @@ -166,7 +167,7 @@ public class Control extends Module{ "cursor_y", new Axis(Input.CONTROLLER_R_STICK_VERTICAL_AXIS), "select", Input.CONTROLLER_R_BUMPER, "break", Input.CONTROLLER_L_BUMPER, - "shootInternal", Input.CONTROLLER_R_TRIGGER, + "shoot", Input.CONTROLLER_R_TRIGGER, "zoom_hold", Input.ANY_KEY, "zoom", new Axis(Input.CONTROLLER_DPAD_DOWN, Input.CONTROLLER_DPAD_UP), "menu", Input.CONTROLLER_X, @@ -223,7 +224,13 @@ public class Control extends Module{ weapons.clear(); weapons.add(Weapon.blaster); - player.weapon = weapons.first(); + player.weaponLeft = player.weaponRight = weapons.first(); + + if(debug){ + //weapons.add(Weapon.triblaster, Weapon.clustergun, Weapon.beam, Weapon.vulcan); + //weapons.add(Weapon.shockgun); + player.weaponLeft = player.weaponRight = weapons.peek(); + } lastUpdated = -1; wave = 1; @@ -245,7 +252,7 @@ public class Control extends Module{ } ui.hudfrag.updateItems(); - ui.weaponfrag.update(); + ui.hudfrag.updateWeapons(); } public void play(){ @@ -672,5 +679,4 @@ public class Control extends Module{ } } } - } diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 7e3a7746e7..4148519ba8 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -17,6 +17,7 @@ import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.net.Syncable; import io.anuke.mindustry.net.Syncable.Interpolator; +import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -148,7 +149,7 @@ public class NetClient extends Module { Net.handle(ShootPacket.class, packet -> { Player player = Vars.control.playerGroup.getByID(packet.playerid); - Weapon weapon = Weapon.values()[packet.weaponid]; + Weapon weapon = (Weapon) Upgrade.getByID(packet.weaponid); weapon.shoot(player, packet.x, packet.y, packet.rotation); }); @@ -251,6 +252,15 @@ public class NetClient extends Module { GameState.set(State.menu); Gdx.app.postRunnable(() -> Vars.ui.showError("$text.server.kicked." + KickReason.values()[packet.reason].name())); }); + + Net.handle(WeaponSwitchPacket.class, packet -> { + Player player = Vars.control.playerGroup.getByID(packet.playerid); + + if(player == null) return; + + player.weaponLeft = (Weapon)Upgrade.getByID(packet.left); + player.weaponRight = (Weapon)Upgrade.getByID(packet.right); + }); } @Override @@ -264,9 +274,17 @@ public class NetClient extends Module { } } + public void handleWeaponSwitch(){ + WeaponSwitchPacket packet = new WeaponSwitchPacket(); + packet.left = Vars.player.weaponLeft.id; + packet.right = Vars.player.weaponRight.id; + packet.playerid = Vars.player.id; + Net.send(packet, SendMode.tcp); + } + public void handleUpgrade(Weapon weapon){ UpgradePacket packet = new UpgradePacket(); - packet.id = weapon.ordinal(); + packet.id = weapon.id; Net.send(packet, SendMode.tcp); } @@ -283,7 +301,7 @@ public class NetClient extends Module { public void handleShoot(Weapon weapon, float x, float y, float angle){ ShootPacket packet = new ShootPacket(); - packet.weaponid = (byte)weapon.ordinal(); + packet.weaponid = weapon.id; packet.x = x; packet.y = y; packet.rotation = angle; diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 0c2fb6ad92..d8400f1e92 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -15,9 +15,7 @@ import io.anuke.mindustry.io.NetworkIO; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Packets.*; -import io.anuke.mindustry.resource.ItemStack; -import io.anuke.mindustry.resource.Recipe; -import io.anuke.mindustry.resource.Weapon; +import io.anuke.mindustry.resource.*; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.UCore; @@ -118,7 +116,7 @@ public class NetServer extends Module{ Net.handleServer(ShootPacket.class, packet -> { Player player = connections.get(Net.getLastConnection()); - Weapon weapon = Weapon.values()[packet.weaponid]; + Weapon weapon = (Weapon)Upgrade.getByID(packet.weaponid); weapon.shoot(player, packet.x, packet.y, packet.rotation); packet.playerid = player.id; @@ -129,7 +127,7 @@ public class NetServer extends Module{ Vars.control.input.placeBlockInternal(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, false); packet.playerid = connections.get(Net.getLastConnection()).id; - Recipe recipe = Recipe.getByResult(Block.getByID(packet.block)); + Recipe recipe = Recipes.getByResult(Block.getByID(packet.block)); if(recipe != null){ for(ItemStack stack : recipe.requirements){ Vars.control.removeItem(stack); @@ -149,16 +147,28 @@ public class NetServer extends Module{ Net.handleServer(ChatPacket.class, packet -> { Player player = connections.get(Net.getLastConnection()); - if(player == null) - return; //GHOSTS AAAA + if(player == null) return; //GHOSTS AAAA packet.name = player.name; Net.send(packet, SendMode.tcp); }); Net.handleServer(UpgradePacket.class, packet -> { - Weapon weapon = Weapon.values()[packet.id]; - Vars.control.removeItems(weapon.requirements); + Weapon weapon = (Weapon)Upgrade.getByID(packet.id); + Vars.control.removeItems(UpgradeRecipes.get(weapon)); + }); + + Net.handleServer(WeaponSwitchPacket.class, packet -> { + Player player = connections.get(Net.getLastConnection()); + + if(player == null) return; + + packet.playerid = player.id; + + player.weaponLeft = (Weapon)Upgrade.getByID(packet.left); + player.weaponRight = (Weapon)Upgrade.getByID(packet.right); + + Net.sendExcept(player.clientid, packet, SendMode.tcp); }); } diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 1f200c4ad3..2e24248672 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; @@ -324,6 +325,16 @@ public class Renderer extends RendererModule{ } Draw.reset(); } + + //draw config selected block + if(Vars.ui.configfrag.isShown()){ + Tile tile = ui.configfrag.getSelectedTile(); + Draw.color(Colors.get("accent")); + Draw.thick(1f); + Draw.square(tile.worldx() + tile.block().getPlaceOffset().x, tile.worldy() + tile.block().getPlaceOffset().y, + tile.block().width * Vars.tilesize / 2f + 1f); + Draw.reset(); + } int tilex = control.input.getBlockX(); int tiley = control.input.getBlockY(); diff --git a/core/src/io/anuke/mindustry/core/Tutorial.java b/core/src/io/anuke/mindustry/core/Tutorial.java index 8b8c86ff1c..acaf23cb39 100644 --- a/core/src/io/anuke/mindustry/core/Tutorial.java +++ b/core/src/io/anuke/mindustry/core/Tutorial.java @@ -392,9 +392,9 @@ public class Tutorial{ } void onSwitch(){ - if(!Vars.control.getWeapons().contains(Weapon.multigun, true)){ - Vars.control.getWeapons().add(Weapon.multigun); - Vars.ui.weaponfrag.update(); + if(!Vars.control.getWeapons().contains(Weapon.triblaster, true)){ + Vars.control.getWeapons().add(Weapon.triblaster); + Vars.ui.hudfrag.updateWeapons(); } } }, diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index f0a5808a34..57a7882294 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -39,13 +39,11 @@ public class UI extends SceneModule{ public SettingsMenuDialog settings; public ControlsDialog controls; public MapEditorDialog editor; - public UpgradeDialog upgrades; public final MenuFragment menufrag = new MenuFragment(); public final ToolFragment toolfrag = new ToolFragment(); public final HudFragment hudfrag = new HudFragment(); public final PlacementFragment placefrag = new PlacementFragment(); - public final WeaponFragment weaponfrag = new WeaponFragment(); public final ChatFragment chatfrag = new ChatFragment(); public final PlayerListFragment listfrag = new PlayerListFragment(); public final BackgroundFragment backfrag = new BackgroundFragment(); @@ -137,7 +135,6 @@ public class UI extends SceneModule{ join = new JoinDialog(); discord = new DiscordDialog(); load = new LoadDialog(); - upgrades = new UpgradeDialog(); levels = new LevelDialog(); settings = new SettingsMenuDialog(); paused = new PausedDialog(); @@ -147,7 +144,6 @@ public class UI extends SceneModule{ build.begin(scene); backfrag.build(); - weaponfrag.build(); hudfrag.build(); configfrag.build(); menufrag.build(); diff --git a/core/src/io/anuke/mindustry/entities/BulletType.java b/core/src/io/anuke/mindustry/entities/BulletType.java index 5037870f0a..c072a834ce 100644 --- a/core/src/io/anuke/mindustry/entities/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/BulletType.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.graphics.Color; - import io.anuke.mindustry.entities.effect.DamageArea; import io.anuke.mindustry.entities.effect.EMP; import io.anuke.mindustry.entities.enemies.Enemy; @@ -10,17 +9,12 @@ import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.BaseBulletType; -import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; -public abstract class BulletType extends BaseBulletType{ - static Color glowy = Color.valueOf("fdc056"); - static Color lightGold = Hue.mix(Color.GOLD, Color.WHITE, 0.4f); - static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f); - static Color lightOrange = Color.valueOf("f68021"); - static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f); - static Color whiteYellow = Hue.mix(Color.YELLOW, Color.WHITE, 0.6f); +import static io.anuke.mindustry.graphics.Fx.*; + +public abstract class BulletType extends BaseBulletType{ public static final BulletType @@ -88,9 +82,7 @@ public abstract class BulletType extends BaseBulletType{ } public void removed(Bullet b){ - Timers.run(5f, ()->{ - new EMP(b.x, b.y, b.getDamage()).add(); - }); + Timers.run(5f, ()-> new EMP(b.x, b.y, b.getDamage()).add()); Effects.effect(Fx.empshockwave, b); Effects.shake(3f, 3f, b); } @@ -220,12 +212,6 @@ public abstract class BulletType extends BaseBulletType{ public void draw(Bullet b){} }, - shellshot = new BulletType(1.5f, 6){ - { - lifetime = 7f; - } - public void draw(Bullet b){} - }, blastshot = new BulletType(1.6f, 6){ { lifetime = 7f; @@ -255,7 +241,7 @@ public abstract class BulletType extends BaseBulletType{ Draw.reset(); } }, - flame = new BulletType(0.6f, 5){ + flame = new BulletType(0.6f, 5){ //for turrets public void draw(Bullet b){ Draw.color(Color.YELLOW, Color.SCARLET, b.time/lifetime); float size = 6f-b.time/lifetime*5f; @@ -274,7 +260,7 @@ public abstract class BulletType extends BaseBulletType{ Draw.reset(); } }, - flameshot = new BulletType(0.5f, 3){ + flameshot = new BulletType(0.5f, 3){ //for enemies public void draw(Bullet b){ Draw.color(Color.ORANGE, Color.SCARLET, b.time/lifetime); float size = 6f-b.time/lifetime*5f; @@ -282,21 +268,158 @@ public abstract class BulletType extends BaseBulletType{ Draw.reset(); } }, - shot = new BulletType(2.4f, 4){ - {lifetime = 40;} + shot = new BulletType(2.7f, 5){ + { + lifetime = 40; + } + public void draw(Bullet b){ - Draw.color(lightGold); - Draw.rect("bullet", b.x, b.y, b.angle()); + Draw.color(Color.WHITE, lightOrange, b.fract()/2f + 0.25f); + Draw.thick(1.5f); + Draw.lineAngle(b.x, b.y, b.angle(), 3f); Draw.reset(); } }, - multishot = new BulletType(2.5f, 3){ - {lifetime=40;} - public void draw(Bullet b){ - Draw.color(Color.SKY); - Draw.rect("bullet", b.x, b.y, b.angle()); + spread = new BulletType(2.4f, 7) { + { + lifetime = 70; + } + + public void draw(Bullet b) { + float size = 3f - b.ifract()*1f; + + Draw.color(Color.PURPLE, Color.WHITE, 0.8f); + Draw.thick(1f); + Draw.circle(b.x, b.y, size); Draw.reset(); } + }, + cluster = new BulletType(4.4f, 13){ + { + lifetime = 60; + drag = 0.06f; + } + + public void draw(Bullet b){ + Draw.thick(2f); + Draw.color(lightOrange, Color.WHITE, 0.4f); + Draw.polygon(b.y, b.x, 3, 1.6f, b.angle()); + Draw.thick(1f); + Draw.color(Color.WHITE, lightOrange, b.ifract()/2f); + Draw.alpha(b.ifract()); + Draw.spikes(b.x, b.y, 1.5f, 2f, 6); + Draw.reset(); + } + + public void despawned(Bullet b){ + removed(b); + } + + public void removed(Bullet b){ + Effects.shake(1.5f, 1.5f, b); + + Effects.effect(Fx.clusterbomb, b); + + DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 22f, damage); + } + }, + vulcan = new BulletType(4.5f, 11) { + { + lifetime = 50; + } + + public void init(Bullet b) { + Timers.reset(b, "smoke", Mathf.random(4f)); + } + + public void draw(Bullet b){ + Draw.color(lightGray); + Draw.thick(1f); + Draw.lineAngleCenter(b.x, b.y, b.angle(), 2f); + Draw.reset(); + } + + public void update(Bullet b){ + if(Timers.get(b, "smoke", 4)){ + Effects.effect(Fx.chainsmoke, b.x, b.y); + } + } + }, + shockshell = new BulletType(5.4f, 10) { + + { + drag = 0.03f; + lifetime = 30f; + } + + public void init(Bullet b) { + b.velocity.scl(Mathf.random(0.5f, 1f)); + } + + public void draw(Bullet b) { + Draw.color(Color.WHITE, Color.ORANGE, b.ifract()); + Draw.thick(2f); + Draw.lineAngleCenter(b.x, b.y, b.angle(), b.fract()*5f); + Draw.reset(); + } + + public void despawned(Bullet b) { + removed(b); + } + + public void removed(Bullet b) { + for(int i = 0; i < 4; i ++){ + Bullet bullet = new Bullet(scrap, b.owner, b.x, b.y, b.angle() + Mathf.range(80f)); + bullet.add(); + } + } + }, + scrap = new BulletType(2f, 3) { + { + drag = 0.06f; + lifetime = 30f; + } + + public void init(Bullet b) { + b.velocity.scl(Mathf.random(0.5f, 1f)); + } + + public void draw(Bullet b) { + Draw.color(Color.WHITE, Color.ORANGE, b.ifract()); + Draw.thick(1f); + Draw.lineAngleCenter(b.x, b.y, b.angle(), b.fract()*4f); + Draw.reset(); + } + }, + beamlaser = new BulletType(0.001f, 35) { + float length = 230f; + { + drawSize = length*2f+20f; + lifetime = 15f; + } + + public void init(Bullet b) { + DamageArea.damageLine(true, Fx.beamhit, b.x, b.y, b.angle(), length, damage); + } + + public void draw(Bullet b) { + float f = b.fract()*1.5f; + + Draw.color(beam); + Draw.rect("circle", b.x, b.y, 6f*f, 6f*f); + Draw.thick(3f * f); + Draw.lineAngle(b.x, b.y, b.angle(), length); + + Draw.thick(2f * f); + Draw.lineAngle(b.x, b.y, b.angle(), length + 6f); + Draw.thick(1f * f); + Draw.lineAngle(b.x, b.y, b.angle(), length + 12f); + + Draw.color(beamLight); + Draw.thick(1.5f * f); + Draw.rect("circle", b.x, b.y, 3f*f, 3f*f); + Draw.lineAngle(b.x, b.y, b.angle(), length); + } }; private BulletType(float speed, int damage){ diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 44e4cef0e6..3419dd68d3 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -16,15 +16,17 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; public class Player extends DestructibleEntity implements Syncable{ - private static final float speed = 1.1f; - private static final float dashSpeed = 1.8f; + static final float speed = 1.1f; + static final float dashSpeed = 1.8f; public String name = "name"; - public transient Weapon weapon = Weapon.blaster; - public Mech mech = Mech.standard; - public float angle; public boolean isAndroid; + public Weapon weaponLeft = Weapon.blaster; + public Weapon weaponRight = Weapon.blaster; + public Mech mech = Mech.standard; + + public float angle; public transient float targetAngle = 0f; public transient int clientid; @@ -86,15 +88,28 @@ public class Player extends DestructibleEntity implements Syncable{ } if((Vars.debug && (!Vars.showPlayer || !Vars.showUI)) || (isAndroid && isLocal)) return; + boolean snap = Vars.snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate") && isLocal; String part = isAndroid ? "ship" : "mech"; - if(Vars.snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate") && isLocal){ - Draw.rect(part+"-"+mech.name(), (int)x, (int)y, angle-90); + if(snap){ + Draw.rect(part + "-" + mech.name, (int)x, (int)y, angle-90); }else{ - Draw.rect(part+"-"+mech.name(), x, y, angle-90); + Draw.rect(part + "-" + mech.name, x, y, angle-90); + } + + if(!isAndroid) { + for (boolean b : new boolean[]{true, false}) { + Weapon weapon = b ? weaponLeft : weaponRight; + Angles.translation(angle + Mathf.sign(b) * -50f, 3.5f); + float s = 5f; + if(snap){ + Draw.rect(weapon.name, (int)x + Angles.x(), (int)y + Angles.y(), s, s, angle- 90); + }else{ + Draw.rect(weapon.name, x + Angles.x(), y + Angles.y(), s, s, angle - 90); + } + } } - } @Override @@ -124,12 +139,12 @@ public class Player extends DestructibleEntity implements Syncable{ vector.y += ya*speed; vector.x += xa*speed; - boolean shooting = !Inputs.keyDown("dash") && Inputs.keyDown("shootInternal") && control.getInput().recipe == null + boolean shooting = !Inputs.keyDown("dash") && Inputs.keyDown("shoot") && control.getInput().recipe == null && !ui.hasMouse() && !control.getInput().onConfigurable(); - if(shooting && Timers.get(this, "reload", weapon.reload)){ - weapon.shoot(this, x, y, Angles.mouseAngle(x, y)); - Sounds.play(weapon.shootsound); + if(shooting){ + weaponLeft.update(player, true); + weaponRight.update(player, false); } if(Inputs.keyDown("dash") && Timers.get(this, "dashfx", 3) && vector.len() > 0){ diff --git a/core/src/io/anuke/mindustry/entities/effect/DamageArea.java b/core/src/io/anuke/mindustry/entities/effect/DamageArea.java index cad6589933..7e7a070e7b 100644 --- a/core/src/io/anuke/mindustry/entities/effect/DamageArea.java +++ b/core/src/io/anuke/mindustry/entities/effect/DamageArea.java @@ -1,22 +1,66 @@ package io.anuke.mindustry.entities.effect; +import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; - import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.world.Tile; +import io.anuke.ucore.core.Effects; +import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.util.Mathf; +import io.anuke.ucore.util.*; -//TODO public class DamageArea{ + private static Rectangle rect = new Rectangle(); + + //only for entities, not tiles (yet!) + public static void damageLine(boolean enemies, Effect effect, float x, float y, float angle, float length, int damage){ + Angles.translation(angle, length); + rect.setPosition(x, y).setSize(Angles.x(), Angles.y()); + float x2 = Angles.x() + x, y2 = Angles.y() + y; + + if(rect.width < 0){ + rect.x += rect.width; + rect.width *= -1; + } + + if(rect.height < 0){ + rect.y += rect.height; + rect.height *= -1; + } + + float expand = 3f; + + rect.y -= expand; + rect.x -= expand; + rect.width += expand*2; + rect.height += expand*2; + + if(enemies){ + Entities.getNearby(Vars.control.enemyGroup, rect, e -> { + Enemy enemy = (Enemy)e; + Rectangle other = enemy.hitbox.getRect(enemy.x, enemy.y); + other.y -= expand; + other.x -= expand; + other.width += expand*2; + other.height += expand*2; + + Vector2 vec = Physics.raycastRect(x, y, x2, y2, other); + + if(vec != null){ + Effects.effect(effect, vec.x, vec.y); + enemy.damage(damage); + } + }); + }//TODO else damage players and blocks? + } public static void damageEntities(float x, float y, float radius, int damage){ damage(true, x, y, radius, damage); - - if(!Vars.android && Vars.player.distanceTo(x, y) < radius){ - Player player = Vars.player; + + for(Player player : Vars.control.playerGroup.all()){ + if(player.isAndroid) continue; int amount = calculateDamage(x, y, player.x, player.y, radius, damage); player.damage(amount); } diff --git a/core/src/io/anuke/mindustry/entities/effect/EMP.java b/core/src/io/anuke/mindustry/entities/effect/EMP.java index e0b284e94a..1f597faa3f 100644 --- a/core/src/io/anuke/mindustry/entities/effect/EMP.java +++ b/core/src/io/anuke/mindustry/entities/effect/EMP.java @@ -56,7 +56,9 @@ public class EMP extends TimedEntity{ p.setPower(tile, 0f); tile.entity.damage((int)(damage*1.5f)); //extra damage } - + + if(tile == null) continue; + //entity may be null here, after the block is dead! Effects.effect(Fx.empspark, tile.worldx(), tile.worldy()); if(tile.entity != null) tile.entity.damage(damage); @@ -82,7 +84,7 @@ public class EMP extends TimedEntity{ } Draw.thick(fract()*2f); - Draw.polygon(34, x, y, radius * Vars.tilesize); + Draw.polygon(y, x, 34, radius * Vars.tilesize); Draw.reset(); } @@ -96,7 +98,7 @@ public class EMP extends TimedEntity{ float dx = Mathf.range(r), dy = Mathf.range(r); - float frac = (float)(seg+1f)/joints; + float frac = (seg+1f)/joints; float tx = (targetx - x)*frac + x + dx, ty = (targety - y)*frac + y + dy; diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java index 3955007fe3..8414a1b69c 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java @@ -28,6 +28,7 @@ public class Enemy extends DestructibleEntity implements Syncable{ public float angle; public Vector2 velocity = new Vector2(); public Entity target; + public float hitTime; public int tier = 1; public Enemy(EnemyType type){ @@ -59,6 +60,12 @@ public class Enemy extends DestructibleEntity implements Syncable{ return (other instanceof Bullet) && !(((Bullet) other).owner instanceof Enemy); } + @Override + public void damage(int amount){ + super.damage(amount); + hitTime = EnemyType.hitDuration; + } + @Override public void onDeath(){ type.onDeath(this); diff --git a/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java b/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java index 626ea50381..0f595d5ce9 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java +++ b/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java @@ -31,6 +31,7 @@ public class EnemyType { public final static int maxtier = 4; public final static float maxIdle = 60*1.5f; public final static float maxIdleLife = 60f*13f; //13 seconds idle = death + public final static float hitDuration = 5f; public final String name; public final byte id; @@ -65,6 +66,7 @@ public class EnemyType { String region = name + "-t" + Mathf.clamp(enemy.tier, 1, 3); Shaders.outline.color.set(tierColors[enemy.tier - 1]); + Shaders.outline.lighten = Mathf.clamp(enemy.hitTime/hitDuration); Shaders.outline.region = Draw.region(region); Shaders.outline.apply(); @@ -73,12 +75,16 @@ public class EnemyType { Draw.color(); Graphics.flush(); + Shaders.outline.lighten = 0f; } public void drawOver(Enemy enemy){ } public void update(Enemy enemy){ float lastx = enemy.x, lasty = enemy.y; + if(enemy.hitTime > 0){ + enemy.hitTime -= Timers.delta(); + } move(enemy); diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/TitanType.java b/core/src/io/anuke/mindustry/entities/enemies/types/TitanType.java index 24d6d2b16c..c8e2786b94 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/types/TitanType.java +++ b/core/src/io/anuke/mindustry/entities/enemies/types/TitanType.java @@ -27,7 +27,7 @@ public class TitanType extends EnemyType { if(Timers.getTime(enemy, "salvo") < 60){ if(Timers.get(enemy, "salvoShoot", 6)){ - enemy.shoot(BulletType.flame, Mathf.range(20f)); + enemy.shoot(BulletType.flameshot, Mathf.range(20f)); } } diff --git a/core/src/io/anuke/mindustry/graphics/Fx.java b/core/src/io/anuke/mindustry/graphics/Fx.java index f65230e76a..a0a99490d7 100644 --- a/core/src/io/anuke/mindustry/graphics/Fx.java +++ b/core/src/io/anuke/mindustry/graphics/Fx.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.graphics; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Colors; - import io.anuke.mindustry.Vars; import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Effects.Effect; @@ -11,10 +10,15 @@ import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; public class Fx{ - static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f); - static Color lightOrange = Color.valueOf("f68021"); - static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f); - static Color whiteYellow = Hue.mix(Color.YELLOW, Color.WHITE, 0.6f); + public static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f); + public static Color lightOrange = Color.valueOf("f68021"); + public static Color lighterOrange = Color.valueOf("f6e096"); + public static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f); + public static Color whiteYellow = Hue.mix(Color.YELLOW, Color.WHITE, 0.6f); + public static Color lightGray = Color.valueOf("b0b0b0"); + public static Color glowy = Color.valueOf("fdc056"); + public static Color beam = Color.valueOf("9bffbe"); + public static Color beamLight = Color.valueOf("ddffe9"); public static final Effect @@ -117,7 +121,7 @@ public class Fx{ nuclearShockwave = new Effect(10f, 200f, e -> { Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract()); Draw.thick(e.fract()*3f + 0.2f); - Draw.polygon(40, e.x, e.y, e.ifract()*140f); + Draw.polygon(e.y, e.x, 40, e.ifract()*140f); Draw.reset(); }), @@ -350,42 +354,51 @@ public class Fx{ Draw.reset(); }), - shoot = new Effect(8, e -> { - Draw.thickness(1f); - Draw.color(Color.WHITE, Color.GOLD, e.ifract()); - Draw.spikes(e.x, e.y, e.ifract() * 2f, 2, 5); + laserShoot = new Effect(8, e -> { + Draw.color(Color.WHITE, lightOrange, e.ifract()); + Draw.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 6f, 2f, 0.8f); + Draw.reset(); + }), + + spreadShoot = new Effect(12, e -> { + Draw.color(Color.WHITE, Color.PURPLE, e.ifract()); + Draw.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 9f, 3.5f, 0.8f); + Draw.reset(); + }), + + clusterShoot = new Effect(12, e -> { + Draw.color(Color.WHITE, lightOrange, e.ifract()); + Draw.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 10f, 2.5f, 0.7f); Draw.reset(); }), - shoot2 = new Effect(8, e -> { - Draw.thickness(1f); - Draw.color(Color.WHITE, Color.SKY, e.ifract()); - Draw.spikes(e.x, e.y, e.ifract() * 2f, 1, 5); + vulcanShoot = new Effect(8, e -> { + Draw.color(lighterOrange, lightOrange, e.ifract()); + Draw.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 10f, 2f, 0.7f); Draw.reset(); }), - shoot3 = new Effect(8, e -> { - Draw.thickness(1f); - Draw.color(Color.WHITE, Color.GOLD, e.ifract()); - Draw.spikes(e.x, e.y, e.ifract() * 2f, 1, 5); - Draw.reset(); - }), - - railshoot = new Effect(8, e -> { - Draw.thickness(2f - e.ifract()*2f); - Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract()); - Draw.spikes(e.x, e.y, 1f + e.ifract() * 4f, 1, 5); - Draw.reset(); - }), - - mortarshoot = new Effect(9, e -> { - Draw.thickness(1.3f - e.ifract()); + shockShoot = new Effect(8, e -> { Draw.color(Color.WHITE, Color.ORANGE, e.ifract()); - Draw.spikes(e.x, e.y, e.ifract() * 4f, 2, 6); - Draw.circle(e.x, e.y, e.ifract() * 5f + 1f); + Draw.lineShot(e.x, e.y, e.rotation, 3, e.fract(), 14f, 4f, 0.8f); Draw.reset(); }), - + + beamShoot = new Effect(8, e -> { + Draw.color(beamLight, beam, e.ifract()); + Draw.lineShot(e.x, e.y, e.rotation - 70, 3, e.fract(), 12f, 1f, 0.5f); + Draw.lineShot(e.x, e.y, e.rotation + 70, 3, e.fract(), 12f, 1f, 0.5f); + Draw.reset(); + }), + + beamhit = new Effect(8, e -> { + Draw.color(beamLight, beam, e.ifract()); + Draw.thick(e.fract()*3f+0.5f); + Draw.circle(e.x, e.y, e.ifract()*8f); + Draw.spikes(e.x, e.y, e.ifract()*6f, 2f, 4, 45); + Draw.reset(); + }), + titanExplosion = new Effect(11, 48f, e -> { Draw.thickness(2f*e.fract()+0.5f); Draw.color(Color.WHITE, Color.DARK_GRAY, e.powfract()); @@ -435,6 +448,14 @@ public class Fx{ Draw.reset(); }), + + clusterbomb = new Effect(10f, e -> { + Draw.color(Color.WHITE, lightOrange, e.ifract()); + Draw.thick(e.fract()*1.5f); + Draw.polygon(e.y, e.x, 4, e.fract()*8f); + Draw.circle(e.x, e.y, e.ifract()*14f); + Draw.reset(); + }), coreexplosion = new Effect(13, e -> { Draw.thickness(3f-e.ifract()*2f); @@ -457,10 +478,16 @@ public class Fx{ Draw.rect("circle", e.x, e.y, size, size); Draw.reset(); }), + + chainsmoke = new Effect(30, e -> { + Draw.color(lightGray); + float size = e.fract()*4f; + Draw.rect("circle", e.x, e.y, size, size); + Draw.reset(); + }), dashsmoke = new Effect(30, e -> { Draw.color(Color.CORAL, Color.GRAY, e.ifract()); - //Draw.alpha(e.fract()); float size = e.fract()*4f; Draw.rect("circle", e.x, e.y, size, size); Draw.reset(); @@ -472,13 +499,6 @@ public class Fx{ Draw.circle(e.x, e.y, 7f - e.ifract() * 6f); Draw.reset(); }), - - ind = new Effect(100, e -> { - Draw.thickness(3f); - Draw.color(Color.ROYAL); - Draw.circle(e.x, e.y, 3); - Draw.reset(); - }), respawn = new Effect(Vars.respawnduration, e -> { Draw.tcolor(Color.SCARLET); diff --git a/core/src/io/anuke/mindustry/graphics/Shaders.java b/core/src/io/anuke/mindustry/graphics/Shaders.java index 237ecd7170..eb26c012c4 100644 --- a/core/src/io/anuke/mindustry/graphics/Shaders.java +++ b/core/src/io/anuke/mindustry/graphics/Shaders.java @@ -16,7 +16,8 @@ public class Shaders{ public static class Outline extends Shader{ public Color color = new Color(); - + public float lighten = 0f; + public Outline(){ super("outline", "default"); } @@ -24,6 +25,7 @@ public class Shaders{ @Override public void apply(){ shader.setUniformf("u_color", color); + shader.setUniformf("u_lighten", lighten); shader.setUniformf("u_texsize", Tmp.v1.set(region.getTexture().getWidth(), region.getTexture().getHeight())); } diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 01f53a3651..3ac5f2c103 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.input; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.Vector2; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.resource.Weapon; @@ -80,8 +81,9 @@ public class DesktopInput extends InputHandler{ for(int i = 1; i <= 6 && i <= control.getWeapons().size; i ++){ if(Inputs.keyTap("weapon_" + i)){ - player.weapon = control.getWeapons().get(i - 1); - ui.weaponfrag.update(); + player.weaponLeft = player.weaponRight = control.getWeapons().get(i - 1); + Vars.netClient.handleWeaponSwitch(); + Vars.ui.hudfrag.updateWeapons(); } } diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 840e039c1f..a8529a7781 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -11,6 +11,7 @@ import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.Recipe; +import io.anuke.mindustry.resource.Recipes; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.SpawnPoint; import io.anuke.mindustry.world.Tile; @@ -241,7 +242,7 @@ public abstract class InputHandler extends InputAdapter{ Block block = tile.isLinked() ? tile.getLinked().block() : tile.block(); Recipe result = null; - for(Recipe recipe : Recipe.values()){ + for(Recipe recipe : Recipes.all()){ if(recipe.result == block){ result = recipe; break; diff --git a/core/src/io/anuke/mindustry/input/PlaceMode.java b/core/src/io/anuke/mindustry/input/PlaceMode.java index 7e664c7821..6b5a5f8f6a 100644 --- a/core/src/io/anuke/mindustry/input/PlaceMode.java +++ b/core/src/io/anuke/mindustry/input/PlaceMode.java @@ -101,7 +101,7 @@ public enum PlaceMode{ Draw.linecrect(tile.worldx() + offset.x, tile.worldy() + offset.y, tile.block().width * Vars.tilesize, tile.block().height * Vars.tilesize); }else if(android && control.getInput().breaktime > 0){ Draw.color(Colors.get("breakStart"), Colors.get("break"), fract); - Draw.polygon(25, tile.worldx() + offset.x, tile.worldy() + offset.y, 4 + (1f - fract) * 26); + Draw.polygon(tile.worldy() + offset.y, tile.worldx() + offset.x, 25, 4 + (1f - fract) * 26); } Draw.reset(); } diff --git a/core/src/io/anuke/mindustry/io/BundleGen.java b/core/src/io/anuke/mindustry/io/BundleGen.java index dc65da789e..95c33a6996 100644 --- a/core/src/io/anuke/mindustry/io/BundleGen.java +++ b/core/src/io/anuke/mindustry/io/BundleGen.java @@ -1,5 +1,6 @@ package io.anuke.mindustry.io; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; @@ -7,7 +8,6 @@ import io.anuke.mindustry.core.Tutorial; import io.anuke.mindustry.core.Tutorial.Stage; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Liquid; -import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.GameMode; import io.anuke.mindustry.world.Map; @@ -22,6 +22,17 @@ import io.anuke.ucore.util.Mathf; public class BundleGen { private static FileHandle file; + public static void cleanBundles(FileHandle file){ + String[] strings = file.readString().split("\n"); + FileHandle out = Gdx.files.absolute("/home/anuke/out.properties"); + out.writeString("", false); + for(String string : strings){ + if(!string.contains(".description")){ + out.writeString(string + "\n", true); + } + } + } + public static void buildBundle(FileHandle file){ BundleGen.file = file; @@ -47,10 +58,6 @@ public class BundleGen { for(GameMode mode : GameMode.values()){ write("mode." + mode.name() + ".name=" + mode.name()); } - for(Weapon weapon : Weapon.values()){ - write("weapon." + weapon.name() + ".name=" + weapon.name()); - write("weapon." + weapon.name() + ".description=" + weapon.description); - } for(Item item : Item.getAllItems()){ write("item." + item.name + ".name=" + item.name); } diff --git a/core/src/io/anuke/mindustry/io/NetworkIO.java b/core/src/io/anuke/mindustry/io/NetworkIO.java index 28008ca20c..db108fcbc3 100644 --- a/core/src/io/anuke/mindustry/io/NetworkIO.java +++ b/core/src/io/anuke/mindustry/io/NetworkIO.java @@ -154,7 +154,7 @@ public class NetworkIO { load(file.read()); } - //TODO GWT support + public static void load(InputStream is){ try(DataInputStream stream = new DataInputStream(is)){ @@ -187,7 +187,8 @@ public class NetworkIO { Vars.control.getWeapons().clear(); Vars.control.getWeapons().add(Weapon.blaster); - Vars.ui.weaponfrag.update(); + Vars.player.weaponLeft = Vars.player.weaponRight = Weapon.blaster; + Vars.ui.hudfrag.updateWeapons(); //enemies diff --git a/core/src/io/anuke/mindustry/io/versions/Save12.java b/core/src/io/anuke/mindustry/io/versions/Save12.java index 85a8410f11..73ff49cb84 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save12.java +++ b/core/src/io/anuke/mindustry/io/versions/Save12.java @@ -7,6 +7,7 @@ import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.resource.Item; +import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.BlockLoader; import io.anuke.mindustry.world.GameMode; @@ -60,15 +61,15 @@ public class Save12 extends SaveFileVersion { Vars.control.getWeapons().clear(); Vars.control.getWeapons().add(Weapon.blaster); - Vars.player.weapon = Weapon.blaster; + Vars.player.weaponLeft = Vars.player.weaponRight = Weapon.blaster; int weapons = stream.readByte(); for(int i = 0; i < weapons; i ++){ - Vars.control.addWeapon(Weapon.values()[stream.readByte()]); + Vars.control.addWeapon((Weapon)Upgrade.getByID(stream.readByte())); } - Vars.ui.weaponfrag.update(); + Vars.ui.hudfrag.updateWeapons(); //inventory @@ -194,7 +195,7 @@ public class Save12 extends SaveFileVersion { //start at 1, because the first weapon is always the starter - ignore that for(int i = 1; i < Vars.control.getWeapons().size; i ++){ - stream.writeByte(Vars.control.getWeapons().get(i).ordinal()); //weapon ordinal + stream.writeByte(Vars.control.getWeapons().get(i).id); //weapon ordinal } //--INVENTORY-- diff --git a/core/src/io/anuke/mindustry/io/versions/Save13.java b/core/src/io/anuke/mindustry/io/versions/Save13.java index ba4ccbee17..e42186efc3 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save13.java +++ b/core/src/io/anuke/mindustry/io/versions/Save13.java @@ -7,6 +7,7 @@ import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.resource.Item; +import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.blocks.Blocks; @@ -60,15 +61,15 @@ public class Save13 extends SaveFileVersion { Vars.control.getWeapons().clear(); Vars.control.getWeapons().add(Weapon.blaster); - Vars.player.weapon = Weapon.blaster; + Vars.player.weaponLeft = Vars.player.weaponRight = Weapon.blaster; int weapons = stream.readByte(); for(int i = 0; i < weapons; i ++){ - Vars.control.addWeapon(Weapon.values()[stream.readByte()]); + Vars.control.addWeapon((Weapon) Upgrade.getByID(stream.readByte())); } - Vars.ui.weaponfrag.update(); + Vars.ui.hudfrag.updateWeapons(); //inventory @@ -204,7 +205,7 @@ public class Save13 extends SaveFileVersion { //start at 1, because the first weapon is always the starter - ignore that for(int i = 1; i < Vars.control.getWeapons().size; i ++){ - stream.writeByte(Vars.control.getWeapons().get(i).ordinal()); //weapon ordinal + stream.writeByte(Vars.control.getWeapons().get(i).id); //weapon ordinal } //--INVENTORY-- diff --git a/core/src/io/anuke/mindustry/io/versions/Save14.java b/core/src/io/anuke/mindustry/io/versions/Save14.java index a17bb8a914..3db66332a0 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save14.java +++ b/core/src/io/anuke/mindustry/io/versions/Save14.java @@ -8,6 +8,7 @@ import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.resource.Item; +import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.GameMode; @@ -78,15 +79,15 @@ public class Save14 extends SaveFileVersion{ Vars.control.getWeapons().clear(); Vars.control.getWeapons().add(Weapon.blaster); - Vars.player.weapon = Weapon.blaster; + Vars.player.weaponLeft = Vars.player.weaponRight = Weapon.blaster; int weapons = stream.readByte(); for(int i = 0; i < weapons; i ++){ - Vars.control.addWeapon(Weapon.values()[stream.readByte()]); + Vars.control.addWeapon((Weapon) Upgrade.getByID(stream.readByte())); } - Vars.ui.weaponfrag.update(); + Vars.ui.hudfrag.updateWeapons(); //inventory @@ -232,7 +233,7 @@ public class Save14 extends SaveFileVersion{ //start at 1, because the first weapon is always the starter - ignore that for(int i = 1; i < Vars.control.getWeapons().size; i ++){ - stream.writeByte(Vars.control.getWeapons().get(i).ordinal()); //weapon ordinal + stream.writeByte(Vars.control.getWeapons().get(i).id); //weapon ordinal } //--INVENTORY-- diff --git a/core/src/io/anuke/mindustry/mapeditor/MapView.java b/core/src/io/anuke/mindustry/mapeditor/MapView.java index 911ece1cfd..92abf3543e 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapView.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapView.java @@ -238,9 +238,9 @@ public class MapView extends Element implements GestureListener{ Draw.thick(Unit.dp.scl(3f * zoom)); Draw.line(sx, sy, v2.x, v2.y); - Draw.polygon(40, sx, sy, editor.getBrushSize() * zoom * 3); + Draw.polygon(sy, sx, 40, editor.getBrushSize() * zoom * 3); - Draw.polygon(40, v2.x, v2.y, editor.getBrushSize() * zoom * 3); + Draw.polygon(v2.y, v2.x, 40, editor.getBrushSize() * zoom * 3); } batch.flush(); diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index cef7f1dcca..683ae483d6 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -116,6 +116,11 @@ public class Packets { } public static class UpgradePacket{ - public int id; //weapon ID only, currently + public byte id; //weapon ID only, currently + } + + public static class WeaponSwitchPacket{ + public int playerid; + public byte left, right; } } diff --git a/core/src/io/anuke/mindustry/net/Registrator.java b/core/src/io/anuke/mindustry/net/Registrator.java index 285adde428..baedb47bfe 100644 --- a/core/src/io/anuke/mindustry/net/Registrator.java +++ b/core/src/io/anuke/mindustry/net/Registrator.java @@ -35,6 +35,7 @@ public class Registrator { ChatPacket.class, KickPacket.class, UpgradePacket.class, + WeaponSwitchPacket.class, Class.class, byte[].class, diff --git a/core/src/io/anuke/mindustry/resource/Mech.java b/core/src/io/anuke/mindustry/resource/Mech.java index 7080cb7ec4..57a9bf4800 100644 --- a/core/src/io/anuke/mindustry/resource/Mech.java +++ b/core/src/io/anuke/mindustry/resource/Mech.java @@ -1,15 +1,11 @@ package io.anuke.mindustry.resource; -public enum Mech{ - standard, - scout{{ - - }}; - public float speedBoost = 1f, damageBoost = 1f; - public int regenRate = 10; - public int health = 20; +public class Mech extends Upgrade{ + public static final Mech - private Mech(){ - + standard = new Mech("standard"); + + public Mech(String name){ + super(name); } } diff --git a/core/src/io/anuke/mindustry/resource/Recipe.java b/core/src/io/anuke/mindustry/resource/Recipe.java index b2203cd380..9030f4ea34 100644 --- a/core/src/io/anuke/mindustry/resource/Recipe.java +++ b/core/src/io/anuke/mindustry/resource/Recipe.java @@ -1,114 +1,15 @@ package io.anuke.mindustry.resource; -import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.blocks.*; -import static io.anuke.mindustry.resource.Section.*; +public class Recipe { + public Block result; + public ItemStack[] requirements; + public Section section; -public enum Recipe{ - stonewall(defense, DefenseBlocks.stonewall, stack(Item.stone, 12)), - ironwall(defense, DefenseBlocks.ironwall, stack(Item.iron, 12)), - steelwall(defense, DefenseBlocks.steelwall, stack(Item.steel, 12)), - titaniumwall(defense, DefenseBlocks.titaniumwall, stack(Item.titanium, 12)), - duriumwall(defense, DefenseBlocks.diriumwall, stack(Item.dirium, 12)), - //compositewall(defense, DefenseBlocks.compositewall, stack(Item.dirium, 2), stack(Item.titanium, 2), stack(Item.steel, 2), stack(Item.iron, 2)), - steelwalllarge(defense, DefenseBlocks.steelwalllarge, stack(Item.steel, 12*4)), - titaniumwalllarge(defense, DefenseBlocks.titaniumwalllarge, stack(Item.titanium, 12*4)), - duriumwalllarge(defense, DefenseBlocks.diriumwalllarge, stack(Item.dirium, 12*4)), - door(defense, DefenseBlocks.door, stack(Item.steel, 3), stack(Item.iron, 3*4)), - largedoor(defense, DefenseBlocks.largedoor, stack(Item.steel, 3*4), stack(Item.iron, 3*4*4)), - titaniumshieldwall(defense, DefenseBlocks.titaniumshieldwall, stack(Item.titanium, 16)), - - conveyor(distribution, DistributionBlocks.conveyor, stack(Item.stone, 1)), - steelconveyor(distribution, DistributionBlocks.steelconveyor, stack(Item.steel, 1)), - poweredconveyor(distribution, DistributionBlocks.pulseconveyor, stack(Item.dirium, 1)), - router(distribution, DistributionBlocks.router, stack(Item.stone, 2)), - junction(distribution, DistributionBlocks.junction, stack(Item.iron, 2)), - tunnel(distribution, DistributionBlocks.tunnel, stack(Item.iron, 2)), - conduit(distribution, DistributionBlocks.conduit, stack(Item.steel, 1)), - pulseconduit(distribution, DistributionBlocks.pulseconduit, stack(Item.titanium, 1), stack(Item.steel, 1)), - liquidrouter(distribution, DistributionBlocks.liquidrouter, stack(Item.steel, 2)), - liquidjunction(distribution, DistributionBlocks.liquidjunction, stack(Item.steel, 2)), - sorter(distribution, DistributionBlocks.sorter, stack(Item.steel, 2)), - - turret(weapon, WeaponBlocks.turret, stack(Item.stone, 4)), - dturret(weapon, WeaponBlocks.doubleturret, stack(Item.stone, 7)), - machineturret(weapon, WeaponBlocks.machineturret, stack(Item.iron, 8), stack(Item.stone, 10)), - shotgunturret(weapon, WeaponBlocks.shotgunturret, stack(Item.iron, 10), stack(Item.stone, 10)), - flameturret(weapon, WeaponBlocks.flameturret, stack(Item.iron, 12), stack(Item.steel, 9)), - sniperturret(weapon, WeaponBlocks.sniperturret, stack(Item.iron, 15), stack(Item.steel, 10)), - laserturret(weapon, WeaponBlocks.laserturret, stack(Item.steel, 12), stack(Item.titanium, 12)), - mortarturret(weapon, WeaponBlocks.mortarturret, stack(Item.steel, 25), stack(Item.titanium, 15)), - teslaturret(weapon, WeaponBlocks.teslaturret, stack(Item.steel, 20), stack(Item.titanium, 25), stack(Item.dirium, 15)), - plasmaturret(weapon, WeaponBlocks.plasmaturret, stack(Item.steel, 10), stack(Item.titanium, 20), stack(Item.dirium, 15)), - chainturret(weapon, WeaponBlocks.chainturret, stack(Item.steel, 50), stack(Item.titanium, 25), stack(Item.dirium, 40)), - titanturret(weapon, WeaponBlocks.titanturret, stack(Item.steel, 70), stack(Item.titanium, 50), stack(Item.dirium, 55)), - - smelter(crafting, ProductionBlocks.smelter, stack(Item.stone, 40), stack(Item.iron, 40)), - crucible(crafting, ProductionBlocks.crucible, stack(Item.titanium, 40), stack(Item.steel, 40)), - coalpurifier(crafting, ProductionBlocks.coalpurifier, stack(Item.steel, 10), stack(Item.iron, 10)), - titaniumpurifier(crafting, ProductionBlocks.titaniumpurifier, stack(Item.steel, 30), stack(Item.iron, 30)), - oilrefinery(crafting, ProductionBlocks.oilrefinery, stack(Item.steel, 15), stack(Item.iron, 15)), - stoneformer(crafting, ProductionBlocks.stoneformer, stack(Item.steel, 10), stack(Item.iron, 10)), - lavasmelter(crafting, ProductionBlocks.lavasmelter, stack(Item.steel, 30), stack(Item.titanium, 15)), - - stonedrill(production, ProductionBlocks.stonedrill, stack(Item.stone, 12)), - irondrill(production, ProductionBlocks.irondrill, stack(Item.stone, 25)), - coaldrill(production, ProductionBlocks.coaldrill, stack(Item.stone, 25), stack(Item.iron, 40)), - titaniumdrill(production, ProductionBlocks.titaniumdrill, stack(Item.iron, 40), stack(Item.steel, 50)), - uraniumdrill(production, ProductionBlocks.uraniumdrill, stack(Item.iron, 40), stack(Item.steel, 40)), - omnidrill(production, ProductionBlocks.omnidrill, stack(Item.titanium, 30), stack(Item.dirium, 40)), - - coalgenerator(power, ProductionBlocks.coalgenerator, stack(Item.iron, 30), stack(Item.stone, 20)), - thermalgenerator(power, ProductionBlocks.thermalgenerator, stack(Item.steel, 30), stack(Item.iron, 30)), - combustiongenerator(power, ProductionBlocks.combustiongenerator, stack(Item.iron, 30), stack(Item.stone, 20)), - rtgenerator(power, ProductionBlocks.rtgenerator, stack(Item.titanium, 20), stack(Item.steel, 20)), - nuclearreactor(power, ProductionBlocks.nuclearReactor, stack(Item.titanium, 40), stack(Item.dirium, 40), stack(Item.steel, 50)), - powerbooster(power, DistributionBlocks.powerbooster, stack(Item.steel, 8), stack(Item.iron, 8)), - powerlaser(power, DistributionBlocks.powerlaser, stack(Item.steel, 3), stack(Item.iron, 3)), - powerlasercorner(power, DistributionBlocks.powerlasercorner, stack(Item.steel, 4), stack(Item.iron, 4)), - powerlaserrouter(power, DistributionBlocks.powerlaserrouter, stack(Item.steel, 5), stack(Item.iron, 5)), - - shieldgenerator(power, DefenseBlocks.shieldgenerator, stack(Item.titanium, 30), stack(Item.dirium, 30)), - - teleporter(distribution, DistributionBlocks.teleporter, stack(Item.steel, 20), stack(Item.dirium, 15)), - - healturret(power, DefenseBlocks.repairturret, stack(Item.iron, 30)), - megahealturret(power, DefenseBlocks.megarepairturret, stack(Item.iron, 20), stack(Item.steel, 30)), - - pump(production, ProductionBlocks.pump, stack(Item.steel, 10)), - fluxpump(production, ProductionBlocks.fluxpump, stack(Item.steel, 10), stack(Item.dirium, 5)); - - public Block result; - public ItemStack[] requirements; - public Section section; - - private Recipe(Section section, Block result, ItemStack... requirements){ - this.result = result; - this.requirements = requirements; - this.section = section; - } - - private static ItemStack stack(Item item, int amount){ - return new ItemStack(item, amount); - } - - public static Recipe getByResult(Block block){ - for(Recipe recipe : Recipe.values()){ - if(recipe.result == block){ - return recipe; - } - } - return null; - } - - public static Array getBy(Section section, Array r){ - for(Recipe recipe : Recipe.values()){ - if(recipe.section == section) - r.add(recipe); - } - - return r; - } + public Recipe(Section section, Block result, ItemStack... requirements){ + this.result = result; + this.requirements = requirements; + this.section = section; + } } diff --git a/core/src/io/anuke/mindustry/resource/Recipes.java b/core/src/io/anuke/mindustry/resource/Recipes.java new file mode 100644 index 0000000000..c6542dfe97 --- /dev/null +++ b/core/src/io/anuke/mindustry/resource/Recipes.java @@ -0,0 +1,113 @@ +package io.anuke.mindustry.resource; + +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.blocks.DefenseBlocks; +import io.anuke.mindustry.world.blocks.DistributionBlocks; +import io.anuke.mindustry.world.blocks.ProductionBlocks; +import io.anuke.mindustry.world.blocks.WeaponBlocks; + +import static io.anuke.mindustry.resource.Section.*; + +public class Recipes { + private static final Array list = Array.with( + new Recipe(defense, DefenseBlocks.stonewall, stack(Item.stone, 12)), + new Recipe(defense, DefenseBlocks.ironwall, stack(Item.iron, 12)), + new Recipe(defense, DefenseBlocks.steelwall, stack(Item.steel, 12)), + new Recipe(defense, DefenseBlocks.titaniumwall, stack(Item.titanium, 12)), + new Recipe(defense, DefenseBlocks.diriumwall, stack(Item.dirium, 12)), + new Recipe(defense, DefenseBlocks.steelwalllarge, stack(Item.steel, 12*4)), + new Recipe(defense, DefenseBlocks.titaniumwalllarge, stack(Item.titanium, 12*4)), + new Recipe(defense, DefenseBlocks.diriumwalllarge, stack(Item.dirium, 12*4)), + new Recipe(defense, DefenseBlocks.door, stack(Item.steel, 3), stack(Item.iron, 3*4)), + new Recipe(defense, DefenseBlocks.largedoor, stack(Item.steel, 3*4), stack(Item.iron, 3*4*4)), + new Recipe(defense, DefenseBlocks.titaniumshieldwall, stack(Item.titanium, 16)), + + new Recipe(distribution, DistributionBlocks.conveyor, stack(Item.stone, 1)), + new Recipe(distribution, DistributionBlocks.steelconveyor, stack(Item.steel, 1)), + new Recipe(distribution, DistributionBlocks.pulseconveyor, stack(Item.dirium, 1)), + new Recipe(distribution, DistributionBlocks.router, stack(Item.stone, 2)), + new Recipe(distribution, DistributionBlocks.junction, stack(Item.iron, 2)), + new Recipe(distribution, DistributionBlocks.tunnel, stack(Item.iron, 2)), + new Recipe(distribution, DistributionBlocks.conduit, stack(Item.steel, 1)), + new Recipe(distribution, DistributionBlocks.pulseconduit, stack(Item.titanium, 1), stack(Item.steel, 1)), + new Recipe(distribution, DistributionBlocks.liquidrouter, stack(Item.steel, 2)), + new Recipe(distribution, DistributionBlocks.liquidjunction, stack(Item.steel, 2)), + new Recipe(distribution, DistributionBlocks.sorter, stack(Item.steel, 2)), + + new Recipe(weapon, WeaponBlocks.turret, stack(Item.stone, 4)), + new Recipe(weapon, WeaponBlocks.doubleturret, stack(Item.stone, 7)), + new Recipe(weapon, WeaponBlocks.machineturret, stack(Item.iron, 8), stack(Item.stone, 10)), + new Recipe(weapon, WeaponBlocks.shotgunturret, stack(Item.iron, 10), stack(Item.stone, 10)), + new Recipe(weapon, WeaponBlocks.flameturret, stack(Item.iron, 12), stack(Item.steel, 9)), + new Recipe(weapon, WeaponBlocks.sniperturret, stack(Item.iron, 15), stack(Item.steel, 10)), + new Recipe(weapon, WeaponBlocks.laserturret, stack(Item.steel, 12), stack(Item.titanium, 12)), + new Recipe(weapon, WeaponBlocks.mortarturret, stack(Item.steel, 25), stack(Item.titanium, 15)), + new Recipe(weapon, WeaponBlocks.teslaturret, stack(Item.steel, 20), stack(Item.titanium, 25), stack(Item.dirium, 15)), + new Recipe(weapon, WeaponBlocks.plasmaturret, stack(Item.steel, 10), stack(Item.titanium, 20), stack(Item.dirium, 15)), + new Recipe(weapon, WeaponBlocks.chainturret, stack(Item.steel, 50), stack(Item.titanium, 25), stack(Item.dirium, 40)), + new Recipe(weapon, WeaponBlocks.titanturret, stack(Item.steel, 70), stack(Item.titanium, 50), stack(Item.dirium, 55)), + + new Recipe(crafting, ProductionBlocks.smelter, stack(Item.stone, 40), stack(Item.iron, 40)), + new Recipe(crafting, ProductionBlocks.crucible, stack(Item.titanium, 40), stack(Item.steel, 40)), + new Recipe(crafting, ProductionBlocks.coalpurifier, stack(Item.steel, 10), stack(Item.iron, 10)), + new Recipe(crafting, ProductionBlocks.titaniumpurifier, stack(Item.steel, 30), stack(Item.iron, 30)), + new Recipe(crafting, ProductionBlocks.oilrefinery, stack(Item.steel, 15), stack(Item.iron, 15)), + new Recipe(crafting, ProductionBlocks.stoneformer, stack(Item.steel, 10), stack(Item.iron, 10)), + new Recipe(crafting, ProductionBlocks.lavasmelter, stack(Item.steel, 30), stack(Item.titanium, 15)), + new Recipe(crafting, ProductionBlocks.weaponFactory, stack(Item.steel, 60), stack(Item.iron, 60)), + + new Recipe(production, ProductionBlocks.stonedrill, stack(Item.stone, 12)), + new Recipe(production, ProductionBlocks.irondrill, stack(Item.stone, 25)), + new Recipe(production, ProductionBlocks.coaldrill, stack(Item.stone, 25), stack(Item.iron, 40)), + new Recipe(production, ProductionBlocks.titaniumdrill, stack(Item.iron, 40), stack(Item.steel, 50)), + new Recipe(production, ProductionBlocks.uraniumdrill, stack(Item.iron, 40), stack(Item.steel, 40)), + new Recipe(production, ProductionBlocks.omnidrill, stack(Item.titanium, 30), stack(Item.dirium, 40)), + + new Recipe(power, ProductionBlocks.coalgenerator, stack(Item.iron, 30), stack(Item.stone, 20)), + new Recipe(power, ProductionBlocks.thermalgenerator, stack(Item.steel, 30), stack(Item.iron, 30)), + new Recipe(power, ProductionBlocks.combustiongenerator, stack(Item.iron, 30), stack(Item.stone, 20)), + new Recipe(power, ProductionBlocks.rtgenerator, stack(Item.titanium, 20), stack(Item.steel, 20)), + new Recipe(power, ProductionBlocks.nuclearReactor, stack(Item.titanium, 40), stack(Item.dirium, 40), stack(Item.steel, 50)), + new Recipe(power, DistributionBlocks.powerbooster, stack(Item.steel, 8), stack(Item.iron, 8)), + new Recipe(power, DistributionBlocks.powerlaser, stack(Item.steel, 3), stack(Item.iron, 3)), + new Recipe(power, DistributionBlocks.powerlasercorner, stack(Item.steel, 4), stack(Item.iron, 4)), + new Recipe(power, DistributionBlocks.powerlaserrouter, stack(Item.steel, 5), stack(Item.iron, 5)), + + new Recipe(power, DefenseBlocks.shieldgenerator, stack(Item.titanium, 30), stack(Item.dirium, 30)), + + new Recipe(distribution, DistributionBlocks.teleporter, stack(Item.steel, 20), stack(Item.dirium, 15)), + + new Recipe(power, DefenseBlocks.repairturret, stack(Item.iron, 30)), + new Recipe(power, DefenseBlocks.megarepairturret, stack(Item.iron, 20), stack(Item.steel, 30)), + + new Recipe(production, ProductionBlocks.pump, stack(Item.steel, 10)), + new Recipe(production, ProductionBlocks.fluxpump, stack(Item.steel, 10), stack(Item.dirium, 5)) + ); + + private static ItemStack stack(Item item, int amount){ + return new ItemStack(item, amount); + } + + public static Array all(){ + return list; + } + + public static Recipe getByResult(Block block){ + for(Recipe recipe : list){ + if(recipe.result == block){ + return recipe; + } + } + return null; + } + + public static Array getBy(Section section, Array r){ + for(Recipe recipe : list){ + if(recipe.section == section) + r.add(recipe); + } + + return r; + } +} diff --git a/core/src/io/anuke/mindustry/resource/Upgrade.java b/core/src/io/anuke/mindustry/resource/Upgrade.java new file mode 100644 index 0000000000..423528a483 --- /dev/null +++ b/core/src/io/anuke/mindustry/resource/Upgrade.java @@ -0,0 +1,33 @@ +package io.anuke.mindustry.resource; + +import com.badlogic.gdx.utils.Array; +import io.anuke.ucore.util.Bundles; + +public abstract class Upgrade { + private static Array upgrades = new Array<>(); + private static byte lastid; + + public final byte id; + public final String name; + public final String description; + + public Upgrade(String name){ + this.id = lastid ++; + this.name = name; + this.description = Bundles.getNotNull("upgrade."+name+".description"); + + upgrades.add(this); + } + + public String localized(){ + return Bundles.get("upgrade." + name + ".name"); + } + + public static Upgrade getByID(byte id){ + return upgrades.get(id); + } + + public static Array getAllUpgrades() { + return upgrades; + } +} diff --git a/core/src/io/anuke/mindustry/resource/UpgradeRecipes.java b/core/src/io/anuke/mindustry/resource/UpgradeRecipes.java new file mode 100644 index 0000000000..a3854e9e58 --- /dev/null +++ b/core/src/io/anuke/mindustry/resource/UpgradeRecipes.java @@ -0,0 +1,33 @@ +package io.anuke.mindustry.resource; + +import com.badlogic.gdx.utils.ObjectMap; +import com.badlogic.gdx.utils.ObjectMap.Entries; +import io.anuke.ucore.util.Mathf; + +public class UpgradeRecipes { + private static final ObjectMap recipes = Mathf.map( + Weapon.triblaster, list(stack(Item.iron, 40), stack(Item.steel, 40)), + Weapon.clustergun, list(stack(Item.iron, 60), stack(Item.steel, 80)), + Weapon.vulcan, list(stack(Item.iron, 60), stack(Item.steel, 120), stack(Item.titanium, 60)), + Weapon.beam, list(stack(Item.steel, 240), stack(Item.titanium, 120), stack(Item.dirium, 80)), + Weapon.shockgun, list(stack(Item.steel, 120), stack(Item.titanium, 120), stack(Item.dirium, 120)) + ); + + private static final ItemStack[] empty = {}; + + public static ItemStack[] get(Upgrade upgrade){ + return recipes.get(upgrade, empty); + } + + public static Entries getAllRecipes(){ + return recipes.entries(); + } + + private static ItemStack[] list(ItemStack... stacks){ + return stacks; + } + + private static ItemStack stack(Item item, int amount){ + return new ItemStack(item, amount); + } +} diff --git a/core/src/io/anuke/mindustry/resource/Weapon.java b/core/src/io/anuke/mindustry/resource/Weapon.java index 57a199347d..ca0ed72f84 100644 --- a/core/src/io/anuke/mindustry/resource/Weapon.java +++ b/core/src/io/anuke/mindustry/resource/Weapon.java @@ -1,8 +1,5 @@ package io.anuke.mindustry.resource; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.BulletType; @@ -10,106 +7,105 @@ import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.net.Net; import io.anuke.ucore.core.Effects; +import io.anuke.ucore.core.Effects.Effect; +import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.Entity; -import io.anuke.ucore.util.Bundles; +import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; -public enum Weapon{ - blaster(15, BulletType.shot){ +public class Weapon extends Upgrade{ + public static final Weapon + + blaster = new Weapon("blaster", 12, BulletType.shot){ { - unlocked = true; - } - - @Override - public void shootInternal(Player p, float x, float y, float rotation){ - super.shootInternal(p, x, y, rotation); - Effects.effect(Fx.shoot3, x + vector.x, y+vector.y); + effect = Fx.laserShoot; } }, - triblaster(13, BulletType.shot, stack(Item.iron, 40)){ - - @Override - public void shootInternal(Player p, float x, float y, float rotation){ - float space = 12; - - bullet(p, x, y, rotation); - bullet(p, x, y, rotation + space); - bullet(p, x, y, rotation - space); - - Effects.effect(Fx.shoot, x + vector.x, y + vector.y); - - } - }, - multigun(6, BulletType.multishot, stack(Item.iron, 60), stack(Item.steel, 20)){ - @Override - public void shootInternal(Player p, float x, float y, float rotation){ - MathUtils.random.setSeed(Gdx.graphics.getFrameId()); - - bullet(p, x, y, rotation + Mathf.range(8)); - - Effects.effect(Fx.shoot2, x + vector.x, y + vector.y); - } - }, - flamer(5, BulletType.flame, stack(Item.steel, 60), stack(Item.iron, 120)){ - + triblaster = new Weapon("triblaster", 20, BulletType.spread){ { - shootsound = "flame2"; - } - - @Override - public void shootInternal(Player p, float x, float y, float rotation){ - MathUtils.random.setSeed(Gdx.graphics.getFrameId()); - - bullet(p, x, y, rotation + Mathf.range(12)); + shots = 3; + effect = Fx.spreadShoot; + roundrobin = true; } }, - railgun(40, BulletType.sniper, stack(Item.steel, 60), stack(Item.iron, 60)){ - + clustergun = new Weapon("clustergun", 26f, BulletType.cluster){ { - shootsound = "railgun"; - } - - @Override - public void shootInternal(Player p, float x, float y, float rotation){ - bullet(p, x, y, rotation); - Effects.effect(Fx.railshoot, x + vector.x, y + vector.y); + effect = Fx.clusterShoot; + inaccuracy = 20f; + roundrobin = true; + shots = 2; + spacing = 0; } }, - mortar(100, BulletType.shell, stack(Item.titanium, 40), stack(Item.steel, 60)){ - + beam = new Weapon("beam", 30f, BulletType.beamlaser){ + { + effect = Fx.beamShoot; + inaccuracy = 0; + roundrobin = true; + shake = 2f; + } + }, + vulcan = new Weapon("vulcan", 5, BulletType.vulcan){ + { + effect = Fx.vulcanShoot; + inaccuracy = 5; + roundrobin = true; + shake = 1f; + inaccuracy = 4f; + } + }, + shockgun = new Weapon("shockgun", 36, BulletType.shockshell){ { shootsound = "bigshot"; - } - - @Override - public void shootInternal(Player p, float x, float y, float rotation){ - bullet(p, x, y, rotation); - Effects.effect(Fx.mortarshoot, x + vector.x, y + vector.y); - Effects.shake(2f, 2f, p); + effect = Fx.shockShoot; + shake = 2f; + roundrobin = true; + shots = 7; + inaccuracy = 15f; } }; - public float reload; - public BulletType type; - public String shootsound = "shoot"; - public boolean unlocked; - public ItemStack[] requirements; - public final String description; - - Vector2 vector = new Vector2(); - - public String localized(){ - return Bundles.get("weapon."+name() + ".name"); - } + /**weapon reload in frames*/ + float reload; + /**type of bullet shot*/ + BulletType type; + /**sound made when shooting*/ + String shootsound = "shoot"; + /**amount of shots per fire*/ + int shots = 1; + /**spacing in degrees between multiple shots, if applicable*/ + float spacing = 12f; + /**inaccuracy of degrees of each shot*/ + float inaccuracy = 0f; + /**intensity and duration of each shot's screen shake*/ + float shake = 0f; + /**effect displayed when shooting*/ + Effect effect; + /**whether to shoot the weapons in different arms one after another, rather an all at once*/ + boolean roundrobin = false; - private Weapon(float reload, BulletType type, ItemStack... requirements){ + private Weapon(String name, float reload, BulletType type){ + super(name); this.reload = reload; this.type = type; - this.requirements = requirements; - this.description = Bundles.getNotNull("weapon."+name()+".description"); + } + + public void update(Player p, boolean left){ + if(Timers.get(p, "reload"+left, reload)){ + if(roundrobin){ + Timers.reset(p, "reload" + !left, reload/2f); + } + float ang = Angles.mouseAngle(p.x, p.y); + Angles.translation(ang + Mathf.sign(left) * -60f, 3f); + shoot(p, p.x + Angles.x(), p.y + Angles.y(), Angles.mouseAngle(p.x + Angles.x(), p.y + Angles.y())); + } } void shootInternal(Player p, float x, float y, float rotation){ - bullet(p, x, y, rotation); + Angles.shotgun(shots, spacing, rotation, f -> bullet(p, x, y, f + Mathf.range(inaccuracy))); + Angles.translation(rotation, 3f); + if(effect != null) Effects.effect(effect, x + Angles.x(), y + Angles.y(), rotation); + Effects.shake(shake, shake, x, y); + Effects.sound(shootsound, x, y); } public void shoot(Player p, float x, float y, float angle){ @@ -121,11 +117,7 @@ public enum Weapon{ } void bullet(Entity owner, float x, float y, float angle){ - vector.set(3, 0).rotate(angle); - new Bullet(type, owner, x + vector.x, y + vector.y, angle).add(); - } - - private static ItemStack stack(Item item, int amount){ - return new ItemStack(item, amount); + Angles.translation(angle, 3f); + new Bullet(type, owner, x + Angles.x(), y + Angles.y(), angle).add(); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/UpgradeDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/UpgradeDialog.java deleted file mode 100644 index 8000210ee4..0000000000 --- a/core/src/io/anuke/mindustry/ui/dialogs/UpgradeDialog.java +++ /dev/null @@ -1,144 +0,0 @@ -package io.anuke.mindustry.ui.dialogs; - - -import com.badlogic.gdx.graphics.Color; -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.core.GameState; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.resource.ItemStack; -import io.anuke.mindustry.resource.Weapon; -import io.anuke.ucore.core.Draw; -import io.anuke.ucore.core.Effects; -import io.anuke.ucore.function.Listenable; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.TextButton; -import io.anuke.ucore.scene.ui.Tooltip; -import io.anuke.ucore.scene.ui.layout.Table; - -import static io.anuke.mindustry.Vars.control; -import static io.anuke.mindustry.Vars.ui; - -public class UpgradeDialog extends FloatingDialog{ - boolean wasPaused = false; - - public UpgradeDialog() { - super("$text.upgrades"); - setup(); - } - - void setup(){ - addCloseButton(); - - hidden(()->{ - if(!wasPaused) - GameState.set(State.playing); - }); - shown(()->{ - wasPaused = GameState.is(State.paused); - GameState.set(State.paused); - }); - - Table weptab = new Table(); - weptab.margin(20); - - int i = 0; - for(Weapon weapon : Weapon.values()){ - TextButton button = new TextButton("$weapon."+weapon.name()+".name"); - - Image img = new Image(Draw.region(weapon.name())); - button.add(img).size(8*5); - button.getCells().reverse(); - button.row(); - button.margin(14); - button.getLabelCell().left(); - button.pack(); - - button.update(()->{ - if(control.hasWeapon(weapon)){ - button.setDisabled(true); - button.setColor(Color.GRAY); - }else if(!control.hasItems(weapon.requirements)){ - button.setDisabled(true); - }else{ - button.setDisabled(false); - button.setColor(Color.WHITE); - } - }); - - if(i > 0 && (i)%2==0) - weptab.row(); - - i++; - - weptab.add(button).width(220); - - Table tiptable = new Table(); - - Listenable run = ()->{ - tiptable.clearChildren(); - - String description = weapon.description; - - tiptable.background("pane"); - tiptable.add("[orange]" + weapon.localized(), 0.5f).left().padBottom(4f); - - Table reqtable = new Table(); - - tiptable.row(); - tiptable.add(reqtable).left(); - - if(!control.hasWeapon(weapon)){ - ItemStack[] req = weapon.requirements; - for(ItemStack s : req){ - - int amount = Math.min(control.getAmount(s.item), s.amount); - reqtable.addImage(Draw.region("icon-" + s.item.name)).padRight(3).size(8*2); - reqtable.add( - (amount >= s.amount ? "" : "[RED]") - + amount + " / " +s.amount, 0.5f).left(); - reqtable.row(); - } - } - - tiptable.row(); - tiptable.add().size(10); - tiptable.row(); - tiptable.add("[gray]" + description).left(); - tiptable.row(); - if(control.hasWeapon(weapon)){ - tiptable.add("$text.purchased").padTop(6).left(); - } - tiptable.margin(14f); - }; - - run.listen(); - - Tooltip tip = new Tooltip<>(tiptable, run); - - tip.setInstant(true); - - button.addListener(tip); - - button.clicked(()->{ - if(button.isDisabled()) return; - - control.removeItems(weapon.requirements); - control.addWeapon(weapon); - ui.weaponfrag.update(); - run.listen(); - Effects.sound("purchase"); - - if(Net.active() && Net.client()){ - Vars.netClient.handleUpgrade(weapon); - } - }); - } - - content().add("$text.weapons"); - content().row(); - content().add(weptab); - content().row(); - } - -} diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java index 009f549e0e..f493f0e347 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java @@ -23,6 +23,14 @@ public class BlockConfigFragment implements Fragment { Core.scene.add(table); } + public boolean isShown(){ + return table.isVisible() && configTile != null; + } + + public Tile getSelectedTile(){ + return configTile; + } + public void showConfig(Tile tile){ configTile = tile; @@ -35,7 +43,7 @@ public class BlockConfigFragment implements Fragment { table.update(()->{ table.setOrigin(Align.center); - Vector2 pos = Graphics.screen(tile.worldx(), tile.worldy()); + Vector2 pos = Graphics.screen(tile.worldx() + tile.block().getPlaceOffset().x, tile.worldy() + tile.block().getPlaceOffset().y); table.setPosition(pos.x, pos.y, Align.center); if(configTile == null || configTile.block() == Blocks.air){ hideConfig(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index 3c23a3ca78..24fd7598cd 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -9,10 +9,7 @@ import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.input.InputHandler; -import io.anuke.mindustry.resource.Item; -import io.anuke.mindustry.resource.ItemStack; -import io.anuke.mindustry.resource.Recipe; -import io.anuke.mindustry.resource.Section; +import io.anuke.mindustry.resource.*; import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.ucore.core.Draw; import io.anuke.ucore.graphics.Hue; @@ -30,7 +27,7 @@ import static io.anuke.mindustry.Vars.control; import static io.anuke.mindustry.Vars.fontscale; public class BlocksFragment implements Fragment{ - private Table desctable, itemtable, blocks; + private Table desctable, itemtable, blocks, weapons; private Stack stack = new Stack(); private Array statlist = new Array<>(); private boolean shown = true; @@ -72,17 +69,17 @@ public class BlocksFragment implements Fragment{ Stack stack = new Stack(); ButtonGroup group = new ButtonGroup<>(); - Array recipes = new Array(); + Array recipes = new Array<>(); for (Section sec : Section.values()) { recipes.clear(); - Recipe.getBy(sec, recipes); + Recipes.getBy(sec, recipes); maxcol = Math.max((int) ((float) recipes.size / rows + 1), maxcol); } for (Section sec : Section.values()) { recipes.clear(); - Recipe.getBy(sec, recipes); + Recipes.getBy(sec, recipes); Table table = new Table(); @@ -93,7 +90,7 @@ public class BlocksFragment implements Fragment{ } }); button.setName("sectionbutton" + sec.name()); - add(button).growX().height(54).padRight(-1).padTop(sec.ordinal() <= 2 ? -10 : -5); + add(button).growX().height(54).padLeft(-1).padTop(sec.ordinal() <= 2 ? -10 : -5); button.getImageCell().size(40).padBottom(4).padTop(2); group.add(button); @@ -147,16 +144,47 @@ public class BlocksFragment implements Fragment{ add(stack).colspan(Section.values().length); margin(10f); - marginLeft(0f); - marginRight(0f); + marginLeft(1f); + marginRight(1f); end(); }}.right().bottom().uniformX(); + row(); + + if(!Vars.android) { + weapons = new table("button").margin(0).fillX().end().get(); + } + visible(() -> !GameState.is(State.menu) && shown); }}.end().get(); }}.end(); + + updateWeapons(); + } + + public void updateWeapons(){ + if(Vars.android) return; + + weapons.clearChildren(); + weapons.left(); + + ButtonGroup group = new ButtonGroup<>(); + + for(int i = 0; i < Vars.control.getWeapons().size; i ++){ + Weapon weapon = Vars.control.getWeapons().get(i); + weapons.addImageButton(weapon.name, "toggle", 8*3, () -> { + Vars.player.weaponLeft = Vars.player.weaponRight = weapon; + }).left().size(40f, 45f).padRight(-1).group(group); + } + + int idx = Vars.control.getWeapons().indexOf(Vars.player.weaponLeft, true); + + if(idx != -1) + group.getButtons().get(idx).setChecked(true); + else if(group.getButtons().size > 0) + group.getButtons().get(0).setChecked(true); } public void toggle(boolean show, float t, Interpolation ip){ @@ -244,7 +272,6 @@ public class BlocksFragment implements Fragment{ }).expandX().padLeft(3).top().right().size(40f, 44f).padTop(-2); } - desctable.add().pad(2); Table requirements = new Table(); @@ -255,12 +282,11 @@ public class BlocksFragment implements Fragment{ desctable.left(); for(ItemStack stack : recipe.requirements){ - ItemStack fs = stack; requirements.addImage(Draw.region("icon-"+stack.item.name)).size(8*3); Label reqlabel = new Label(""); reqlabel.update(()->{ - int current = control.getAmount(fs.item); + int current = control.getAmount(stack.item); String text = Mathf.clamp(current, 0, stack.amount) + "/" + stack.amount; reqlabel.setColor(current < stack.amount ? Colors.get("missingitems") : Color.WHITE); @@ -274,8 +300,7 @@ public class BlocksFragment implements Fragment{ desctable.row(); - Label label = new Label("[health]"+ Bundles.get("text.health")+": " + recipe.result.health + (recipe.result.description == null ? - "" : ("\n[]" + recipe.result.description))); + Label label = new Label("[health]"+ Bundles.get("text.health")+": " + recipe.result.health); label.setWrap(true); desctable.add(label).width(200).padTop(4).padBottom(2); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 08a9d7693c..ddc20f59e0 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -219,6 +219,10 @@ public class HudFragment implements Fragment{ public void updateItems(){ blockfrag.updateItems(); } + + public void updateWeapons(){ + blockfrag.updateWeapons(); + } public void fadeRespawn(boolean in){ respawntable.addAction(Actions.color(in ? new Color(0, 0, 0, 0.3f) : Color.CLEAR, 0.3f)); diff --git a/core/src/io/anuke/mindustry/ui/fragments/WeaponFragment.java b/core/src/io/anuke/mindustry/ui/fragments/WeaponFragment.java deleted file mode 100644 index 3d69f44ee1..0000000000 --- a/core/src/io/anuke/mindustry/ui/fragments/WeaponFragment.java +++ /dev/null @@ -1,71 +0,0 @@ -package io.anuke.mindustry.ui.fragments; - -import io.anuke.mindustry.core.GameState; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.resource.Weapon; -import io.anuke.ucore.core.Core; -import io.anuke.ucore.core.Draw; -import io.anuke.ucore.scene.ui.ButtonGroup; -import io.anuke.ucore.scene.ui.ImageButton; -import io.anuke.ucore.scene.ui.Tooltip; -import io.anuke.ucore.scene.ui.layout.Table; - -import static io.anuke.mindustry.Vars.*; - -public class WeaponFragment implements Fragment{ - Table weapontable; - - public void build(){ - weapontable = Core.scene.table(); - weapontable.bottom().left(); - weapontable.setVisible(()-> !GameState.is(State.menu)); - - if(android){ - weapontable.remove(); - } - } - - public void update(){ - weapontable.clearChildren(); - - ButtonGroup group = new ButtonGroup<>(); - - weapontable.defaults().size(58, 62); - - for(Weapon weapon : control.getWeapons()){ - ImageButton button = new ImageButton(Draw.region(weapon.name()), "toggle"); - button.getImageCell().size(8*5); - - group.add(button); - - button.clicked(()->{ - if(weapon == player.weapon) return; - player.weapon = weapon; - button.setChecked(true); - }); - - button.setChecked(weapon == player.weapon); - - weapontable.add(button); - - Table tiptable = new Table(); - String description = weapon.description; - - tiptable.background("button"); - tiptable.add("$weapon."+weapon.name()+".name", 0.5f).left().padBottom(3f); - - tiptable.row(); - tiptable.row(); - tiptable.add("[GRAY]" + description).left(); - tiptable.margin(14f); - - Tooltip
tip = new Tooltip<>(tiptable); - - tip.setInstant(true); - - button.addListener(tip); - } - - weapontable.addImageButton("icon-menu", 8*4, ui.upgrades::show); - } -} diff --git a/core/src/io/anuke/mindustry/world/blocks/DefenseBlocks.java b/core/src/io/anuke/mindustry/world/blocks/DefenseBlocks.java index 36b4328908..67b24c60f8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/DefenseBlocks.java +++ b/core/src/io/anuke/mindustry/world/blocks/DefenseBlocks.java @@ -50,7 +50,7 @@ public class DefenseBlocks{ repairturret = new RepairTurret("repairturret"){ { range = 30; - reload = 60f; + reload = 40f; health = 60; powerUsed = 0.08f; } @@ -59,7 +59,7 @@ public class DefenseBlocks{ megarepairturret = new RepairTurret("megarepairturret"){ { range = 44; - reload = 30f; + reload = 20f; health = 90; powerUsed = 0.13f; } diff --git a/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java b/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java index b81afdd768..159de661e1 100644 --- a/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java +++ b/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java @@ -199,5 +199,10 @@ public class ProductionBlocks{ health = 600; breaktime *= 2.3f; } + }, + weaponFactory = new WeaponFactory("weaponfactory"){ + { + width = height = 2; + } }; } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/production/WeaponFactory.java b/core/src/io/anuke/mindustry/world/blocks/types/production/WeaponFactory.java new file mode 100644 index 0000000000..170785f90d --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/types/production/WeaponFactory.java @@ -0,0 +1,109 @@ +package io.anuke.mindustry.world.blocks.types.production; + +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.resource.ItemStack; +import io.anuke.mindustry.resource.Upgrade; +import io.anuke.mindustry.resource.UpgradeRecipes; +import io.anuke.mindustry.resource.Weapon; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.types.Configurable; +import io.anuke.ucore.core.Draw; +import io.anuke.ucore.core.Effects; +import io.anuke.ucore.function.Listenable; +import io.anuke.ucore.scene.style.TextureRegionDrawable; +import io.anuke.ucore.scene.ui.ImageButton; +import io.anuke.ucore.scene.ui.Tooltip; +import io.anuke.ucore.scene.ui.layout.Table; + +import static io.anuke.mindustry.Vars.control; + +public class WeaponFactory extends Block implements Configurable{ + + public WeaponFactory(String name){ + super(name); + solid = true; + destructible = true; + } + + @Override + public void buildTable(Tile tile, Table table) { + int i = 0; + + Table content = new Table(); + + for(Upgrade upgrade : Upgrade.getAllUpgrades()){ + if(!(upgrade instanceof Weapon)) continue; + Weapon weapon = (Weapon)upgrade; + + ItemStack[] requirements = UpgradeRecipes.get(weapon); + + Table tiptable = new Table(); + + Listenable run = ()->{ + tiptable.clearChildren(); + + String description = weapon.description; + + tiptable.background("pane"); + tiptable.add("[orange]" + weapon.localized(), 0.5f).left().padBottom(2f); + + Table reqtable = new Table(); + + tiptable.row(); + tiptable.add(reqtable).left(); + + if(!control.hasWeapon(weapon)){ + for(ItemStack s : requirements){ + + int amount = Math.min(control.getAmount(s.item), s.amount); + reqtable.addImage(Draw.region("icon-" + s.item.name)).padRight(3).size(8*2); + reqtable.add( + (amount >= s.amount ? "" : "[RED]") + + amount + " / " +s.amount, 0.5f).left(); + reqtable.row(); + } + } + + tiptable.row(); + tiptable.add().size(4); + tiptable.row(); + tiptable.add("[gray]" + description).left(); + tiptable.row(); + if(control.hasWeapon(weapon)){ + tiptable.add("$text.purchased").padTop(4).left(); + } + tiptable.margin(8f); + }; + + run.listen(); + + Tooltip
tip = new Tooltip<>(tiptable, run); + + tip.setInstant(true); + + ImageButton button = content.addImageButton("white", 8*4, () -> { + control.removeItems(requirements); + control.addWeapon(weapon); + Vars.ui.hudfrag.updateWeapons(); + run.listen(); + Effects.sound("purchase"); + + if(Net.active() && Net.client()){ + Vars.netClient.handleUpgrade(weapon); + } + }).size(49f, 54f).padBottom(-5).get(); + + button.setDisabled(() -> control.hasWeapon(weapon)); + button.getStyle().imageUp = new TextureRegionDrawable(Draw.region(weapon.name)); + button.addListener(tip); + + if(++i % 3 == 0){ + content.row(); + } + } + + table.add(content).padTop(140f); + } +} diff --git a/kryonet/src/io/anuke/kryonet/KryoClient.java b/kryonet/src/io/anuke/kryonet/KryoClient.java index 8ff3020aeb..71267eaf3b 100644 --- a/kryonet/src/io/anuke/kryonet/KryoClient.java +++ b/kryonet/src/io/anuke/kryonet/KryoClient.java @@ -136,6 +136,7 @@ public class KryoClient implements ClientProvider{ for(Class c : types){ client.getKryo().register(c); } + KryoRegistrator.register(client.getKryo()); } @Override diff --git a/kryonet/src/io/anuke/kryonet/KryoRegistrator.java b/kryonet/src/io/anuke/kryonet/KryoRegistrator.java new file mode 100644 index 0000000000..e7d2deb624 --- /dev/null +++ b/kryonet/src/io/anuke/kryonet/KryoRegistrator.java @@ -0,0 +1,38 @@ +package io.anuke.kryonet; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.Serializer; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import io.anuke.mindustry.resource.Mech; +import io.anuke.mindustry.resource.Upgrade; +import io.anuke.mindustry.resource.Weapon; + +public class KryoRegistrator { + + public static void register(Kryo kryo){ + kryo.register(Weapon.class, new Serializer() { + @Override + public void write(Kryo kryo, Output output, Weapon object) { + output.writeByte(object.id); + } + + @Override + public Weapon read(Kryo kryo, Input input, Class type) { + return (Weapon)Upgrade.getByID(input.readByte()); + } + }); + + kryo.register(Mech.class, new Serializer() { + @Override + public void write(Kryo kryo, Output output, Mech object) { + output.writeByte(object.id); + } + + @Override + public Mech read(Kryo kryo, Input input, Class type) { + return (Mech)Upgrade.getByID(input.readByte()); + } + }); + } +} diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java index 1ce34c3e62..95d008f087 100644 --- a/kryonet/src/io/anuke/kryonet/KryoServer.java +++ b/kryonet/src/io/anuke/kryonet/KryoServer.java @@ -190,6 +190,7 @@ public class KryoServer implements ServerProvider { for(Class c : types){ server.getKryo().register(c); } + KryoRegistrator.register(server.getKryo()); } @Override