diff --git a/core/assets-raw/sprites/blocks/power/turbine-generator-top.png b/core/assets-raw/sprites/blocks/power/turbine-generator-top.png index 84caa97329..4e2f4fa5b4 100644 Binary files a/core/assets-raw/sprites/blocks/power/turbine-generator-top.png and b/core/assets-raw/sprites/blocks/power/turbine-generator-top.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index d70c302565..e7ce299d9d 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -533,3 +533,4 @@ block.liquid-tank.name=Liquid Tank block.liquid-junction.name=Liquid Junction block.bridge-conduit.name=Bridge Conduit block.rotary-pump.name=Rotary Pump +block.nuclear-reactor.name=Nuclear Reactor diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 0fe64032fd..3900661c1d 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/content/Items.java b/core/src/io/anuke/mindustry/content/Items.java index 0671364581..eabd520782 100644 --- a/core/src/io/anuke/mindustry/content/Items.java +++ b/core/src/io/anuke/mindustry/content/Items.java @@ -21,11 +21,13 @@ public class Items implements ContentList{ tungsten = new Item("tungsten", Color.valueOf("a0b0c8")) {{ type = ItemType.material; hardness = 1; + cost = 0.75f; }}; lead = new Item("lead", Color.valueOf("8e85a2")) {{ type = ItemType.material; hardness = 1; + cost = 0.6f; }}; coal = new Item("coal", Color.valueOf("272727")) {{ @@ -41,6 +43,7 @@ public class Items implements ContentList{ titanium = new Item("titanium", Color.valueOf("8da1e3")) {{ type = ItemType.material; hardness = 3; + cost = 1.1f; }}; thorium = new Item("thorium", Color.valueOf("f9a3c7")) {{ @@ -48,20 +51,24 @@ public class Items implements ContentList{ explosiveness = 0.1f; hardness = 4; radioactivity = 0.5f; + cost = 1.2f; }}; silicon = new Item("silicon", Color.valueOf("53565c")) {{ type = ItemType.material; + cost = 0.9f; }}; plastanium = new Item("plastanium", Color.valueOf("e9ead3")) {{ type = ItemType.material; flammability = 0.1f; explosiveness = 0.1f; + cost = 1.5f; }}; phasematter = new Item("phase-matter", Color.valueOf("f4ba6e")) {{ type = ItemType.material; + cost = 1.5f; }}; surgealloy = new Item("surge-alloy", Color.valueOf("b4d5c7")) {{ diff --git a/core/src/io/anuke/mindustry/content/Recipes.java b/core/src/io/anuke/mindustry/content/Recipes.java index 5ebcec9ec6..2ff0bea050 100644 --- a/core/src/io/anuke/mindustry/content/Recipes.java +++ b/core/src/io/anuke/mindustry/content/Recipes.java @@ -101,6 +101,8 @@ public class Recipes implements ContentList{ new Recipe(power, PowerBlocks.solarPanel, new ItemStack(Items.lead, 20), new ItemStack(Items.silicon, 30)); new Recipe(power, PowerBlocks.largeSolarPanel, new ItemStack(Items.lead, 200), new ItemStack(Items.silicon, 290), new ItemStack(Items.phasematter, 30)); + //generators - other + new Recipe(power, PowerBlocks.nuclearReactor, new ItemStack(Items.lead, 600), new ItemStack(Items.silicon, 400), new ItemStack(Items.carbide, 300), new ItemStack(Items.thorium, 300)); //new Recipe(distribution, StorageBlocks.core, new ItemStack(Items.carbide, 50)); new Recipe(distribution, StorageBlocks.unloader, new ItemStack(Items.carbide, 40), new ItemStack(Items.silicon, 50)); diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java index 69e2d879ab..e8533325f7 100644 --- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java @@ -22,6 +22,7 @@ public class PowerBlocks extends BlockList implements ContentList { maxLiquidGenerate = 0.5f; powerPerLiquid = 0.08f; powerCapacity = 40f; + powerPerLiquid = 0.25f; generateEffect = BlockFx.redgeneratespark; size = 2; }}; @@ -30,6 +31,7 @@ public class PowerBlocks extends BlockList implements ContentList { powerOutput = 0.28f; powerCapacity = 40f; itemDuration = 30f; + powerPerLiquid = 0.7f; auxLiquidUse = 0.05f; size = 2; }}; @@ -51,7 +53,8 @@ public class PowerBlocks extends BlockList implements ContentList { nuclearReactor = new NuclearReactor("nuclear-reactor") {{ size = 3; - health = 600; + health = 700; + powerMultiplier = 0.8f; }}; fusionReactor = new FusionReactor("fusion-reactor") {{ diff --git a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java index efcc0e9657..3cb3766bd8 100644 --- a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java @@ -83,13 +83,13 @@ public class TurretBlocks extends BlockList implements ContentList { }}; lancer = new LaserTurret("lancer") {{ - range = 70f; - chargeTime = 70f; + range = 90f; + chargeTime = 60f; chargeMaxDelay = 30f; chargeEffects = 7; shootType = AmmoTypes.lancerLaser; recoil = 2f; - reload = 130f; + reload = 100f; cooldown = 0.03f; powerUsed = 20f; powerCapacity = 60f; @@ -131,7 +131,7 @@ public class TurretBlocks extends BlockList implements ContentList { salvo = new BurstTurret("salvo") {{ size = 2; - range = 110f; + range = 120f; ammoTypes = new AmmoType[]{AmmoTypes.bulletTungsten, AmmoTypes.bulletCarbide, AmmoTypes.bulletPyratite, AmmoTypes.bulletThorium, AmmoTypes.bulletSilicon}; reload = 40f; restitution = 0.03f; diff --git a/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java b/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java index 5ae4f300e8..3912d60949 100644 --- a/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java @@ -96,7 +96,7 @@ public class TurretBullets extends BulletList implements ContentList { Color[] colors = {Palette.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Palette.lancerLaser, Color.WHITE}; float[] tscales = {1f, 0.7f, 0.5f, 0.2f}; float[] lenscales = {1f, 1.1f, 1.13f, 1.14f}; - float length = 70f; + float length = 90f; { hiteffect = BulletFx.hitLancer; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index eff4715163..8e322d84fb 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -162,7 +162,7 @@ public class Control extends Module{ } public void addPlayer(int index){ - if(players.length < index + 1){ + if(players.length != index + 1){ Player[] old = players; players = new Player[index + 1]; System.arraycopy(old, 0, players, 0, old.length); @@ -288,6 +288,8 @@ public class Control extends Module{ ContentLoader.dispose(); Net.dispose(); ui.editor.dispose(); + inputs = new InputHandler[]{}; + players = new Player[]{}; } @Override diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 7b8596a7d6..cf25d06aae 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -258,7 +258,7 @@ public class Renderer extends RendererModule{ if(group.count(p -> p.isFlying() == flying) + playerGroup.count(p -> p.isFlying() == flying && p.getTeam() == team) == 0 && flying) continue; - drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying, Unit::drawUnder); + drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder); drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawUnder); Shaders.outline.color.set(team.color); @@ -266,13 +266,13 @@ public class Renderer extends RendererModule{ Graphics.beginShaders(Shaders.outline); Graphics.shader(Shaders.mix, true); - drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying); + drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead()); drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team); Graphics.shader(); blocks.drawTeamBlocks(Layer.turret, team); Graphics.endShaders(); - drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying, Unit::drawOver); + drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver); drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawOver); } } diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 3d9b2051fa..7c46ed1bfa 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -55,6 +55,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra public float boostHeat; public Color color = new Color(); public Mech mech; + public int spawner; public NetConnection con; public int playerIndex = 0; @@ -63,7 +64,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra public TargetTrait target; public TargetTrait moveTarget; - private boolean respawning; private float walktime; private Queue placeQueue = new ThreadQueue<>(); private Tile mining; @@ -175,6 +175,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra return mech.weapon.getAmmoType(item) != null && inventory.canAcceptAmmo(mech.weapon.getAmmoType(item)); } + @Override + public void added() { + baseRotation = 90f; + } + @Override public void addAmmo(Item item) { inventory.addAmmo(mech.weapon.getAmmoType(item)); @@ -222,7 +227,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra if(player == null) return; player.dead = true; - player.respawning = false; player.placeQueue.clear(); player.dropCarry(); @@ -435,11 +439,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra if(isDead()){ isBoosting = false; boostHeat = 0f; - CoreEntity entity = (CoreEntity)getClosestCore(); - - if (!respawning && entity != null) { - entity.trySetPlayer(this); - } + updateRespawning(); return; } @@ -656,7 +656,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra inventory.clear(); placeQueue.clear(); dead = true; - respawning = false; trail.clear(); health = maxHealth(); @@ -667,12 +666,18 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra return isShooting && inventory.hasAmmo() && (!isBoosting || mech.flying); } - public void setRespawning(){ - respawning = true; + public void updateRespawning(){ + CoreEntity entity = (CoreEntity)getClosestCore(); + + if (entity != null) { + this.spawner = entity.tile.id(); + entity.updateSpawning(this); + } } - public void setRespawning(boolean respawning){ - this.respawning = respawning; + public void beginRespawning(SpawnerTrait spawner){ + this.spawner = spawner.getTile().packedPosition(); + this.dead = true; } @Override @@ -735,6 +740,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra buffer.writeByte(mech.id); buffer.writeBoolean(isBoosting); buffer.writeInt(mining == null ? -1 : mining.packedPosition()); + buffer.writeInt(spawner); writeBuilding(buffer); } @@ -750,6 +756,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra mech = Upgrade.getByID(buffer.readByte()); boolean boosting = buffer.readBoolean(); int mine = buffer.readInt(); + spawner = buffer.readInt(); + readBuilding(buffer, !isLocal); interpolator.read(lastx, lasty, x, y, time, rotation); diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/TileEntity.java index 8786144858..e53425605f 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/TileEntity.java @@ -131,6 +131,10 @@ public class TileEntity extends BaseEntity implements TargetTrait { } } + public Tile getTile(){ + return tile; + } + @Override public Team getTeam() { return tile.getTeam(); diff --git a/core/src/io/anuke/mindustry/entities/Unit.java b/core/src/io/anuke/mindustry/entities/Unit.java index e43860ee8b..4808b740a4 100644 --- a/core/src/io/anuke/mindustry/entities/Unit.java +++ b/core/src/io/anuke/mindustry/entities/Unit.java @@ -132,6 +132,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ @Override public void readSave(DataInput stream) throws IOException { byte team = stream.readByte(); + boolean dead = stream.readBoolean(); float x = stream.readFloat(); float y = stream.readFloat(); byte xv = stream.readByte(); @@ -141,6 +142,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ this.status.readSave(stream); this.inventory.readSave(stream); + this.dead = dead; this.team = Team.all[team]; this.health = health; this.x = x; @@ -151,6 +153,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ public void writeSave(DataOutput stream, boolean net) throws IOException { stream.writeByte(team.ordinal()); + stream.writeBoolean(isDead()); stream.writeFloat(net ? interpolator.target.x : x); stream.writeFloat(net ? interpolator.target.y : y); stream.writeByte((byte)(Mathf.clamp(velocity.x, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index 9331513d42..b4b69e5c19 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -192,7 +192,9 @@ public interface BuilderTrait extends Entity{ entity.construct(unit, core, 1f / entity.buildCost * Timers.delta() * getBuildPower(tile)); } - unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f); + if(unit.distanceTo(tile) <= placeDistance){ + unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f); + } current.progress = entity.progress(); } @@ -239,7 +241,11 @@ public interface BuilderTrait extends Entity{ Tile tile = world.tile(request.x, request.y); - Draw.color(unit.distanceTo(tile) > placeDistance || request.remove ? Palette.remove : Palette.accent); + if(unit.distanceTo(tile) > placeDistance){ + return; + } + + Draw.color(Palette.accent); float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f); float px = unit.x + Angles.trnsx(unit.rotation, focusLen); float py = unit.y + Angles.trnsy(unit.rotation, focusLen); diff --git a/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java b/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java new file mode 100644 index 0000000000..1fd4a9daf0 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java @@ -0,0 +1,10 @@ +package io.anuke.mindustry.entities.traits; + +import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.world.Tile; + +public interface SpawnerTrait { + Tile getTile(); + void updateSpawning(Unit unit); + float getSpawnProgress(); +} diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java index 4c943b2676..6eef8aa300 100644 --- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java @@ -12,6 +12,7 @@ import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.effect.ScorchDecal; import io.anuke.mindustry.entities.traits.ShooterTrait; +import io.anuke.mindustry.entities.traits.SpawnerTrait; import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.TeamInfo.TeamData; @@ -52,7 +53,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ protected boolean isWave; protected Squad squad; - protected int spawner = -1; + protected int spawner; /**Initialize the type and team of this unit. Only call once!*/ public void init(UnitType type, Team team){ @@ -62,8 +63,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ this.team = team; } - public void setSpawner(UnitFactoryEntity spawner) { - this.spawner = spawner.tile.packedPosition(); + public void setSpawner(Tile tile) { + this.spawner = tile.packedPosition(); } public UnitType getType() { @@ -92,6 +93,19 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ ((TileEntity)target).tile.block().flags.contains(flag); } + public void updateRespawning(){ + if(spawner == -1) return; + + Tile tile = world.tile(spawner); + if(tile != null && tile.entity != null){ + if(tile.entity instanceof SpawnerTrait){ + ((SpawnerTrait) tile.entity).updateSpawning(this); + } + }else{ + spawner = -1; + } + } + public void setState(UnitState state){ this.state.set(state); } @@ -254,6 +268,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ if(hitTime < 0) hitTime = 0; + if(isDead()){ + updateRespawning(); + return; + } + if(Net.client()){ interpolate(); status.update(this); @@ -322,7 +341,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ hitboxTile.setSize(type.hitsizeTile); state.set(getStartState()); - heal(); + health(maxHealth()); } @Override @@ -353,6 +372,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ public void write(DataOutput data) throws IOException{ super.writeSave(data); data.writeByte(type.id); + data.writeInt(spawner); } @Override @@ -360,6 +380,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ float lastx = x, lasty = y, lastrot = rotation; super.readSave(data); this.type = UnitType.getByID(data.readByte()); + this.spawner = data.readInt(); interpolator.read(lastx, lasty, x, y, time, rotation); rotation = lastrot; diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 186537dd3e..94c9296b2d 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -64,31 +64,31 @@ public class BlockRenderer{ int worldx = Mathf.scl(camera.position.x, tilesize) + x; int worldy = Mathf.scl(camera.position.y, tilesize) + y; boolean expanded = (x < -rangex || x > rangex || y < -rangey || y > rangey); - - Tile tile = world.tile(worldx, worldy); - - if(tile != null){ - Block block = tile.block(); - - if(!expanded && block != Blocks.air && world.isAccessible(worldx, worldy)){ - synchronized (Tile.tileSetLock) { + + synchronized (Tile.tileSetLock) { + Tile tile = world.tile(worldx, worldy); + + if (tile != null) { + Block block = tile.block(); + + if (!expanded && block != Blocks.air && world.isAccessible(worldx, worldy)) { tile.block().drawShadow(tile); } - } - - if(!(block instanceof StaticBlock)){ - if(block != Blocks.air){ - if(!expanded){ - addRequest(tile, Layer.block); - } - if(block.expanded || !expanded){ - if(block.layer != null && block.isLayer(tile)){ - addRequest(tile, block.layer); + if (!(block instanceof StaticBlock)) { + if (block != Blocks.air) { + if (!expanded) { + addRequest(tile, Layer.block); } - if(block.layer2 != null && block.isLayer2(tile)){ - addRequest(tile, block.layer2); + if (block.expanded || !expanded) { + if (block.layer != null && block.isLayer(tile)) { + addRequest(tile, block.layer); + } + + if (block.layer2 != null && block.isLayer2(tile)) { + addRequest(tile, block.layer2); + } } } } diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index c9c4dcb58d..1363f75035 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -17,7 +17,6 @@ import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Timers; import io.anuke.ucore.function.Callable; -import io.anuke.ucore.graphics.CapStyle; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.graphics.Lines; @@ -123,11 +122,11 @@ public class OverlayRenderer { drawbars.run(); if(values[0] > 0){ - drawEncloser(target.drawx(), target.drawy() + block.size * tilesize/2f + 2f + values[0]/2f - 0.5f + (values[0] > 1 ? 0.75f : 0), values[0]); + drawEncloser(target.drawx(), target.drawy() + block.size * tilesize/2f + 2f, values[0]); } if(values[1] > 0){ - drawEncloser(target.drawx(), target.drawy() - block.size * tilesize/2f - 2f - values[1]/2f - 0.5f, values[1]); + drawEncloser(target.drawx(), target.drawy() - block.size * tilesize/2f - 2f - values[1], values[1]); } doDraw[0] = true; @@ -208,15 +207,11 @@ public class OverlayRenderer { } void drawEncloser(float x, float y, float height){ - x -= 0.5f; - y += 0.5f - (height-1f)/2f; float len = 3; - Lines.stroke(2f + height); Draw.color(Palette.bar); - Lines.line(x - len - 0.5f, y, x + len + 1.5f, y, CapStyle.none); - - Draw.reset(); + Fill.crect(x - len - 1, y - 1, len*2f + 2f, height + 2f); + Draw.color(); } } diff --git a/core/src/io/anuke/mindustry/graphics/Trail.java b/core/src/io/anuke/mindustry/graphics/Trail.java index dc8283ce98..04389cd44b 100644 --- a/core/src/io/anuke/mindustry/graphics/Trail.java +++ b/core/src/io/anuke/mindustry/graphics/Trail.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.graphics; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.FloatArray; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Fill; @@ -9,14 +10,20 @@ import io.anuke.ucore.util.Mathf; /**Class that renders a trail.*/ public class Trail { + private final static float maxJump = 15f; private final int length; private final FloatArray points = new FloatArray(); + private float lastX, lastY; public Trail(int length){ this.length = length; } public synchronized void update(float curx, float cury){ + if(Vector2.dst(curx, cury, lastX, lastY) >= maxJump){ + points.clear(); + } + points.add(curx, cury); if(points.size > length*2) { @@ -24,6 +31,9 @@ public class Trail { System.arraycopy(items, 2, items, 0, points.size - 2); points.size -= 2; } + + lastX = curx; + lastY = cury; } public synchronized void clear(){ diff --git a/core/src/io/anuke/mindustry/input/DefaultKeybinds.java b/core/src/io/anuke/mindustry/input/DefaultKeybinds.java index f32f650c14..5c9bfafa21 100644 --- a/core/src/io/anuke/mindustry/input/DefaultKeybinds.java +++ b/core/src/io/anuke/mindustry/input/DefaultKeybinds.java @@ -19,9 +19,9 @@ public class DefaultKeybinds { new Category("General"), "move_x", new Axis(Input.A, Input.D), "move_y", new Axis(Input.S, Input.W), - "select", Input.MOUSE_LEFT, - "break", Input.MOUSE_RIGHT, - "shoot", Input.MOUSE_LEFT, + //"select", Input.MOUSE_LEFT, + //"break", Input.MOUSE_RIGHT, + //"shoot", Input.MOUSE_LEFT, "rotate", new Axis(Input.SCROLL), "dash", Input.SHIFT_LEFT, "drop_unit", Input.SHIFT_LEFT, @@ -39,8 +39,7 @@ public class DefaultKeybinds { "chat_history_prev", Input.UP, "chat_history_next", Input.DOWN, "chat_scroll", new Axis(Input.SCROLL), - "console", Input.GRAVE, - "block_logs", Input.I + "console", Input.GRAVE ); KeyBinds.defaultSection(section, DeviceType.controller, @@ -49,9 +48,9 @@ public class DefaultKeybinds { "move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS), "cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS), "cursor_y", new Axis(Input.CONTROLLER_R_STICK_VERTICAL_AXIS), - "select", Input.CONTROLLER_R_BUMPER, - "break", Input.CONTROLLER_L_BUMPER, - "shoot", Input.CONTROLLER_R_TRIGGER, + //"select", Input.CONTROLLER_R_BUMPER, + //"break", Input.CONTROLLER_L_BUMPER, + //"shoot", Input.CONTROLLER_R_TRIGGER, "dash", Input.CONTROLLER_Y, "rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT), "rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B), diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 3dbadd3123..dc1d462627 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -300,14 +300,14 @@ public class DesktopInput extends InputHandler{ if(player.playerIndex > 0){ controlling = true; } - + /* if(Inputs.keyTap(section,"select")){ Inputs.getProcessor().touchDown((int)getMouseX(), (int)getMouseY(), player.playerIndex, Buttons.LEFT); } if(Inputs.keyRelease(section,"select")){ Inputs.getProcessor().touchUp((int)getMouseX(), (int)getMouseY(), player.playerIndex, Buttons.LEFT); - } + }*/ float xa = Inputs.getAxis(section, "cursor_x"); float ya = Inputs.getAxis(section, "cursor_y"); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index bcfee7c140..ddff5a96ce 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -6,7 +6,6 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.type.Category; @@ -190,7 +189,7 @@ public class BlocksFragment extends Fragment{ Stack istack = new Stack(); for(TextureRegion region : regions){ Image u = new Image(region); - u.update(() -> u.setColor(image.isDisabled() ? Color.GRAY : Color.WHITE)); + u.update(() -> u.setColor(istack.getColor())); istack.add(u); } @@ -236,35 +235,21 @@ public class BlocksFragment extends Fragment{ } }); - image.setDisabled(() -> { - TileEntity entity = players[0].getClosestCore(); - - if(entity == null) return true; - - for(ItemStack s : r.requirements){ - if(!entity.items.hasItem(s.item, Mathf.ceil(s.amount/2f))){ - return true; - } - } - return false; - }); - recipeTable.add(image).size(size + 8); image.update(() -> { - if(!image.isDisabled()) { - for (Player player : players) { - if (control.input(player.playerIndex).recipe == r) { - image.setChecked(true); - return; - } + image.setChecked(r == control.input(0).recipe); + TileEntity entity = players[0].getClosestCore(); + + if(entity == null) return; + + for(ItemStack s : r.requirements){ + if(!entity.items.hasItem(s.item, Mathf.ceil(s.amount))){ + istack.setColor(Color.GRAY); + return; } - }/*else{ - if(control.input(0).recipe == r){ - control.input(0).recipe = null; - } - }*/ - image.setChecked(false); + } + istack.setColor(Color.WHITE); }); if (i % rows == rows - 1) { diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index ec9eb98254..9087faf510 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -198,6 +198,8 @@ public abstract class BaseBlock { /**Try dumping a specific item near the tile.*/ public boolean tryDump(Tile tile, Item todump){ + if(tile.entity == null || !hasItems) return false; + int size = tile.block().size; GridPoint2[] nearby = Edges.getEdges(size); diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java index 2c963268e8..aa075581ae 100644 --- a/core/src/io/anuke/mindustry/world/Build.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -146,13 +146,17 @@ public class Build { return true; } + if(!type.canPlaceOn(tile)){ + return false; + } + int offsetx = -(type.size - 1) / 2; int offsety = -(type.size - 1) / 2; for (int dx = 0; dx < type.size; dx++) { for (int dy = 0; dy < type.size; dy++) { Tile other = world.tile(x + dx + offsetx, y + dy + offsety); if (other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) - || !type.canPlaceOn(other) || other.cliffs != 0 || !other.floor().placeableOn || + || other.cliffs != 0 || !other.floor().placeableOn || (tile.floor().liquidDrop != null && !type.floating)) { return false; } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index e8462bb8c3..9e24abd336 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -253,6 +253,25 @@ public class Tile implements PosTrait, TargetTrait { } return tmpArray; } + + /**Returns the list of all tiles linked to this multiblock if it were this block, or an empty array if it's not a multiblock. + * This array contains all linked tiles, including this tile itself.*/ + public synchronized Array getLinkedTilesAs(Block block, Array tmpArray){ + tmpArray.clear(); + if(block.isMultiblock()){ + int offsetx = -(block.size-1)/2; + int offsety = -(block.size-1)/2; + for(int dx = 0; dx < block.size; dx ++){ + for(int dy = 0; dy < block.size; dy ++){ + Tile other = world.tile(x + dx + offsetx, y + dy + offsety); + tmpArray.add(other); + } + } + }else{ + tmpArray.add(this); + } + return tmpArray; + } /**Returns the block the multiblock is linked to, or null if it is not linked to any block.*/ public Tile getLinked(){ diff --git a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java index 33f83ace98..55e6ce750c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java @@ -13,6 +13,7 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockBar; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; +import io.anuke.mindustry.world.meta.values.LiquidFilterValue; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -38,6 +39,7 @@ public class NuclearReactor extends PowerGenerator { protected float heating = 0.009f; //heating per frame protected float coolantPower = 0.015f; //how much heat decreases per coolant unit protected float smokeThreshold = 0.3f; //threshold at which block starts smoking + protected float maxLiquidUse = 1f; //max liquid use per frame protected int explosionRadius = 19; protected int explosionDamage = 135; protected float flashThreshold = 0.46f; //heat threshold at which the lights start flashing @@ -49,6 +51,7 @@ public class NuclearReactor extends PowerGenerator { liquidCapacity = 50; powerCapacity = 80f; hasItems = true; + hasLiquids = true; } @Override @@ -62,6 +65,7 @@ public class NuclearReactor extends PowerGenerator { public void setStats(){ super.setStats(); stats.add(BlockStat.inputItem, generateItem); + stats.add(BlockStat.inputLiquid, new LiquidFilterValue(liquid -> liquid.temperature <= 0.5f)); stats.add(BlockStat.maxPowerGeneration, powerMultiplier*60f, StatUnit.powerSecond); } @@ -85,12 +89,12 @@ public class NuclearReactor extends PowerGenerator { if(entity.liquids.liquid.temperature <= 0.5f){ //is coolant float pow = coolantPower * entity.liquids.liquid.heatCapacity; //heat depleted per unit of liquid - float maxUsed = Math.min(entity.liquids.amount, entity.heat / pow); //max that can be cooled in terms of liquid + float maxUsed = Math.min(Math.min(entity.liquids.amount, entity.heat / pow), maxLiquidUse * Timers.delta()); //max that can be cooled in terms of liquid entity.heat -= maxUsed * pow; entity.liquids.amount -= maxUsed; }else{ //is heater float heat = coolantPower * entity.liquids.liquid.heatCapacity / 4f; //heat created per unit of liquid - float maxUsed = Math.min(entity.liquids.amount, (1f - entity.heat) / heat); //max liquid used + float maxUsed = Math.min(Math.min(entity.liquids.amount, (1f - entity.heat) / heat), maxLiquidUse * Timers.delta()); //max liquid used entity.heat += maxUsed * heat; entity.liquids.amount -= maxUsed; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java index a1febf75fa..1856f63c32 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -43,8 +43,8 @@ public class Drill extends Block{ protected Liquid inputLiquid = Liquids.water; /**Whether the liquid is required to drill. If false, then it will be used as a speed booster.*/ protected boolean liquidRequired = false; - /**How many times faster the drill will progress when booster by liquid.*/ - protected float liquidBoostIntensity = 1.3f; + /**How many times faster the drill will progress when boosted by liquid.*/ + protected float liquidBoostIntensity = 1.6f; /**Speed at which the drill speeds up.*/ protected float warmupSpeed = 0.02f; @@ -224,7 +224,7 @@ public class Drill extends Block{ @Override public boolean canPlaceOn(Tile tile) { if(isMultiblock()){ - for(Tile other : tile.getLinkedTiles(drawTiles)){ + for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ if(isValid(other)){ return true; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Pump.java b/core/src/io/anuke/mindustry/world/blocks/production/Pump.java index a5d9350499..7e98c47e3d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Pump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Pump.java @@ -63,7 +63,7 @@ public class Pump extends LiquidBlock{ public boolean canPlaceOn(Tile tile) { if(isMultiblock()){ Liquid last = null; - for(Tile other : tile.getLinkedTiles(drawTiles)){ + for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ //can't place pump on block with multiple liquids if(last != null && other.floor().liquidDrop != last){ return false; diff --git a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java index fd77cc75d2..a15ff7c5ea 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java @@ -95,7 +95,7 @@ public class SolidPump extends Pump { @Override public boolean canPlaceOn(Tile tile) { if(isMultiblock()){ - for(Tile other : tile.getLinkedTiles(drawTiles)){ + for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ if(isValid(other)){ return true; } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index e9d4f2b57a..ea0189c6ef 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -11,6 +11,7 @@ import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Units; +import io.anuke.mindustry.entities.traits.SpawnerTrait; import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.UnitType; import io.anuke.mindustry.gen.CallBlocks; @@ -21,6 +22,7 @@ import io.anuke.mindustry.net.In; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemType; +import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockFlag; import io.anuke.ucore.core.Effects; @@ -64,6 +66,13 @@ public class CoreBlock extends StorageBlock { flags = EnumSet.of(BlockFlag.resupplyPoint, BlockFlag.target); } + @Override + public void setBars() { + super.setBars(); + + bars.remove(BarType.inventory); + } + @Override public void load() { super.load(); @@ -132,7 +141,7 @@ public class CoreBlock extends StorageBlock { @Override public boolean acceptItem(Item item, Tile tile, Tile source) { - return tile.entity.items.items[item.id]< itemCapacity && item.type == ItemType.material; + return tile.entity.items.items[item.id] < itemCapacity && item.type == ItemType.material; } @Override @@ -192,14 +201,13 @@ public class CoreBlock extends StorageBlock { } } - if(!found) { - + if(!found){ BaseUnit unit = droneType.create(tile.getTeam()); - entity.droneID = unit.id; + unit.setSpawner(tile); unit.setDead(true); - unit.setGroup(unitGroups[unit.getTeam().ordinal()]); - CallBlocks.onCoreUnitSet(tile, unit); - unit.setGroup(null); + unit.add(); + + entity.droneID = unit.id; } } @@ -243,18 +251,17 @@ public class CoreBlock extends StorageBlock { entity.currentUnit.rotation = 90f; entity.currentUnit.setNet(tile.drawx(), tile.drawy()); entity.currentUnit.add(); - - if(entity.currentUnit instanceof Player){ - ((Player) entity.currentUnit).baseRotation = 90f; - } - entity.currentUnit = null; } + @Remote(called = Loc.server, in = In.blocks) + public static void setCoreSolid(Tile tile, boolean solid){ + CoreEntity entity = tile.entity(); + entity.solid = solid; + } +/* @Remote(called = Loc.server, in = In.blocks) public static void onCoreUnitSet(Tile tile, Unit player){ - if(player == null) return; - CoreEntity entity = tile.entity(); entity.currentUnit = player; entity.progress = 0f; @@ -264,14 +271,8 @@ public class CoreBlock extends StorageBlock { ((Player) player).setRespawning(true); } } - - @Remote(called = Loc.server, in = In.blocks) - public static void setCoreSolid(Tile tile, boolean solid){ - CoreEntity entity = tile.entity(); - entity.solid = solid; - } - - public class CoreEntity extends TileEntity{ +*/ + public class CoreEntity extends TileEntity implements SpawnerTrait{ public Unit currentUnit; int droneID = -1; boolean solid = true; @@ -280,12 +281,20 @@ public class CoreBlock extends StorageBlock { float time; float heat; - public void trySetPlayer(Player player){ + @Override + public void updateSpawning(Unit unit) { if(currentUnit == null){ - CallBlocks.onCoreUnitSet(tile, player); + currentUnit = unit; + progress = 0f; + unit.set(tile.drawx(), tile.drawy()); } } + @Override + public float getSpawnProgress() { + return progress; + } + @Override public void write(DataOutputStream stream) throws IOException { stream.writeBoolean(solid); diff --git a/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java index 4d3a0a0967..ab704759f9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java @@ -8,7 +8,9 @@ import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Units; +import io.anuke.mindustry.entities.traits.SpawnerTrait; import io.anuke.mindustry.gen.CallBlocks; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Shaders; @@ -52,7 +54,7 @@ public class MechFactory extends Block{ public void tapped(Tile tile, Player player) { if(checkValidTap(tile, player)){ - CallBlocks.onMechFactoryBegin(player, tile); + CallBlocks.onMechFactoryTap(player, tile); }else if(player.isLocal && mobile){ player.moveTarget = tile.entity; } @@ -134,19 +136,12 @@ public class MechFactory extends Block{ return new MechFactoryEntity(); } - @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) - public static void onMechFactoryBegin(Player player, Tile tile){ + @Remote(targets = Loc.both, called = Loc.server, in = In.blocks) + public static void onMechFactoryTap(Player player, Tile tile){ if(!checkValidTap(tile, player)) return; MechFactoryEntity entity = tile.entity(); - entity.progress = 0f; - entity.player = player; - - player.rotation = 90f; - player.baseRotation = 90f; - player.set(entity.x, entity.y); - player.setDead(true); - player.setRespawning(true); + player.beginRespawning(entity); } @Remote(called = Loc.server, in = In.blocks) @@ -179,12 +174,32 @@ public class MechFactory extends Block{ Math.abs(player.y - tile.drawy()) <= tile.block().size * tilesize / 2f && entity.player == null; } - public class MechFactoryEntity extends TileEntity{ - public Player player; - public float progress; - public float time; - public float heat; - public boolean open; + public class MechFactoryEntity extends TileEntity implements SpawnerTrait{ + Player player; + float progress; + float time; + float heat; + boolean open; + + @Override + public void updateSpawning(Unit unit) { + if(!(unit instanceof Player)) throw new IllegalArgumentException("Mech factories only accept player respawners."); + + if(player == null){ + progress = 0f; + player = (Player)unit; + + player.rotation = 90f; + player.baseRotation = 90f; + player.set(x, y); + player.beginRespawning(this); + } + } + + @Override + public float getSpawnProgress() { + return progress; + } @Override public void write(DataOutputStream stream) throws IOException { diff --git a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java index 4aec12e9bf..3722567476 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java @@ -7,7 +7,9 @@ import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Units; +import io.anuke.mindustry.entities.traits.SpawnerTrait; import io.anuke.mindustry.gen.CallBlocks; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Shaders; @@ -28,6 +30,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; +//TODO re-implement properly public class Reconstructor extends Block{ protected float departTime = 30f; protected float arriveTime = 40f; @@ -117,9 +120,9 @@ public class Reconstructor extends Block{ if(entity.current != null){ float progress = entity.departing ? entity.updateTime : (1f - entity.updateTime); - Player player = entity.current; + //Player player = entity.current; - TextureRegion region = player.mech.iconRegion; + TextureRegion region = entity.current.getIconRegion(); Shaders.build.region = region; Shaders.build.progress = progress; @@ -157,7 +160,7 @@ public class Reconstructor extends Block{ if(entity.departing){ //force respawn if there's suddenly nothing to link to if(!validLink(tile, entity.link)){ - entity.current.setRespawning(false); + //entity.current.setRespawning(false); return; } @@ -168,7 +171,7 @@ public class Reconstructor extends Block{ //no power? death. if(other.power.amount < powerPerTeleport){ entity.current.setDead(true); - entity.current.setRespawning(false); + //entity.current.setRespawning(false); entity.current = null; return; } @@ -263,8 +266,8 @@ public class Reconstructor extends Block{ player.rotation = 90f; player.baseRotation = 90f; player.setDead(true); - player.setRespawning(true); - player.setRespawning(); + // player.setRespawning(true); + //player.setRespawning(); } @Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true) @@ -300,12 +303,22 @@ public class Reconstructor extends Block{ }); } - public class ReconstructorEntity extends TileEntity{ - public Player current; - public float updateTime; - public float time; - public int link; - public boolean solid = true, departing; + public class ReconstructorEntity extends TileEntity implements SpawnerTrait{ + Unit current; + float updateTime; + float time; + int link; + boolean solid = true, departing; + + @Override + public void updateSpawning(Unit unit) { + + } + + @Override + public float getSpawnProgress() { + return 0; + } @Override public void write(DataOutputStream stream) throws IOException { diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java index 5f9b4d848f..d4fc03f531 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java @@ -196,7 +196,7 @@ public class UnitFactory extends Block { if(!Net.client()) { BaseUnit unit = factory.type.create(tile.getTeam()); - unit.setSpawner(entity); + unit.setSpawner(tile); unit.set(tile.drawx(), tile.drawy()); unit.add(); unit.getVelocity().y = factory.launchVelocity;