Misc bugfixes / Unified build/break block system
This commit is contained in:
@@ -32,7 +32,6 @@ public class Blocks extends BlockList implements ContentList{
|
||||
|
||||
for(int i = 1; i <= 6; i ++){
|
||||
new BuildBlock("build" + i);
|
||||
new BreakBlock("break" + i);
|
||||
}
|
||||
|
||||
space = new Floor("space") {{
|
||||
|
||||
@@ -27,9 +27,10 @@ public class PowerBlocks extends BlockList implements ContentList {
|
||||
}};
|
||||
|
||||
turbineGenerator = new TurbineGenerator("turbine-generator") {{
|
||||
powerOutput = 0.25f;
|
||||
powerOutput = 0.28f;
|
||||
powerCapacity = 40f;
|
||||
itemDuration = 30f;
|
||||
auxLiquidUse = 0.05f;
|
||||
size = 2;
|
||||
}};
|
||||
|
||||
|
||||
@@ -191,6 +191,10 @@ public class NetServer extends Module{
|
||||
player.setMineTile(packet.mining);
|
||||
player.isBoosting = packet.boosting;
|
||||
player.isShooting = packet.shooting;
|
||||
player.getPlaceQueue().clear();
|
||||
if(packet.currentRequest != null){
|
||||
player.getPlaceQueue().addLast(packet.currentRequest);
|
||||
}
|
||||
|
||||
vector.set(packet.x - player.getInterpolator().target.x, packet.y - player.getInterpolator().target.y);
|
||||
|
||||
|
||||
@@ -245,7 +245,9 @@ public class Renderer extends RendererModule{
|
||||
}
|
||||
|
||||
batch.begin();
|
||||
EntityDraw.setClip(false);
|
||||
drawAndInterpolate(playerGroup, p -> !p.isDead() && !p.isLocal, Player::drawName);
|
||||
EntityDraw.setClip(true);
|
||||
batch.end();
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,10 @@ public class World extends Module{
|
||||
return tiles[0].length;
|
||||
}
|
||||
|
||||
public int toPacked(int x, int y){
|
||||
return x + y *width();
|
||||
}
|
||||
|
||||
public Tile tile(int packed){
|
||||
return tiles == null ? null : tile(packed % width(), packed / width());
|
||||
}
|
||||
|
||||
@@ -735,6 +735,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
buffer.writeByte(mech.id);
|
||||
buffer.writeBoolean(isBoosting);
|
||||
buffer.writeInt(mining == null ? -1 : mining.packedPosition());
|
||||
|
||||
writeBuilding(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -748,6 +750,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
mech = Upgrade.getByID(buffer.readByte());
|
||||
boolean boosting = buffer.readBoolean();
|
||||
int mine = buffer.readInt();
|
||||
readBuilding(buffer, !isLocal);
|
||||
|
||||
interpolator.read(lastx, lasty, x, y, time, rotation);
|
||||
rotation = lastrot;
|
||||
|
||||
|
||||
@@ -8,32 +8,36 @@ import io.anuke.mindustry.content.fx.BlockFx;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.gen.CallBlocks;
|
||||
import io.anuke.mindustry.gen.CallEntity;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.BreakBlock;
|
||||
import io.anuke.mindustry.world.blocks.BreakBlock.BreakEntity;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.trait.Entity;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.graphics.Shapes;
|
||||
import io.anuke.ucore.util.*;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Translator;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
/**Interface for units that build, break or mine things.*/
|
||||
public interface BuilderTrait {
|
||||
public interface BuilderTrait extends Entity{
|
||||
//these are not instance variables!
|
||||
Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()};
|
||||
float placeDistance = 140f;
|
||||
@@ -54,6 +58,49 @@ public interface BuilderTrait {
|
||||
/**Build power, can be any float. 1 = builds recipes in normal time, 0 = doesn't build at all.*/
|
||||
float getBuildPower(Tile tile);
|
||||
|
||||
default void writeBuilding(DataOutput output) throws IOException{
|
||||
BuildRequest request = getCurrentRequest();
|
||||
|
||||
if(request != null){
|
||||
output.writeByte(request.remove ? 1 : 0);
|
||||
output.writeInt(world.toPacked(request.x, request.y));
|
||||
if(!request.remove){
|
||||
output.writeByte(request.recipe.id);
|
||||
output.writeByte(request.rotation);
|
||||
}
|
||||
}else{
|
||||
output.writeByte(-1);
|
||||
}
|
||||
}
|
||||
|
||||
default void readBuilding(DataInput input) throws IOException{
|
||||
readBuilding(input, true);
|
||||
}
|
||||
|
||||
default void readBuilding(DataInput input, boolean applyChanges) throws IOException{
|
||||
synchronized (getPlaceQueue()) {
|
||||
if(applyChanges) getPlaceQueue().clear();
|
||||
|
||||
byte type = input.readByte();
|
||||
if (type != -1) {
|
||||
int position = input.readInt();
|
||||
BuildRequest request;
|
||||
|
||||
if (type == 1) { //remove
|
||||
request = new BuildRequest(position % world.width(), position / world.width());
|
||||
} else { //place
|
||||
byte recipe = input.readByte();
|
||||
byte rotation = input.readByte();
|
||||
request = new BuildRequest(position % world.width(), position / world.width(), rotation, Recipe.getByID(recipe));
|
||||
}
|
||||
|
||||
if(applyChanges){
|
||||
getPlaceQueue().addLast(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Return whether this builder's place queue contains items.*/
|
||||
default boolean isBuilding(){
|
||||
return getPlaceQueue().size != 0;
|
||||
@@ -77,11 +124,7 @@ public interface BuilderTrait {
|
||||
|
||||
/**Clears the placement queue.*/
|
||||
default void clearBuilding(){
|
||||
if(this instanceof Player) {
|
||||
CallBlocks.onBuildDeselect((Player) this);
|
||||
}else{
|
||||
getPlaceQueue().clear();
|
||||
}
|
||||
getPlaceQueue().clear();
|
||||
}
|
||||
|
||||
/**Add another build requests to the tail of the queue, if it doesn't exist there yet.*/
|
||||
@@ -119,75 +162,38 @@ public interface BuilderTrait {
|
||||
setMineTile(null);
|
||||
}
|
||||
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
//if there is no core to build with, stop building!
|
||||
if(core == null){
|
||||
return;
|
||||
}
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(unit.distanceTo(tile) > placeDistance || //out of range, skip it
|
||||
(current.lastEntity != null && current.lastEntity.isDead())) { //build/destroy request has died, skip it
|
||||
getPlaceQueue().removeFirst();
|
||||
}else if(current.remove){
|
||||
|
||||
if (!(tile.block() instanceof BreakBlock)) { //check if haven't started placing
|
||||
if(Build.validBreak(unit.getTeam(), current.x, current.y)){
|
||||
|
||||
//if it's valid, place it
|
||||
if(!current.requested && unit instanceof Player){
|
||||
CallBlocks.breakBlock((Player)unit, unit.getTeam(), current.x, current.y);
|
||||
current.requested = true;
|
||||
}
|
||||
}else{
|
||||
//otherwise, skip it
|
||||
getPlaceQueue().removeFirst();
|
||||
}
|
||||
if (!(tile.block() instanceof BuildBlock)) {
|
||||
if(!current.remove && Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)) {
|
||||
Build.beginPlace(unit.getTeam(), current.x, current.y, current.recipe, current.rotation);
|
||||
}else if(current.remove && Build.validBreak(unit.getTeam(), current.x, current.y)){
|
||||
Build.beginBreak(unit.getTeam(), current.x, current.y);
|
||||
}else{
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
//if there is no core to build with, stop building!
|
||||
if(core == null){
|
||||
return;
|
||||
}
|
||||
|
||||
//otherwise, update it.
|
||||
BreakEntity entity = tile.entity();
|
||||
current.lastEntity = entity;
|
||||
|
||||
entity.addProgress(core, unit, 1f / entity.breakTime * Timers.delta() * getBuildPower(tile));
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
getCurrentRequest().progress = entity.progress();
|
||||
}
|
||||
}else{
|
||||
if (!(tile.block() instanceof BuildBlock)) { //check if haven't started placing
|
||||
if(Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)){
|
||||
|
||||
//if it's valid, place it
|
||||
if(!current.requested && unit instanceof Player){
|
||||
CallBlocks.placeBlock((Player)unit, unit.getTeam(), current.x, current.y, current.recipe, current.rotation);
|
||||
current.requested = true;
|
||||
}
|
||||
|
||||
}else{
|
||||
//otherwise, skip it
|
||||
getPlaceQueue().removeFirst();
|
||||
}
|
||||
}else{
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
//if there is no core to build with, stop building!
|
||||
if(core == null){
|
||||
return;
|
||||
}
|
||||
|
||||
//otherwise, update it.
|
||||
BuildEntity entity = tile.entity();
|
||||
current.lastEntity = entity;
|
||||
|
||||
entity.addProgress(core.items, 1f / entity.recipe.cost * Timers.delta() * getBuildPower(tile));
|
||||
if(unit instanceof Player){
|
||||
entity.lastBuilder = (Player)unit;
|
||||
}
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
getCurrentRequest().progress = entity.progress();
|
||||
getPlaceQueue().removeFirst();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, update it.
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
//deconstructing is 2x as fast
|
||||
if(current.remove){
|
||||
entity.deconstruct(unit, core, 2f / entity.buildCost * Timers.delta() * getBuildPower(tile));
|
||||
}else{
|
||||
entity.construct(unit, core, 1f / entity.buildCost * Timers.delta() * getBuildPower(tile));
|
||||
}
|
||||
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
current.progress = entity.progress();
|
||||
}
|
||||
|
||||
/**Do not call directly.*/
|
||||
@@ -302,9 +308,6 @@ public interface BuilderTrait {
|
||||
public final Recipe recipe;
|
||||
public final boolean remove;
|
||||
|
||||
public boolean requested;
|
||||
public TileEntity lastEntity;
|
||||
|
||||
public float progress;
|
||||
|
||||
/**This creates a build request.*/
|
||||
|
||||
@@ -18,7 +18,6 @@ import io.anuke.mindustry.gen.CallEntity;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||
@@ -206,26 +205,19 @@ public class Drone extends FlyingUnit implements BuilderTrait {
|
||||
public void write(DataOutput data) throws IOException {
|
||||
super.write(data);
|
||||
data.writeInt(mineTile == null ? -1 : mineTile.packedPosition());
|
||||
data.writeInt(placeQueue.size == 0 ? -1 : world.tile(placeQueue.last().x, placeQueue.last().y).packedPosition());
|
||||
data.writeByte(placeQueue.size == 0 ? -1 : placeQueue.last().recipe.id);
|
||||
writeBuilding(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput data, long time) throws IOException {
|
||||
super.read(data, time);
|
||||
int mined = data.readInt();
|
||||
int pp = data.readInt();
|
||||
byte rid = data.readByte();
|
||||
|
||||
readBuilding(data);
|
||||
|
||||
if(mined != -1){
|
||||
mineTile = world.tile(mined);
|
||||
}
|
||||
|
||||
if(pp != -1){
|
||||
Tile tile = world.tile(pp);
|
||||
placeQueue.clear();
|
||||
placeQueue.addLast(new BuildRequest(tile.x, tile.y, tile.getRotation(), Recipe.getByID(rid)));
|
||||
}
|
||||
}
|
||||
|
||||
public final UnitState
|
||||
|
||||
@@ -144,6 +144,16 @@ public class TypeIO {
|
||||
return world.tile(buffer.getInt());
|
||||
}
|
||||
|
||||
@WriteClass(Block.class)
|
||||
public static void writeBlock(ByteBuffer buffer, Block block){
|
||||
buffer.put((byte)block.id);
|
||||
}
|
||||
|
||||
@ReadClass(Block.class)
|
||||
public static Block readBlock(ByteBuffer buffer){
|
||||
return Block.getByID(buffer.get());
|
||||
}
|
||||
|
||||
@WriteClass(KickReason.class)
|
||||
public static void writeKick(ByteBuffer buffer, KickReason reason){
|
||||
buffer.put((byte)reason.ordinal());
|
||||
|
||||
@@ -5,7 +5,9 @@ import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
|
||||
import io.anuke.mindustry.io.Version;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.io.IOUtils;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@@ -122,6 +124,7 @@ public class Packets {
|
||||
public float x, y, pointerX, pointerY, rotation, baseRotation, xv, yv;
|
||||
public Tile mining;
|
||||
public boolean boosting, shooting;
|
||||
public BuildRequest currentRequest;
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer buffer) {
|
||||
@@ -145,6 +148,19 @@ public class Packets {
|
||||
buffer.putShort((short)(player.baseRotation*2));
|
||||
|
||||
buffer.putInt(player.getMineTile() == null ? -1 : player.getMineTile().packedPosition());
|
||||
|
||||
BuildRequest request = player.getCurrentRequest();
|
||||
|
||||
if(request != null){
|
||||
buffer.put(request.remove ? (byte)1 : 0);
|
||||
buffer.putInt(world.toPacked(request.x, request.y));
|
||||
if(!request.remove){
|
||||
buffer.put((byte)request.recipe.id);
|
||||
buffer.put((byte)request.rotation);
|
||||
}
|
||||
}else{
|
||||
buffer.put((byte)-1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,6 +180,21 @@ public class Packets {
|
||||
rotation = buffer.getShort()/2f;
|
||||
baseRotation = buffer.getShort()/2f;
|
||||
mining = world.tile(buffer.getInt());
|
||||
|
||||
byte type = buffer.get();
|
||||
if (type != -1) {
|
||||
int position = buffer.getInt();
|
||||
|
||||
if (type == 1) { //remove
|
||||
currentRequest = new BuildRequest(position % world.width(), position / world.width());
|
||||
} else { //place
|
||||
byte recipe = buffer.get();
|
||||
byte rotation = buffer.get();
|
||||
currentRequest = new BuildRequest(position % world.width(), position / world.width(), rotation, Recipe.getByID(recipe));
|
||||
}
|
||||
}else{
|
||||
currentRequest = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
package io.anuke.mindustry.world;
|
||||
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
|
||||
import io.anuke.mindustry.game.EventType.BlockBuildEvent;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.net.In;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.blocks.BreakBlock;
|
||||
import io.anuke.mindustry.world.blocks.BreakBlock.BreakEntity;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||
import io.anuke.ucore.core.Events;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
@@ -26,15 +17,10 @@ public class Build {
|
||||
private static final Rectangle hitrect = new Rectangle();
|
||||
|
||||
/**Returns block type that was broken, or null if unsuccesful.*/
|
||||
@Remote(targets = Loc.both, forward = true, called = Loc.server, in = In.blocks)
|
||||
public static void breakBlock(Player player, Team team, int x, int y){
|
||||
if(Net.server()){
|
||||
if(!validBreak(team, x, y)){
|
||||
return;
|
||||
}
|
||||
|
||||
team = player.getTeam();
|
||||
//throw new ValidateException(player, "An invalid block has been broken.");
|
||||
//@Remote(targets = Loc.both, forward = true, called = Loc.server, in = In.blocks)
|
||||
public static void beginBreak(Team team, int x, int y){
|
||||
if(!validBreak(team, x, y)){
|
||||
return;
|
||||
}
|
||||
|
||||
Tile tile = world.tile(x, y);
|
||||
@@ -46,59 +32,38 @@ public class Build {
|
||||
|
||||
Block previous = tile.block();
|
||||
|
||||
//remote players only
|
||||
if(player != null && !player.isLocal){
|
||||
player.getPlaceQueue().clear();
|
||||
player.getPlaceQueue().addFirst(new BuildRequest(x, y));
|
||||
}
|
||||
Block sub = Block.getByName("build" + previous.size);
|
||||
|
||||
Block sub = Block.getByName("break" + previous.size);
|
||||
tile.setBlock(sub);
|
||||
tile.<BuildEntity>entity().setDeconstruct(previous);
|
||||
tile.setTeam(team);
|
||||
|
||||
if(previous instanceof BuildBlock){
|
||||
BuildEntity build = tile.entity();
|
||||
if (previous.isMultiblock()) {
|
||||
int offsetx = -(previous.size - 1) / 2;
|
||||
int offsety = -(previous.size - 1) / 2;
|
||||
|
||||
tile.setBlock(sub);
|
||||
tile.setTeam(team);
|
||||
|
||||
BreakEntity breake = tile.entity();
|
||||
breake.set(build.recipe.result);
|
||||
breake.progress = 1.0 - build.progress;
|
||||
}else {
|
||||
tile.setBlock(sub);
|
||||
tile.<BreakEntity>entity().set(previous);
|
||||
tile.setTeam(team);
|
||||
|
||||
if (previous.isMultiblock()) {
|
||||
int offsetx = -(previous.size - 1) / 2;
|
||||
int offsety = -(previous.size - 1) / 2;
|
||||
|
||||
for (int dx = 0; dx < previous.size; dx++) {
|
||||
for (int dy = 0; dy < previous.size; dy++) {
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if (!(worldx == x && worldy == y)) {
|
||||
Tile toplace = world.tile(worldx, worldy);
|
||||
if (toplace != null) {
|
||||
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));
|
||||
toplace.setTeam(team);
|
||||
}
|
||||
for (int dx = 0; dx < previous.size; dx++) {
|
||||
for (int dy = 0; dy < previous.size; dy++) {
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if (!(worldx == x && worldy == y)) {
|
||||
Tile toplace = world.tile(worldx, worldy);
|
||||
if (toplace != null) {
|
||||
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));
|
||||
toplace.setTeam(team);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**Places a BuildBlock at this location. Call validPlace first.*/
|
||||
@Remote(targets = Loc.both, forward = true, called = Loc.server, in = In.blocks)
|
||||
public static void placeBlock(Player player, Team team, int x, int y, Recipe recipe, int rotation){
|
||||
if(Net.server()){
|
||||
if(!validPlace(team, x, y, recipe.result, rotation)){
|
||||
return;
|
||||
}
|
||||
|
||||
team = player.getTeam();
|
||||
//throw new ValidateException(player, "An invalid block has been placed.");
|
||||
/**Places a BuildBlock at this location.*/
|
||||
//@Remote(targets = Loc.both, forward = true, called = Loc.server, in = In.blocks)
|
||||
public static void beginPlace(Team team, int x, int y, Recipe recipe, int rotation){
|
||||
if(!validPlace(team, x, y, recipe.result, rotation)){
|
||||
return;
|
||||
}
|
||||
|
||||
Tile tile = world.tile(x, y);
|
||||
@@ -109,51 +74,33 @@ public class Build {
|
||||
Block result = recipe.result;
|
||||
Block previous = tile.block();
|
||||
|
||||
//remote players only
|
||||
if(player != null && !player.isLocal){
|
||||
player.getPlaceQueue().clear();
|
||||
player.getPlaceQueue().addFirst(new BuildRequest(x, y, rotation, recipe));
|
||||
}
|
||||
|
||||
Block sub = Block.getByName("build" + result.size);
|
||||
|
||||
if(previous instanceof BreakBlock){
|
||||
BreakEntity breake = tile.entity();
|
||||
tile.setBlock(sub, rotation);
|
||||
tile.<BuildEntity>entity().setConstruct(previous, recipe);
|
||||
tile.setTeam(team);
|
||||
|
||||
tile.setBlock(sub);
|
||||
tile.setTeam(team);
|
||||
if (result.isMultiblock()) {
|
||||
int offsetx = -(result.size - 1) / 2;
|
||||
int offsety = -(result.size - 1) / 2;
|
||||
|
||||
BuildEntity build = tile.entity();
|
||||
build.set(breake.previous, recipe);
|
||||
build.progress = 1.0 - breake.progress;
|
||||
}else{
|
||||
tile.setBlock(sub, rotation);
|
||||
tile.<BuildEntity>entity().set(previous, recipe);
|
||||
tile.setTeam(team);
|
||||
|
||||
if (result.isMultiblock()) {
|
||||
int offsetx = -(result.size - 1) / 2;
|
||||
int offsety = -(result.size - 1) / 2;
|
||||
|
||||
for (int dx = 0; dx < result.size; dx++) {
|
||||
for (int dy = 0; dy < result.size; dy++) {
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if (!(worldx == x && worldy == y)) {
|
||||
Tile toplace = world.tile(worldx, worldy);
|
||||
if (toplace != null) {
|
||||
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));
|
||||
toplace.setTeam(team);
|
||||
}
|
||||
for (int dx = 0; dx < result.size; dx++) {
|
||||
for (int dy = 0; dy < result.size; dy++) {
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if (!(worldx == x && worldy == y)) {
|
||||
Tile toplace = world.tile(worldx, worldy);
|
||||
if (toplace != null) {
|
||||
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));
|
||||
toplace.setTeam(team);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Team fteam = team;
|
||||
|
||||
threads.runDelay(() -> Events.fire(BlockBuildEvent.class, fteam, tile));
|
||||
threads.runDelay(() -> Events.fire(BlockBuildEvent.class, team, tile));
|
||||
}
|
||||
|
||||
/**Returns whether a tile can be placed at this location by this team.*/
|
||||
@@ -226,7 +173,7 @@ public class Build {
|
||||
public static boolean validBreak(Team team, int x, int y) {
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
return tile != null && !tile.block().unbreakable && !(tile.target().block() instanceof BreakBlock)
|
||||
return tile != null && !tile.block().unbreakable
|
||||
&& (!tile.isLinked() || !tile.getLinked().block().unbreakable) && tile.breakable() && (tile.getTeam() == Team.none || tile.getTeam() == team);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
package io.anuke.mindustry.world.blocks;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.mindustry.content.fx.ExplosionFx;
|
||||
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.effect.RubbleDecal;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.gen.CallBlocks;
|
||||
import io.anuke.mindustry.graphics.Layer;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.mindustry.input.CursorType;
|
||||
import io.anuke.mindustry.net.In;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.BarType;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.meta.BlockBar;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class BreakBlock extends Block {
|
||||
private static final float decaySpeedScl = 6f;
|
||||
|
||||
public BreakBlock(String name) {
|
||||
super(name);
|
||||
solidifes = true;
|
||||
update = true;
|
||||
size = Integer.parseInt(name.charAt(name.length()-1) + "");
|
||||
health = 1;
|
||||
layer = Layer.placement;
|
||||
consumesTap = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolidFor(Tile tile) {
|
||||
BreakEntity entity = tile.entity();
|
||||
return entity.previous == null || entity.previous.solid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CursorType getCursor(Tile tile) {
|
||||
return CursorType.hand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tapped(Tile tile, Player player) {
|
||||
CallBlocks.onBreakSelect(player, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBars(){
|
||||
bars.replace(new BlockBar(BarType.health, true, tile -> (float)tile.<BreakEntity>entity().progress));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(Tile tile){
|
||||
Effects.effect(ExplosionFx.blockExplosionSmoke, tile);
|
||||
|
||||
if(!tile.floor().solid && !tile.floor().isLiquid){
|
||||
RubbleDecal.create(tile.drawx(), tile.drawy(), size);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterDestroyed(Tile tile, TileEntity e){
|
||||
BreakEntity entity = (BreakEntity)e;
|
||||
|
||||
if(entity != null && entity.previous != null && entity.previous.synthetic()){
|
||||
tile.setBlock(entity.previous);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Tile tile){
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLayer(Tile tile) {
|
||||
BreakEntity entity = tile.entity();
|
||||
|
||||
Shaders.blockbuild.color = Palette.remove;
|
||||
|
||||
if(entity.previous == null) return;
|
||||
|
||||
for(TextureRegion region : entity.previous.getBlockIcon()){
|
||||
Shaders.blockbuild.region = region;
|
||||
Shaders.blockbuild.progress = (float)(1f-entity.progress); //progress reversed
|
||||
Shaders.blockbuild.apply();
|
||||
|
||||
Draw.rect(region, tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0);
|
||||
|
||||
Graphics.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawShadow(Tile tile) {
|
||||
BreakEntity entity = tile.entity();
|
||||
|
||||
if(entity.previous instanceof BreakBlock || entity.previous == null || entity.previous.shadowRegion == null){
|
||||
return;
|
||||
}
|
||||
|
||||
entity.previous.drawShadow(tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Tile tile) {
|
||||
BreakEntity entity = tile.entity();
|
||||
|
||||
if(entity.progress >= 1f){
|
||||
CallBlocks.onBreakFinish(tile);
|
||||
}else if(entity.progress < 0f){
|
||||
CallBlocks.onBreakDeath(tile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity getEntity() {
|
||||
return new BreakEntity();
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server, in = In.blocks)
|
||||
public static void onBreakDeath(Tile tile){
|
||||
BreakEntity entity = tile.entity();
|
||||
|
||||
Team team = tile.getTeam();
|
||||
tile.setBlock(entity.previous);
|
||||
tile.setTeam(team);
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server, in = In.blocks)
|
||||
public static void onBreakFinish(Tile tile){
|
||||
|
||||
if(tile.entity instanceof BreakEntity){
|
||||
BreakEntity entity = tile.entity();
|
||||
if(entity.previous != null){
|
||||
Effects.effect(Fx.breakBlock, tile.drawx(), tile.drawy(), entity.previous.size);
|
||||
}
|
||||
}
|
||||
|
||||
world.removeBlock(tile);
|
||||
}
|
||||
|
||||
@Remote(called = Loc.both, targets = Loc.both, in = In.blocks, forward = true)
|
||||
public static void onBreakSelect(Player player, Tile tile){
|
||||
if(player == null || !(tile.entity instanceof BreakEntity)) return;
|
||||
|
||||
player.getPlaceQueue().clear();
|
||||
player.addBuildRequest(new BuildRequest(tile.x, tile.y));
|
||||
}
|
||||
|
||||
public class BreakEntity extends TileEntity{
|
||||
private double[] accumulator;
|
||||
|
||||
public double progress = 0;
|
||||
public Block previous;
|
||||
public float breakTime;
|
||||
|
||||
public void addProgress(TileEntity core, Unit unit, double add){
|
||||
Recipe recipe = Recipe.getByResult(previous);
|
||||
|
||||
if(recipe != null) {
|
||||
ItemStack[] requirements = recipe.requirements;
|
||||
|
||||
for (int i = 0; i < requirements.length; i++) {
|
||||
accumulator[i] += requirements[i].amount * add / 2f; //add scaled amount progressed to the accumulator
|
||||
int amount = (int) (accumulator[i]); //get amount
|
||||
|
||||
if (amount > 0) { //if it's positive, add it to the core
|
||||
int accepting = core.tile.block().acceptStack(requirements[i].item, amount, core.tile, unit);
|
||||
core.tile.block().handleStack(requirements[i].item, amount, core.tile, unit);
|
||||
|
||||
accumulator[i] -= accepting;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
progress += add;
|
||||
|
||||
if(progress > 1.0001f){
|
||||
progress = 1.0001f;
|
||||
}
|
||||
}
|
||||
|
||||
public float progress(){
|
||||
return (float)progress;
|
||||
}
|
||||
|
||||
public void set(Block previous){
|
||||
this.previous = previous;
|
||||
if(Recipe.getByResult(previous) != null){
|
||||
this.accumulator = new double[Recipe.getByResult(previous).requirements.length];
|
||||
this.breakTime = Recipe.getByResult(previous).cost;
|
||||
}else{
|
||||
this.breakTime = 20f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import io.anuke.mindustry.content.fx.ExplosionFx;
|
||||
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.effect.RubbleDecal;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
@@ -16,6 +17,7 @@ import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.mindustry.input.CursorType;
|
||||
import io.anuke.mindustry.net.In;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.BarType;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
@@ -25,16 +27,15 @@ import io.anuke.mindustry.world.meta.BlockBar;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static io.anuke.mindustry.Vars.threads;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class BuildBlock extends Block {
|
||||
private static final float decaySpeedScl = 6f;
|
||||
|
||||
public BuildBlock(String name) {
|
||||
super(name);
|
||||
update = true;
|
||||
@@ -48,7 +49,7 @@ public class BuildBlock extends Block {
|
||||
@Override
|
||||
public boolean isSolidFor(Tile tile) {
|
||||
BuildEntity entity = tile.entity();
|
||||
return entity == null || entity.recipe ==null || entity.recipe.result.solid || entity.previous.solid;
|
||||
return entity == null || entity.recipe == null || entity.recipe.result.solid || entity.previous.solid;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +59,13 @@ public class BuildBlock extends Block {
|
||||
|
||||
@Override
|
||||
public void tapped(Tile tile, Player player) {
|
||||
CallBlocks.onBuildSelect(player, tile);
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
//if the target is constructible, begin constructing
|
||||
if(entity.recipe != null){
|
||||
player.clearBuilding();
|
||||
player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.getRotation(), entity.recipe));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +86,7 @@ public class BuildBlock extends Block {
|
||||
public void afterDestroyed(Tile tile, TileEntity e){
|
||||
BuildEntity entity = (BuildEntity)e;
|
||||
|
||||
if(entity.previous.synthetic()){
|
||||
if(entity.previous != null && entity.previous.synthetic()){
|
||||
tile.setBlock(entity.previous);
|
||||
}
|
||||
}
|
||||
@@ -88,10 +95,13 @@ public class BuildBlock extends Block {
|
||||
public void draw(Tile tile){
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
if(entity.previous != null && entity.previous.synthetic()) {
|
||||
for (TextureRegion region : entity.previous.getBlockIcon()) {
|
||||
Draw.rect(region, tile.drawx(), tile.drawy(), entity.recipe.result.rotate ? tile.getRotation() * 90 : 0);
|
||||
}
|
||||
//When breaking, don't draw the previous block... since it's the thing you were breaking
|
||||
if(entity.recipe != null && entity.previous == entity.recipe.result){
|
||||
return;
|
||||
}
|
||||
|
||||
for (TextureRegion region : entity.previous.getBlockIcon()) {
|
||||
Draw.rect(region, tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,12 +111,16 @@ public class BuildBlock extends Block {
|
||||
|
||||
Shaders.blockbuild.color = Palette.accent;
|
||||
|
||||
for(TextureRegion region : entity.recipe.result.getBlockIcon()){
|
||||
Block target = entity.recipe == null ? entity.previous : entity.recipe.result;
|
||||
|
||||
if(target == null) return;
|
||||
|
||||
for(TextureRegion region : target.getBlockIcon()){
|
||||
Shaders.blockbuild.region = region;
|
||||
Shaders.blockbuild.progress = (float)entity.progress;
|
||||
Shaders.blockbuild.apply();
|
||||
|
||||
Draw.rect(region, tile.drawx(), tile.drawy(), entity.recipe.result.rotate ? tile.getRotation() * 90 : 0);
|
||||
Draw.rect(region, tile.drawx(), tile.drawy(), target.rotate ? tile.getRotation() * 90 : 0);
|
||||
|
||||
Graphics.flush();
|
||||
}
|
||||
@@ -116,26 +130,16 @@ public class BuildBlock extends Block {
|
||||
public void drawShadow(Tile tile) {
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
if(entity.recipe != null && entity.recipe.result != null){
|
||||
if(entity.recipe != null){
|
||||
entity.recipe.result.drawShadow(tile);
|
||||
}else if(entity.previous != null){
|
||||
entity.previous.drawShadow(tile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Tile tile) {
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
if(entity.progress >= 1f){
|
||||
CallBlocks.onBuildFinish(tile, entity.lastBuilder);
|
||||
}else if(entity.progress < 0f){
|
||||
CallBlocks.onBuildDeath(tile);
|
||||
}
|
||||
|
||||
if(!entity.updated && entity.recipe != null){
|
||||
entity.progress -= 1f/entity.recipe.cost/decaySpeedScl;
|
||||
}
|
||||
|
||||
entity.updated = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,77 +148,85 @@ public class BuildBlock extends Block {
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server, in = In.blocks)
|
||||
public static void onBuildDeath(Tile tile){
|
||||
if(tile.entity == null) return;
|
||||
tile.entity.damage(tile.entity.health + 1);
|
||||
public static void onDeconstructFinish(Tile tile, Block block){
|
||||
Effects.effect(Fx.breakBlock, tile.drawx(), tile.drawy(), block.size);
|
||||
world.removeBlock(tile);
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server, in = In.blocks)
|
||||
public static void onBuildFinish(Tile tile, Player lastBuilder){
|
||||
if(tile.entity == null || !(tile.entity instanceof BuildEntity)) return;
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
public static void onConstructFinish(Tile tile, Block block, int builderID){
|
||||
Team team = tile.getTeam();
|
||||
tile.setBlock(entity.recipe.result);
|
||||
tile.setBlock(block);
|
||||
tile.setTeam(team);
|
||||
Effects.effect(Fx.placeBlock, tile.drawx(), tile.drawy(), entity.recipe.result.size);
|
||||
Effects.effect(Fx.placeBlock, tile.drawx(), tile.drawy(), block.size);
|
||||
|
||||
//last builder was this local client player, call placed()
|
||||
if(lastBuilder != null && lastBuilder.isLocal){
|
||||
if(!headless && builderID == players[0].id){
|
||||
//this is run delayed, since if this is called on the server, all clients need to recieve the onBuildFinish()
|
||||
//event first before they can recieve the placed() event modification results
|
||||
threads.runDelay(() -> tile.block().placed(tile));
|
||||
}
|
||||
}
|
||||
|
||||
@Remote(called = Loc.both, targets = Loc.both, in = In.blocks, forward = true)
|
||||
public static void onBuildSelect(Player player, Tile tile){
|
||||
if(player == null || !(tile.entity instanceof BuildEntity)) return;
|
||||
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
player.getPlaceQueue().clear();
|
||||
player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.getRotation(), entity.recipe));
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server, targets = Loc.both, in = In.blocks, forward = true)
|
||||
public static void onBuildDeselect(Player player){
|
||||
if(player == null) return;
|
||||
|
||||
player.getPlaceQueue().clear();
|
||||
}
|
||||
|
||||
public class BuildEntity extends TileEntity{
|
||||
/**The recipe of the block that is being constructed.
|
||||
* If there is no recipe for this block, as is the case with rocks, 'previous' is used.*/
|
||||
public Recipe recipe;
|
||||
|
||||
public double progress = 0;
|
||||
public double lastProgress;
|
||||
public double buildCost;
|
||||
/**The block that used to be here.
|
||||
* If a non-recipe block is being deconstructed, this is the block that is being deconstructed.*/
|
||||
public Block previous;
|
||||
public Player lastBuilder;
|
||||
|
||||
private double[] accumulator;
|
||||
private boolean updated;
|
||||
|
||||
public void addProgress(InventoryModule inventory, double amount){
|
||||
double maxProgress = checkRequired(inventory, amount);
|
||||
public void construct(Unit builder, TileEntity core, double amount){
|
||||
double maxProgress = checkRequired(core.items, amount);
|
||||
|
||||
for (int i = 0; i < recipe.requirements.length; i++) {
|
||||
accumulator[i] += recipe.requirements[i].amount*maxProgress; //add min amount progressed to the accumulator
|
||||
}
|
||||
|
||||
maxProgress = checkRequired(inventory, maxProgress);
|
||||
maxProgress = checkRequired(core.items, maxProgress);
|
||||
|
||||
progress += maxProgress;
|
||||
progress = Mathf.clamp(progress + maxProgress);
|
||||
|
||||
lastProgress = maxProgress;
|
||||
updated = true;
|
||||
|
||||
if(progress > 1.0001f){
|
||||
progress = 1.0001f;
|
||||
if(progress >= 1f){
|
||||
CallBlocks.onConstructFinish(tile, recipe.result, builder.getID());
|
||||
}
|
||||
}
|
||||
|
||||
public double checkRequired(InventoryModule inventory, double amount){
|
||||
public void deconstruct(Unit builder, TileEntity core, double amount){
|
||||
Recipe recipe = Recipe.getByResult(previous);
|
||||
|
||||
if(recipe != null) {
|
||||
ItemStack[] requirements = recipe.requirements;
|
||||
|
||||
for (int i = 0; i < requirements.length; i++) {
|
||||
accumulator[i] += requirements[i].amount * amount / 2f; //add scaled amount progressed to the accumulator
|
||||
int accumulated = (int) (accumulator[i]); //get amount
|
||||
|
||||
if (amount > 0) { //if it's positive, add it to the core
|
||||
int accepting = core.tile.block().acceptStack(requirements[i].item, accumulated, core.tile, builder);
|
||||
core.tile.block().handleStack(requirements[i].item, accumulated, core.tile, builder);
|
||||
|
||||
accumulator[i] -= accepting;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
progress = Mathf.clamp(progress - amount);
|
||||
|
||||
if(progress <= 0){
|
||||
CallBlocks.onDeconstructFinish(tile, recipe == null ? previous : recipe.result);
|
||||
}
|
||||
}
|
||||
|
||||
private double checkRequired(InventoryModule inventory, double amount){
|
||||
double maxProgress = amount;
|
||||
|
||||
for(int i = 0; i < recipe.requirements.length; i ++){
|
||||
@@ -243,11 +255,23 @@ public class BuildBlock extends Block {
|
||||
return (float)progress;
|
||||
}
|
||||
|
||||
public void set(Block previous, Recipe recipe){
|
||||
updated = true;
|
||||
public void setConstruct(Block previous, Recipe recipe){
|
||||
this.recipe = recipe;
|
||||
this.previous = previous;
|
||||
this.accumulator = new double[recipe.requirements.length];
|
||||
this.buildCost = recipe.cost;
|
||||
}
|
||||
|
||||
public void setDeconstruct(Block previous){
|
||||
this.previous = previous;
|
||||
this.progress = 1f;
|
||||
if(Recipe.getByResult(previous) != null){
|
||||
this.recipe = Recipe.getByResult(previous);
|
||||
this.accumulator = new double[Recipe.getByResult(previous).requirements.length];
|
||||
this.buildCost = Recipe.getByResult(previous).cost;
|
||||
}else{
|
||||
this.buildCost = 20f; //default no-recipe build cost is 20
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -110,6 +110,7 @@ public abstract class Turret extends Block{
|
||||
stats.add(BlockStat.inaccuracy, (int)inaccuracy, StatUnit.degrees);
|
||||
stats.add(BlockStat.reload, 60f/reload, StatUnit.seconds);
|
||||
stats.add(BlockStat.shots, shots, StatUnit.none);
|
||||
stats.add(BlockStat.targetsAir, targetAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.anuke.mindustry.world.blocks.power;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import io.anuke.mindustry.content.fx.BlockFx;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
@@ -29,6 +30,7 @@ public abstract class ItemGenerator extends PowerGenerator {
|
||||
protected Effect generateEffect = BlockFx.generatespark, explodeEffect =
|
||||
BlockFx.generatespark;
|
||||
protected Color heatColor = Color.valueOf("ff9b59");
|
||||
protected TextureRegion topRegion;
|
||||
|
||||
public ItemGenerator(String name) {
|
||||
super(name);
|
||||
@@ -36,6 +38,12 @@ public abstract class ItemGenerator extends PowerGenerator {
|
||||
hasItems = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
super.load();
|
||||
topRegion = Draw.region(name + "-top");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStats() {
|
||||
super.setStats();
|
||||
@@ -61,7 +69,7 @@ public abstract class ItemGenerator extends PowerGenerator {
|
||||
float alpha = (entity.items.totalItems() > 0 ? 1f : Mathf.clamp(entity.generateTime));
|
||||
alpha = alpha * 0.7f + Mathf.absin(Timers.time(), 12f, 0.3f) * alpha;
|
||||
Draw.alpha(alpha);
|
||||
Draw.rect(name + "-top", tile.worldx(), tile.worldy());
|
||||
Draw.rect(topRegion, tile.drawx(), tile.drawy());
|
||||
Draw.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,11 @@ public class PowerDistributor extends PowerBlock {
|
||||
}
|
||||
|
||||
protected boolean shouldDistribute(Tile tile, Tile other) {
|
||||
other = other.target();
|
||||
//only generators can distribute to other generators
|
||||
return (!(other.block() instanceof PowerGenerator) || tile.block() instanceof PowerGenerator)
|
||||
&& other.entity != null
|
||||
&& other.block().hasPower
|
||||
&& other.entity.power.amount / other.block().powerCapacity < tile.entity.power.amount / powerCapacity;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ public enum BlockStat {
|
||||
shots(StatCategory.shooting),
|
||||
reload(StatCategory.shooting),
|
||||
powerShot(StatCategory.shooting),
|
||||
|
||||
targetsAir(StatCategory.shooting)
|
||||
,
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -5,10 +5,7 @@ import com.badlogic.gdx.utils.OrderedMap;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.world.meta.values.ItemValue;
|
||||
import io.anuke.mindustry.world.meta.values.LiquidValue;
|
||||
import io.anuke.mindustry.world.meta.values.NumberValue;
|
||||
import io.anuke.mindustry.world.meta.values.StringValue;
|
||||
import io.anuke.mindustry.world.meta.values.*;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
import io.anuke.ucore.util.Log;
|
||||
|
||||
@@ -24,6 +21,11 @@ public class BlockStats {
|
||||
add(stat, new NumberValue(value, unit));
|
||||
}
|
||||
|
||||
/**Adds a single y/n boolean value.*/
|
||||
public void add(BlockStat stat, boolean value){
|
||||
add(stat, new BooleanValue(value));
|
||||
}
|
||||
|
||||
/**Adds an item value.*/
|
||||
public void add(BlockStat stat, Item item){
|
||||
add(stat, new ItemValue(new ItemStack(item, 1)));
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.anuke.mindustry.world.meta.values;
|
||||
|
||||
import io.anuke.mindustry.world.meta.StatValue;
|
||||
import io.anuke.ucore.scene.ui.layout.Table;
|
||||
|
||||
public class BooleanValue implements StatValue {
|
||||
private final boolean value;
|
||||
|
||||
public BooleanValue(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(Table table) {
|
||||
table.add(!value ? "$text.no" : "$text.yes");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user