Implemented multiblocks, added nuclear reactor, many internals changed
This commit is contained in:
BIN
core/assets-raw/sprites/blocks/nuclearreactor-icon.png
Normal file
BIN
core/assets-raw/sprites/blocks/nuclearreactor-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 279 B |
BIN
core/assets-raw/sprites/blocks/nuclearreactor.png
Normal file
BIN
core/assets-raw/sprites/blocks/nuclearreactor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 380 B |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 40 KiB |
@@ -23,9 +23,7 @@ import io.anuke.mindustry.io.SaveIO;
|
|||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.ItemStack;
|
import io.anuke.mindustry.resource.ItemStack;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.Tile;
|
|
||||||
import io.anuke.mindustry.world.World;
|
|
||||||
import io.anuke.ucore.UCore;
|
import io.anuke.ucore.UCore;
|
||||||
import io.anuke.ucore.core.*;
|
import io.anuke.ucore.core.*;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
@@ -52,11 +50,12 @@ public class Control extends Module{
|
|||||||
float respawntime;
|
float respawntime;
|
||||||
|
|
||||||
public Control(){
|
public Control(){
|
||||||
|
|
||||||
if(Mindustry.args.contains("-debug", false)){
|
if(Mindustry.args.contains("-debug", false)){
|
||||||
Vars.debug = true;
|
Vars.debug = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UCore.log("Total blocks loaded: " + Block.getAllBlocks().size);
|
||||||
|
|
||||||
Gdx.input.setCatchBackKey(true);
|
Gdx.input.setCatchBackKey(true);
|
||||||
|
|
||||||
if(android){
|
if(android){
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import io.anuke.mindustry.GameState.State;
|
|||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.input.AndroidInput;
|
import io.anuke.mindustry.input.AndroidInput;
|
||||||
|
import io.anuke.mindustry.input.Input;
|
||||||
import io.anuke.mindustry.input.PlaceMode;
|
import io.anuke.mindustry.input.PlaceMode;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.World;
|
import io.anuke.mindustry.world.World;
|
||||||
@@ -294,22 +295,27 @@ public class Renderer extends RendererModule{
|
|||||||
|
|
||||||
if(android){
|
if(android){
|
||||||
Vector2 vec = Graphics.world(AndroidInput.mousex, AndroidInput.mousey);
|
Vector2 vec = Graphics.world(AndroidInput.mousex, AndroidInput.mousey);
|
||||||
x = Mathf.round2(vec.x, tilesize);
|
|
||||||
y = Mathf.round2(vec.y, tilesize);
|
|
||||||
tilex = Mathf.scl2(vec.x, tilesize);
|
tilex = Mathf.scl2(vec.x, tilesize);
|
||||||
tiley = Mathf.scl2(vec.y, tilesize);
|
tiley = Mathf.scl2(vec.y, tilesize);
|
||||||
}else{
|
}else{
|
||||||
x = Mathf.round2(Graphics.mouseWorld().x, tilesize);
|
tilex = Input.tilex();
|
||||||
y = Mathf.round2(Graphics.mouseWorld().y, tilesize);
|
tiley = Input.tiley();
|
||||||
tilex = World.tilex();
|
|
||||||
tiley = World.tiley();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x = tilex*tilesize;
|
||||||
|
y = tiley*tilesize;
|
||||||
|
|
||||||
boolean valid = World.validPlace(tilex, tiley, player.recipe.result);
|
boolean valid = World.validPlace(tilex, tiley, player.recipe.result);
|
||||||
|
|
||||||
|
Vector2 offset = player.recipe.result.getPlaceOffset();
|
||||||
|
|
||||||
|
float si = MathUtils.sin(Timers.time() / 6f) + 1;
|
||||||
|
|
||||||
Draw.color(valid ? Color.PURPLE : Color.SCARLET);
|
Draw.color(valid ? Color.PURPLE : Color.SCARLET);
|
||||||
Draw.thickness(2f);
|
Draw.thickness(2f);
|
||||||
Draw.square(x, y, tilesize / 2 + MathUtils.sin(Timers.time() / 6f) + 1);
|
Draw.linecrect(x + offset.x, y + offset.y,
|
||||||
|
tilesize * player.recipe.result.width + si,
|
||||||
|
tilesize * player.recipe.result.height + si);
|
||||||
|
|
||||||
player.recipe.result.drawPlace(tilex, tiley, valid);
|
player.recipe.result.drawPlace(tilex, tiley, valid);
|
||||||
|
|
||||||
@@ -334,9 +340,9 @@ public class Renderer extends RendererModule{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//block breaking
|
//block breaking
|
||||||
if(Inputs.buttonDown(Buttons.RIGHT) && World.validBreak(World.tilex(), World.tiley())){
|
if(Inputs.buttonDown(Buttons.RIGHT) && World.validBreak(Input.tilex(), Input.tiley())){
|
||||||
Tile tile = World.cursorTile();
|
Tile tile = World.tile(Input.tilex(), Input.tiley());
|
||||||
Draw.color(Color.YELLOW, Color.SCARLET, player.breaktime / tile.block().breaktime);
|
Draw.color(Color.YELLOW, Color.SCARLET, player.breaktime / tile.getBreakTime());
|
||||||
Draw.square(tile.worldx(), tile.worldy(), 4);
|
Draw.square(tile.worldx(), tile.worldy(), 4);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}else if(android && player.breaktime > 0){ //android block breaking
|
}else if(android && player.breaktime > 0){ //android block breaking
|
||||||
@@ -345,7 +351,7 @@ public class Renderer extends RendererModule{
|
|||||||
if(World.validBreak(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize))){
|
if(World.validBreak(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize))){
|
||||||
Tile tile = World.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize));
|
Tile tile = World.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize));
|
||||||
|
|
||||||
float fract = player.breaktime / tile.block().breaktime;
|
float fract = player.breaktime / tile.getBreakTime();
|
||||||
Draw.color(Color.YELLOW, Color.SCARLET, fract);
|
Draw.color(Color.YELLOW, Color.SCARLET, fract);
|
||||||
Draw.circle(tile.worldx(), tile.worldy(), 4 + (1f - fract) * 26);
|
Draw.circle(tile.worldx(), tile.worldy(), 4 + (1f - fract) * 26);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
@@ -353,13 +359,20 @@ public class Renderer extends RendererModule{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(player.recipe == null && !ui.hasMouse()){
|
if(player.recipe == null && !ui.hasMouse()){
|
||||||
Tile tile = World.cursorTile();
|
Tile tile = World.tile(Input.tilex(), Input.tiley());
|
||||||
|
|
||||||
if(tile != null && tile.block() != Blocks.air){
|
if(tile != null && tile.block() != Blocks.air){
|
||||||
if(tile.entity != null)
|
Tile target = tile;
|
||||||
drawHealth(tile.entity.x, tile.entity.y, tile.entity.health, tile.entity.maxhealth);
|
if(tile.isLinked())
|
||||||
|
target = tile.getLinked();
|
||||||
|
|
||||||
tile.block().drawPixelOverlay(tile);
|
Vector2 offset = target.block().getPlaceOffset();
|
||||||
|
|
||||||
|
if(target.entity != null)
|
||||||
|
drawHealth(target.entity.x + offset.x, target.entity.y - 3f - target.block().height/2f * Vars.tilesize + offset.y,
|
||||||
|
target.entity.health, target.entity.maxhealth);
|
||||||
|
|
||||||
|
target.block().drawPixelOverlay(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,9 +383,9 @@ public class Renderer extends RendererModule{
|
|||||||
DestructibleEntity dest = ((DestructibleEntity) entity);
|
DestructibleEntity dest = ((DestructibleEntity) entity);
|
||||||
|
|
||||||
if(dest instanceof Player && Vars.snapCamera && smoothcam){
|
if(dest instanceof Player && Vars.snapCamera && smoothcam){
|
||||||
drawHealth((int)dest.x, (int)dest.y, dest.health, dest.maxhealth);
|
drawHealth((int)dest.x, (int)dest.y - 7f, dest.health, dest.maxhealth);
|
||||||
}else{
|
}else{
|
||||||
drawHealth(dest.x, dest.y, dest.health, dest.maxhealth);
|
drawHealth(dest.x, dest.y - 7f, dest.health, dest.maxhealth);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -385,7 +398,6 @@ public class Renderer extends RendererModule{
|
|||||||
|
|
||||||
public void drawBar(Color color, float x, float y, float fraction){
|
public void drawBar(Color color, float x, float y, float fraction){
|
||||||
float len = 3;
|
float len = 3;
|
||||||
float offset = 7;
|
|
||||||
|
|
||||||
float w = (int) (len * 2 * fraction) + 0.5f;
|
float w = (int) (len * 2 * fraction) + 0.5f;
|
||||||
|
|
||||||
@@ -394,13 +406,13 @@ public class Renderer extends RendererModule{
|
|||||||
|
|
||||||
Draw.thickness(3f);
|
Draw.thickness(3f);
|
||||||
Draw.color(Color.SLATE);
|
Draw.color(Color.SLATE);
|
||||||
Draw.line(x - len + 1, y - offset, x + len + 1.5f, y - offset);
|
Draw.line(x - len + 1, y, x + len + 1.5f, y);
|
||||||
Draw.thickness(1f);
|
Draw.thickness(1f);
|
||||||
Draw.color(Color.BLACK);
|
Draw.color(Color.BLACK);
|
||||||
Draw.line(x - len + 1, y - offset, x + len + 0.5f, y - offset);
|
Draw.line(x - len + 1, y, x + len + 0.5f, y);
|
||||||
Draw.color(color);
|
Draw.color(color);
|
||||||
if(w >= 1)
|
if(w >= 1)
|
||||||
Draw.line(x - len + 1, y - offset, x - len + w, y - offset);
|
Draw.line(x - len + 1, y, x - len + w, y);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -253,7 +253,9 @@ public class UI extends SceneModule{
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for(Recipe r : recipes){
|
for(Recipe r : recipes){
|
||||||
ImageButton image = new ImageButton(Draw.region(r.result.name()), "select");
|
TextureRegion region = Draw.hasRegion(r.result.name() + "-icon") ?
|
||||||
|
Draw.region(r.result.name() + "-icon") : Draw.region(r.result.name());
|
||||||
|
ImageButton image = new ImageButton(region, "select");
|
||||||
|
|
||||||
image.clicked(()->{
|
image.clicked(()->{
|
||||||
if(player.recipe == r){
|
if(player.recipe == r){
|
||||||
@@ -573,8 +575,10 @@ public class UI extends SceneModule{
|
|||||||
|
|
||||||
desctable.row();
|
desctable.row();
|
||||||
|
|
||||||
|
TextureRegion region = Draw.hasRegion(recipe.result.name() + "-icon") ?
|
||||||
|
Draw.region(recipe.result.name() + "-icon") : Draw.region(recipe.result.name());
|
||||||
|
|
||||||
header.addImage(Draw.region(recipe.result.name)).size(8*5).padTop(4).units(Unit.dp);
|
header.addImage(region).size(8*5).padTop(4).units(Unit.dp);
|
||||||
header.add(recipe.result.formalName).padLeft(4).units(Unit.dp);
|
header.add(recipe.result.formalName).padLeft(4).units(Unit.dp);
|
||||||
|
|
||||||
desctable.add().pad(2).units(Unit.dp);
|
desctable.add().pad(2).units(Unit.dp);
|
||||||
|
|||||||
@@ -32,10 +32,25 @@ public class Bullet extends BulletEntity{
|
|||||||
int tilex = Mathf.scl2(x, tilesize);
|
int tilex = Mathf.scl2(x, tilesize);
|
||||||
int tiley = Mathf.scl2(y, tilesize);
|
int tiley = Mathf.scl2(y, tilesize);
|
||||||
Tile tile = World.tile(tilex, tiley);
|
Tile tile = World.tile(tilex, tiley);
|
||||||
|
TileEntity targetEntity = null;
|
||||||
|
|
||||||
if(tile != null && tile.entity != null &&
|
if(tile != null){
|
||||||
tile.entity.collide(this) && !tile.entity.dead){
|
if(tile.entity != null && tile.entity.collide(this) && !tile.entity.dead){
|
||||||
tile.entity.collision(this);
|
targetEntity = tile.entity;
|
||||||
|
}else{
|
||||||
|
//make sure to check for linked block collisions
|
||||||
|
//TODO move this to the block class?
|
||||||
|
Tile linked = tile.getLinked();
|
||||||
|
if(linked != null &&
|
||||||
|
linked.entity != null && linked.entity.collide(this) && !linked.entity.dead){
|
||||||
|
targetEntity = linked.entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(targetEntity != null){
|
||||||
|
|
||||||
|
targetEntity.collision(this);
|
||||||
remove();
|
remove();
|
||||||
type.removed(this);
|
type.removed(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,11 +50,14 @@ public class TileEntity extends Entity{
|
|||||||
Vars.control.coreDestroyed();
|
Vars.control.coreDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.setBlock(Blocks.air);
|
Block block = tile.block();
|
||||||
Effects.shake(4f, 4f, this);
|
|
||||||
Effects.effect("explosion", this);
|
|
||||||
|
|
||||||
Effects.sound("break", this);
|
block.onDestroyed(tile);
|
||||||
|
for(Tile other : tile.getLinkedTiles()){
|
||||||
|
other.setBlock(Blocks.air);
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.setBlock(Blocks.air);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void collision(Bullet other){
|
public void collision(Bullet other){
|
||||||
|
|||||||
@@ -7,12 +7,10 @@ import com.badlogic.gdx.Input.Keys;
|
|||||||
import com.badlogic.gdx.InputAdapter;
|
import com.badlogic.gdx.InputAdapter;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.resource.ItemStack;
|
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.World;
|
import io.anuke.mindustry.world.World;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.ucore.core.Graphics;
|
||||||
import io.anuke.ucore.core.*;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
@@ -60,15 +58,8 @@ public class AndroidInput extends InputAdapter{
|
|||||||
|
|
||||||
if(player.breaktime >= tile.block().breaktime){
|
if(player.breaktime >= tile.block().breaktime){
|
||||||
brokeBlock = true;
|
brokeBlock = true;
|
||||||
if(tile.block().drops != null){
|
World.breakBlock(tile.x, tile.y);
|
||||||
Vars.control.addItem(tile.block().drops.item, tile.block().drops.amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
Effects.effect("break", tile.worldx(), tile.worldy());
|
|
||||||
Effects.shake(3f, 1f, player);
|
|
||||||
tile.setBlock(Blocks.air);
|
|
||||||
player.breaktime = 0f;
|
player.breaktime = 0f;
|
||||||
Sounds.play("break");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,21 +72,7 @@ public class AndroidInput extends InputAdapter{
|
|||||||
if(player.recipe != null &&
|
if(player.recipe != null &&
|
||||||
World.validPlace(tilex, tiley, player.recipe.result)){
|
World.validPlace(tilex, tiley, player.recipe.result)){
|
||||||
|
|
||||||
Tile tile = World.tile(tilex, tiley);
|
World.placeBlock(tilex, tiley);
|
||||||
|
|
||||||
if(tile == null)
|
|
||||||
return; //just in case
|
|
||||||
|
|
||||||
tile.setBlock(player.recipe.result);
|
|
||||||
tile.rotation = (byte)player.rotation;
|
|
||||||
|
|
||||||
Effects.effect("place", tilex*tilesize, tiley*tilesize);
|
|
||||||
Effects.shake(2f, 2f, player);
|
|
||||||
Sounds.play("place");
|
|
||||||
|
|
||||||
for(ItemStack stack : player.recipe.requirements){
|
|
||||||
Vars.control.removeItem(stack);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,17 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
|
|
||||||
import com.badlogic.gdx.Input.Buttons;
|
import com.badlogic.gdx.Input.Buttons;
|
||||||
import com.badlogic.gdx.Input.Keys;
|
import com.badlogic.gdx.Input.Keys;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.resource.ItemStack;
|
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.World;
|
import io.anuke.mindustry.world.World;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.ucore.core.Graphics;
|
||||||
import io.anuke.ucore.core.*;
|
import io.anuke.ucore.core.Inputs;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.scene.utils.Cursors;
|
import io.anuke.ucore.scene.utils.Cursors;
|
||||||
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
public class Input{
|
public class Input{
|
||||||
|
|
||||||
@@ -43,27 +45,11 @@ public class Input{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Inputs.buttonUp(Buttons.LEFT) && player.recipe != null &&
|
if(Inputs.buttonUp(Buttons.LEFT) && player.recipe != null &&
|
||||||
World.validPlace(World.tilex(), World.tiley(), player.recipe.result) && !ui.hasMouse() &&
|
World.validPlace(tilex(), tiley(), player.recipe.result) && !ui.hasMouse() && cursorNear() &&
|
||||||
Vars.control.hasItems(player.recipe.requirements)){
|
Vars.control.hasItems(player.recipe.requirements)){
|
||||||
Tile tile = World.tile(World.tilex(), World.tiley());
|
|
||||||
|
|
||||||
if(tile == null)
|
World.placeBlock(tilex(), tiley());
|
||||||
return; //just in case
|
|
||||||
|
|
||||||
tile.setBlock(player.recipe.result);
|
|
||||||
tile.rotation = (byte)player.rotation;
|
|
||||||
|
|
||||||
Effects.effect("place", World.roundx(), World.roundy());
|
|
||||||
Effects.shake(2f, 2f, player);
|
|
||||||
Sounds.play("place");
|
|
||||||
|
|
||||||
for(ItemStack stack : player.recipe.requirements){
|
|
||||||
Vars.control.removeItem(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!Vars.control.hasItems(player.recipe.requirements)){
|
|
||||||
Cursors.restoreCursor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(player.recipe != null && Inputs.buttonUp(Buttons.RIGHT)){
|
if(player.recipe != null && Inputs.buttonUp(Buttons.RIGHT)){
|
||||||
@@ -71,22 +57,15 @@ public class Input{
|
|||||||
Cursors.restoreCursor();
|
Cursors.restoreCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile cursor = World.cursorTile();
|
Tile cursor = World.tile(tilex(), tiley());
|
||||||
|
|
||||||
//block breaking
|
//block breaking
|
||||||
if(Inputs.buttonDown(Buttons.RIGHT) && World.validBreak(World.tilex(), World.tiley())){
|
if(cursor != null && Inputs.buttonDown(Buttons.RIGHT) && World.validBreak(tilex(), tiley())){
|
||||||
Tile tile = cursor;
|
Tile tile = cursor;
|
||||||
player.breaktime += Timers.delta();
|
player.breaktime += Timers.delta();
|
||||||
if(player.breaktime >= tile.block().breaktime){
|
if(player.breaktime >= tile.getBreakTime()){
|
||||||
if(tile.block().drops != null){
|
World.breakBlock(cursor.x, cursor.y);
|
||||||
Vars.control.addItem(tile.block().drops.item, tile.block().drops.amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
Effects.effect("break", tile.worldx(), tile.worldy());
|
|
||||||
Effects.shake(3f, 1f, player);
|
|
||||||
tile.setBlock(Blocks.air);
|
|
||||||
player.breaktime = 0f;
|
player.breaktime = 0f;
|
||||||
Sounds.play("break");
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
player.breaktime = 0f;
|
player.breaktime = 0f;
|
||||||
@@ -94,6 +73,22 @@ public class Input{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean cursorNear(){
|
||||||
|
return Vector2.dst(player.x, player.y, tilex() * tilesize, tiley() * tilesize) <= placerange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int tilex(){
|
||||||
|
return (player.recipe != null && player.recipe.result.isMultiblock() &&
|
||||||
|
player.recipe.result.width % 2 == 0) ?
|
||||||
|
Mathf.scl(Graphics.mouseWorld().x, tilesize) : Mathf.scl2(Graphics.mouseWorld().x, tilesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int tiley(){
|
||||||
|
return (player.recipe != null && player.recipe.result.isMultiblock() &&
|
||||||
|
player.recipe.result.height % 2 == 0) ?
|
||||||
|
Mathf.scl(Graphics.mouseWorld().y, tilesize) : Mathf.scl2(Graphics.mouseWorld().y, tilesize);
|
||||||
|
}
|
||||||
|
|
||||||
public static int currentWeapon(){
|
public static int currentWeapon(){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Weapon weapon : control.getWeapons()){
|
for(Weapon weapon : control.getWeapons()){
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public enum Recipe{
|
|||||||
omnidrill(production, ProductionBlocks.omnidrill, stack(Item.titanium, 20), stack(Item.dirium, 20)),
|
omnidrill(production, ProductionBlocks.omnidrill, stack(Item.titanium, 20), stack(Item.dirium, 20)),
|
||||||
|
|
||||||
coalgenerator(power, ProductionBlocks.coalgenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)),
|
coalgenerator(power, ProductionBlocks.coalgenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)),
|
||||||
|
nuclearreactor(power, ProductionBlocks.nuclearReactor, stack(Item.titanium, 10), stack(Item.dirium, 10)),
|
||||||
shieldgenerator(power, DefenseBlocks.shieldgenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)),
|
shieldgenerator(power, DefenseBlocks.shieldgenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)),
|
||||||
|
|
||||||
pump(production, ProductionBlocks.pump, stack(Item.steel, 10));
|
pump(production, ProductionBlocks.pump, stack(Item.steel, 10));
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
package io.anuke.mindustry.world;
|
package io.anuke.mindustry.world;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.ItemStack;
|
import io.anuke.mindustry.resource.ItemStack;
|
||||||
import io.anuke.mindustry.resource.Liquid;
|
import io.anuke.mindustry.resource.Liquid;
|
||||||
import io.anuke.ucore.core.Draw;
|
import io.anuke.ucore.core.Draw;
|
||||||
|
import io.anuke.ucore.core.Effects;
|
||||||
|
import io.anuke.ucore.util.Tmp;
|
||||||
|
|
||||||
public class Block{
|
public class Block{
|
||||||
private static int lastid;
|
private static int lastid;
|
||||||
@@ -16,6 +20,8 @@ public class Block{
|
|||||||
|
|
||||||
public final String name;
|
public final String name;
|
||||||
public String formalName;
|
public String formalName;
|
||||||
|
public String explosionEffect = "explosion";
|
||||||
|
public String explosionSound = "break";
|
||||||
public boolean solid, update, rotate, breakable;
|
public boolean solid, update, rotate, breakable;
|
||||||
public int health = 40;
|
public int health = 40;
|
||||||
public String shadow = "shadow";
|
public String shadow = "shadow";
|
||||||
@@ -28,7 +34,7 @@ public class Block{
|
|||||||
//stuff that drops when broken
|
//stuff that drops when broken
|
||||||
public ItemStack drops = null;
|
public ItemStack drops = null;
|
||||||
public Liquid liquidDrop = null;
|
public Liquid liquidDrop = null;
|
||||||
public int width, height;
|
public int width = 1, height = 1;
|
||||||
|
|
||||||
public Block(String name) {
|
public Block(String name) {
|
||||||
blocks.add(this);
|
blocks.add(this);
|
||||||
@@ -73,6 +79,14 @@ public class Block{
|
|||||||
|
|
||||||
public void update(Tile tile){}
|
public void update(Tile tile){}
|
||||||
|
|
||||||
|
public void onDestroyed(Tile tile){
|
||||||
|
float x = tile.worldx(), y = tile.worldy();
|
||||||
|
|
||||||
|
Effects.shake(4f, 4f, x, y);
|
||||||
|
Effects.effect(explosionEffect, x, y);
|
||||||
|
Effects.sound(explosionSound, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
public TileEntity getEntity(){
|
public TileEntity getEntity(){
|
||||||
return new TileEntity();
|
return new TileEntity();
|
||||||
}
|
}
|
||||||
@@ -159,9 +173,24 @@ public class Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void draw(Tile tile){
|
public void draw(Tile tile){
|
||||||
Draw.rect(name(), tile.worldx(), tile.worldy(), rotate ? tile.rotation * 90 : 0);
|
//note: multiblocks do not support rotation
|
||||||
|
if(width == 1 && height == 1){
|
||||||
|
Draw.rect(name(), tile.worldx(), tile.worldy(), rotate ? tile.rotation * 90 : 0);
|
||||||
|
}else{
|
||||||
|
//if multiblock, make sure to draw even block sizes offset, since the core block is at the BOTTOM LEFT
|
||||||
|
Vector2 offset = getPlaceOffset();
|
||||||
|
Draw.rect(name(), tile.worldx() + offset.x, tile.worldy() + offset.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Offset for placing and drawing multiblocks.*/
|
||||||
|
public Vector2 getPlaceOffset(){
|
||||||
|
return Tmp.v3.set(((width + 1) % 2) * Vars.tilesize/2, ((height + 1) % 2) * Vars.tilesize/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMultiblock(){
|
||||||
|
return width != 1 || height != 1;
|
||||||
|
}
|
||||||
|
|
||||||
public static Array<Block> getAllBlocks(){
|
public static Array<Block> getAllBlocks(){
|
||||||
return blocks;
|
return blocks;
|
||||||
|
|||||||
@@ -2,20 +2,28 @@ package io.anuke.mindustry.world;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
|
import io.anuke.ucore.util.Bits;
|
||||||
|
|
||||||
|
|
||||||
public class Tile{
|
public class Tile{
|
||||||
|
private static final Array<Tile> tmpArray = new Array<>();
|
||||||
|
|
||||||
private Block floor = Blocks.air;
|
private Block floor = Blocks.air;
|
||||||
private Block block = Blocks.air;
|
private Block block = Blocks.air;
|
||||||
|
/**The coordinates of the core tile this is linked to, in the form of two bytes packed into one.
|
||||||
|
* This is relative to the block it is linked to; negate coords to find the link.*/
|
||||||
|
private byte link = 0;
|
||||||
public TileEntity entity;
|
public TileEntity entity;
|
||||||
public int x, y;
|
public short x, y;
|
||||||
public byte rotation, dump;
|
public byte rotation, dump;
|
||||||
|
|
||||||
public Tile(int x, int y){
|
public Tile(int x, int y){
|
||||||
this.x = x;
|
this.x = (short)x;
|
||||||
this.y = y;
|
this.y = (short)y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile(int x, int y, Block floor){
|
public Tile(int x, int y, Block floor){
|
||||||
@@ -55,16 +63,23 @@ public class Tile{
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Returns the breaktime of the block, <i>or</i> the breaktime of the linked block, if this tile is linked.*/
|
||||||
|
public float getBreakTime(){
|
||||||
|
return link == 0 ? block.breaktime : getLinked().block.breaktime;
|
||||||
|
}
|
||||||
|
|
||||||
public void setBlock(Block type, int rotation){
|
public void setBlock(Block type, int rotation){
|
||||||
if(rotation < 0) rotation = (-rotation + 2);
|
if(rotation < 0) rotation = (-rotation + 2);
|
||||||
rotation %= 4;
|
rotation %= 4;
|
||||||
this.block = type;
|
this.block = type;
|
||||||
this.rotation = (byte)rotation;
|
this.rotation = (byte)rotation;
|
||||||
|
this.link = 0;
|
||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlock(Block type){
|
public void setBlock(Block type){
|
||||||
this.block = type;
|
this.block = type;
|
||||||
|
this.link = 0;
|
||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +96,49 @@ public class Tile{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean breakable(){
|
public boolean breakable(){
|
||||||
return block.update || block.breakable;
|
if(link == 0){
|
||||||
|
return (block.update || block.breakable);
|
||||||
|
}else{
|
||||||
|
return getLinked().breakable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLinked(){
|
||||||
|
return link != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Sets this to a linked tile, which sets the block to a blockpart. dx and dy can only be -8-7.*/
|
||||||
|
public void setLinked(byte dx, byte dy){
|
||||||
|
setBlock(Blocks.blockpart);
|
||||||
|
link = Bits.packByte((byte)(dx + 8), (byte)(dy + 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Returns the list of all tiles linked to this multiblock, or an empty array if it's not a multiblock.
|
||||||
|
* This array contains only linked tiles, not this tile itself.*/
|
||||||
|
public Array<Tile> getLinkedTiles(){
|
||||||
|
tmpArray.clear();
|
||||||
|
if(!(block.width == 1 && block.health == 1)){
|
||||||
|
int offsetx = -(block.width-1)/2;
|
||||||
|
int offsety = -(block.height-1)/2;
|
||||||
|
for(int dx = 0; dx < block.width; dx ++){
|
||||||
|
for(int dy = 0; dy < block.height; dy ++){
|
||||||
|
Tile other = World.tile(x + dx - offsetx, y + dy - offsety);
|
||||||
|
tmpArray.add(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmpArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Returns the block the multiblock is linked to, or null if it is not linked to any block.*/
|
||||||
|
public Tile getLinked(){
|
||||||
|
if(link == 0){
|
||||||
|
return null;
|
||||||
|
}else{
|
||||||
|
byte dx = Bits.getLeftByte(link);
|
||||||
|
byte dy = Bits.getRightByte(link);
|
||||||
|
return World.tile(x - (dx - 8), y - (dy - 8));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile[] getNearby(){
|
public Tile[] getNearby(){
|
||||||
@@ -100,6 +157,7 @@ public class Tile{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return floor.name() + ":" + block.name();
|
return floor.name() + ":" + block.name() +
|
||||||
|
(link != 0 ? " link=[" + (Bits.getLeftByte(link) - 8) + ", " + (Bits.getRightByte(link) - 8) + "]" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,14 @@ import com.badlogic.gdx.utils.Array;
|
|||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.ai.Pathfind;
|
import io.anuke.mindustry.ai.Pathfind;
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
|
import io.anuke.mindustry.resource.ItemStack;
|
||||||
import io.anuke.mindustry.world.blocks.*;
|
import io.anuke.mindustry.world.blocks.*;
|
||||||
import io.anuke.ucore.core.Graphics;
|
import io.anuke.ucore.core.Effects;
|
||||||
|
import io.anuke.ucore.core.Sounds;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.entities.Entity;
|
import io.anuke.ucore.entities.Entity;
|
||||||
import io.anuke.ucore.entities.SolidEntity;
|
import io.anuke.ucore.entities.SolidEntity;
|
||||||
|
import io.anuke.ucore.scene.utils.Cursors;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Tmp;
|
||||||
|
|
||||||
@@ -66,10 +69,6 @@ public class World{
|
|||||||
return tiles[x][y];
|
return tiles[x][y];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Tile cursorTile(){
|
|
||||||
return tile(tilex(), tiley());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Tile[] getNearby(int x, int y){
|
public static Tile[] getNearby(int x, int y){
|
||||||
temptiles[0] = tile(x+1, y);
|
temptiles[0] = tile(x+1, y);
|
||||||
temptiles[1] = tile(x, y+1);
|
temptiles[1] = tile(x, y+1);
|
||||||
@@ -200,23 +199,70 @@ public class World{
|
|||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO move to control or player?
|
||||||
|
public static void placeBlock(int x, int y){
|
||||||
|
Tile tile = tile(x, y);
|
||||||
|
|
||||||
|
//just in case
|
||||||
|
if(tile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Block result = player.recipe.result;
|
||||||
|
|
||||||
|
tile.setBlock(result);
|
||||||
|
tile.rotation = (byte)player.rotation;
|
||||||
|
|
||||||
|
if(result.isMultiblock()){
|
||||||
|
int offsetx = -(result.width-1)/2;
|
||||||
|
int offsety = -(result.height-1)/2;
|
||||||
|
|
||||||
|
for(int dx = 0; dx < result.width; dx ++){
|
||||||
|
for(int dy = 0; dy < result.height; dy ++){
|
||||||
|
int worldx = dx + offsetx + x;
|
||||||
|
int worldy = dy + offsety + y;
|
||||||
|
if(!(worldx == x && worldy == y)){
|
||||||
|
//TODO make sure this is correct
|
||||||
|
Tile toplace = tile(worldx, worldy);
|
||||||
|
toplace.setLinked((byte)(dx + offsetx), (byte)(dy + offsety));
|
||||||
|
}
|
||||||
|
|
||||||
|
Effects.effect("place", worldx * Vars.tilesize, worldy * Vars.tilesize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Effects.effect("place", x * Vars.tilesize, y * Vars.tilesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Effects.shake(2f, 2f, player);
|
||||||
|
Sounds.play("place");
|
||||||
|
|
||||||
|
for(ItemStack stack : player.recipe.requirements){
|
||||||
|
Vars.control.removeItem(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Vars.control.hasItems(player.recipe.requirements)){
|
||||||
|
Cursors.restoreCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//TODO move this to control?
|
//TODO move this to control?
|
||||||
public static boolean validPlace(int x, int y, Block type){
|
public static boolean validPlace(int x, int y, Block type){
|
||||||
|
|
||||||
if(!cursorNear() && !android)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for(Tile spawn : spawnpoints){
|
for(Tile spawn : spawnpoints){
|
||||||
if(Vector2.dst(x * tilesize, y * tilesize, spawn.worldx(), spawn.worldy()) < enemyspawnspace){
|
if(Vector2.dst(x * tilesize, y * tilesize, spawn.worldx(), spawn.worldy()) < enemyspawnspace){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tmp.r2.setSize(type.width * Vars.tilesize, type.height * Vars.tilesize);
|
||||||
|
Vector2 offset = type.getPlaceOffset();
|
||||||
|
Tmp.r2.setCenter(offset.x + x * Vars.tilesize, offset.y + y * Vars.tilesize);
|
||||||
|
|
||||||
for(SolidEntity e : Entities.getNearby(x * tilesize, y * tilesize, tilesize * 2f)){
|
for(SolidEntity e : Entities.getNearby(x * tilesize, y * tilesize, tilesize * 2f)){
|
||||||
Rectangle.tmp.setSize(e.hitsize);
|
Rectangle.tmp.setSize(e.hitsize);
|
||||||
Rectangle.tmp.setCenter(e.x, e.y);
|
Rectangle.tmp.setCenter(e.x, e.y);
|
||||||
|
|
||||||
if(getCollider(x, y).overlaps(Rectangle.tmp)){
|
if(Tmp.r2.overlaps(Rectangle.tmp)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,7 +271,7 @@ public class World{
|
|||||||
|
|
||||||
if(tile == null) return false;
|
if(tile == null) return false;
|
||||||
|
|
||||||
if(Vars.control.getTutorial().active() &&
|
if(type.isMultiblock() && Vars.control.getTutorial().active() &&
|
||||||
Vars.control.getTutorial().showBlock()){
|
Vars.control.getTutorial().showBlock()){
|
||||||
|
|
||||||
GridPoint2 point = Vars.control.getTutorial().getPlacePoint();
|
GridPoint2 point = Vars.control.getTutorial().getPlacePoint();
|
||||||
@@ -243,7 +289,47 @@ public class World{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tile != null && tile.block() == Blocks.air;
|
if(type.isMultiblock()){
|
||||||
|
int offsetx = -(type.width-1)/2;
|
||||||
|
int offsety = -(type.height-1)/2;
|
||||||
|
for(int dx = 0; dx < type.width; dx ++){
|
||||||
|
for(int dy = 0; dy < type.height; dy ++){
|
||||||
|
Tile other = tile(x + dx - offsetx, y + dy - offsety);
|
||||||
|
if(other == null || other.block() != Blocks.air){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return tile != null && tile.block() == Blocks.air;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void breakBlock(int x, int y){
|
||||||
|
Tile tile = tile(x, y);
|
||||||
|
|
||||||
|
if(tile == null) return;
|
||||||
|
|
||||||
|
if(tile.block().drops != null){
|
||||||
|
Vars.control.addItem(tile.block().drops.item, tile.block().drops.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
Effects.shake(3f, 1f, player);
|
||||||
|
Sounds.play("break");
|
||||||
|
|
||||||
|
if(!tile.block().isMultiblock() && !tile.isLinked()){
|
||||||
|
tile.setBlock(Blocks.air);
|
||||||
|
}else{
|
||||||
|
Tile target = tile.isLinked() ? tile.getLinked() : tile;
|
||||||
|
Array<Tile> removals = target.getLinkedTiles();
|
||||||
|
removals.add(tile);
|
||||||
|
for(Tile toremove : removals){
|
||||||
|
//note that setting a new block automatically unlinks it
|
||||||
|
toremove.setBlock(Blocks.air);
|
||||||
|
Effects.effect("break", toremove.worldx(), toremove.worldy());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean validBreak(int x, int y){
|
public static boolean validBreak(int x, int y){
|
||||||
@@ -269,13 +355,9 @@ public class World{
|
|||||||
return tile.breakable();
|
return tile.breakable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean cursorNear(){
|
//public static Rectangle getCollider(int x, int y){
|
||||||
return Vector2.dst(player.x, player.y, tilex() * tilesize, tiley() * tilesize) <= placerange;
|
// return Rectangle.tmp2.setSize(tilesize).setCenter(x * tilesize, y * tilesize);
|
||||||
}
|
//}
|
||||||
|
|
||||||
public static Rectangle getCollider(int x, int y){
|
|
||||||
return Rectangle.tmp2.setSize(tilesize).setCenter(x * tilesize, y * tilesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TileEntity findTileTarget(float x, float y, Tile tile, float range, boolean damaged){
|
public static TileEntity findTileTarget(float x, float y, Tile tile, float range, boolean damaged){
|
||||||
Entity closest = null;
|
Entity closest = null;
|
||||||
@@ -307,22 +389,6 @@ public class World{
|
|||||||
return (TileEntity) closest;
|
return (TileEntity) closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float roundx(){
|
|
||||||
return Mathf.round2(Graphics.mouseWorld().x, tilesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float roundy(){
|
|
||||||
return Mathf.round2(Graphics.mouseWorld().y, tilesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int tilex(){
|
|
||||||
return Mathf.scl2(Graphics.mouseWorld().x, tilesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int tiley(){
|
|
||||||
return Mathf.scl2(Graphics.mouseWorld().y, tilesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void disposeMaps(){
|
public static void disposeMaps(){
|
||||||
for(Pixmap pixmap : mapPixmaps){
|
for(Pixmap pixmap : mapPixmaps){
|
||||||
pixmap.dispose();
|
pixmap.dispose();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import io.anuke.mindustry.resource.ItemStack;
|
|||||||
import io.anuke.mindustry.resource.Liquid;
|
import io.anuke.mindustry.resource.Liquid;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.blocks.types.BlockPart;
|
||||||
import io.anuke.mindustry.world.blocks.types.Floor;
|
import io.anuke.mindustry.world.blocks.types.Floor;
|
||||||
import io.anuke.ucore.core.Effects;
|
import io.anuke.ucore.core.Effects;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
@@ -25,6 +26,8 @@ public class Blocks{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
blockpart = new BlockPart(),
|
||||||
|
|
||||||
deepwater = new Floor("deepwater"){{
|
deepwater = new Floor("deepwater"){{
|
||||||
vary = false;
|
vary = false;
|
||||||
solid = true;
|
solid = true;
|
||||||
|
|||||||
@@ -181,6 +181,15 @@ public class ProductionBlocks{
|
|||||||
generateAmount = 4f;
|
generateAmount = 4f;
|
||||||
powerCapacity = 40f;
|
powerCapacity = 40f;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
;
|
nuclearReactor = new LiquidPowerGenerator("nuclearreactor"){
|
||||||
|
{
|
||||||
|
width = 2;
|
||||||
|
height = 2;
|
||||||
|
generateLiquid = Liquid.water;
|
||||||
|
health = 340;
|
||||||
|
breaktime *= 2.2f;
|
||||||
|
powerCapacity = 100f;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package io.anuke.mindustry.world.blocks.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.resource.Liquid;
|
||||||
|
import io.anuke.mindustry.world.Block;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
|
/**Used for multiblocks. Each block that is not the center of the multiblock is a blockpart.
|
||||||
|
* Think of these as delegates to the actual block; all events are passed to the target block.*/
|
||||||
|
public class BlockPart extends Block implements PowerAcceptor, LiquidAcceptor{
|
||||||
|
|
||||||
|
public BlockPart() {
|
||||||
|
super("blockpart");
|
||||||
|
//TODO note: all block parts are solid, which means you can't have non-solid multiblocks
|
||||||
|
solid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Tile tile){
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
|
Block block = linked(tile);
|
||||||
|
return block instanceof LiquidAcceptor
|
||||||
|
&& ((LiquidAcceptor)block).acceptLiquid(tile.getLinked(), source, liquid, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
|
Block block = linked(tile);
|
||||||
|
((LiquidAcceptor)block).handleLiquid(tile.getLinked(), source, liquid, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLiquid(Tile tile){
|
||||||
|
Block block = linked(tile);
|
||||||
|
return block instanceof LiquidAcceptor ? ((LiquidAcceptor)block).getLiquid(tile.getLinked()) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLiquidCapacity(Tile tile){
|
||||||
|
Block block = linked(tile);
|
||||||
|
return block instanceof LiquidAcceptor ? ((LiquidAcceptor)block).getLiquidCapacity(tile.getLinked()) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float addPower(Tile tile, float amount){
|
||||||
|
Block block = linked(tile);
|
||||||
|
if(block instanceof PowerAcceptor){
|
||||||
|
return ((PowerAcceptor)block).addPower(tile.getLinked(), amount);
|
||||||
|
}else{
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Block linked(Tile tile){
|
||||||
|
return tile.getLinked().block();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package io.anuke.mindustry.world.blocks.types;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.resource.Liquid;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
|
public interface LiquidAcceptor{
|
||||||
|
|
||||||
|
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount);
|
||||||
|
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount);
|
||||||
|
public float getLiquid(Tile tile);
|
||||||
|
public float getLiquidCapacity(Tile tile);
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import io.anuke.mindustry.world.Tile;
|
|||||||
import io.anuke.ucore.core.Draw;
|
import io.anuke.ucore.core.Draw;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
|
|
||||||
public class LiquidBlock extends Block{
|
public class LiquidBlock extends Block implements LiquidAcceptor{
|
||||||
protected float liquidCapacity = 10f;
|
protected float liquidCapacity = 10f;
|
||||||
protected float flowfactor = 4.9f;
|
protected float flowfactor = 4.9f;
|
||||||
|
|
||||||
@@ -73,11 +73,10 @@ public class LiquidBlock extends Block{
|
|||||||
|
|
||||||
Liquid liquid = entity.liquid;
|
Liquid liquid = entity.liquid;
|
||||||
|
|
||||||
if(next != null && next.block() instanceof LiquidBlock && entity.liquidAmount > 0.01f){
|
if(next != null && next.block() instanceof LiquidAcceptor && entity.liquidAmount > 0.01f){
|
||||||
LiquidBlock other = (LiquidBlock)next.block();
|
LiquidAcceptor other = (LiquidAcceptor)next.block();
|
||||||
LiquidEntity otherentity = next.entity();
|
|
||||||
|
|
||||||
float flow = Math.min(other.liquidCapacity - otherentity.liquidAmount - 0.001f, Math.min(entity.liquidAmount/flowfactor, entity.liquidAmount));
|
float flow = Math.min(other.getLiquidCapacity(next) - other.getLiquid(next) - 0.001f, Math.min(entity.liquidAmount/flowfactor, entity.liquidAmount));
|
||||||
|
|
||||||
if(flow <= 0f || entity.liquidAmount < flow) return;
|
if(flow <= 0f || entity.liquidAmount < flow) return;
|
||||||
|
|
||||||
@@ -88,18 +87,31 @@ public class LiquidBlock extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
LiquidEntity entity = tile.entity();
|
LiquidEntity entity = tile.entity();
|
||||||
|
|
||||||
return entity.liquidAmount + amount < liquidCapacity && (entity.liquid == liquid || entity.liquidAmount <= 0.01f);
|
return entity.liquidAmount + amount < liquidCapacity && (entity.liquid == liquid || entity.liquidAmount <= 0.01f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
LiquidEntity entity = tile.entity();
|
LiquidEntity entity = tile.entity();
|
||||||
entity.liquid = liquid;
|
entity.liquid = liquid;
|
||||||
entity.liquidAmount += amount;
|
entity.liquidAmount += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLiquid(Tile tile){
|
||||||
|
LiquidEntity entity = tile.entity();
|
||||||
|
return entity.liquidAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLiquidCapacity(Tile tile){
|
||||||
|
return liquidCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
public static class LiquidEntity extends TileEntity{
|
public static class LiquidEntity extends TileEntity{
|
||||||
public Liquid liquid;
|
public Liquid liquid;
|
||||||
public float liquidAmount;
|
public float liquidAmount;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.anuke.mindustry.world.blocks.types;
|
|||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
public interface PowerAcceptor{
|
public interface PowerAcceptor{
|
||||||
/**Attempts to add some power to this block; returns the amount of power <i>not</i> accepted.*/
|
/**Attempts to add some power to this block; returns the amount of power <i>not</i> accepted.
|
||||||
|
* To add no power, you would return amount.*/
|
||||||
public float addPower(Tile tile, float amount);
|
public float addPower(Tile tile, float amount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
@@ -29,7 +30,10 @@ public abstract class PowerBlock extends Block implements PowerAcceptor{
|
|||||||
if(fract > 0)
|
if(fract > 0)
|
||||||
fract = Mathf.clamp(fract + 0.2f, 0.24f, 1f);
|
fract = Mathf.clamp(fract + 0.2f, 0.24f, 1f);
|
||||||
|
|
||||||
Vars.renderer.drawBar(Color.YELLOW, tile.worldx(), tile.worldy() + 13, fract);
|
Vector2 offset = getPlaceOffset();
|
||||||
|
|
||||||
|
Vars.renderer.drawBar(Color.YELLOW, tile.worldx() + offset.x,
|
||||||
|
tile.worldy() + Vars.tilesize * height/2f + 2 + offset.y, fract);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Tries adding all the power with no remainder, returns success.*/
|
/**Tries adding all the power with no remainder, returns success.*/
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class Turret extends Block{
|
|||||||
if(fract > 0)
|
if(fract > 0)
|
||||||
fract = Mathf.clamp(fract, 0.24f, 1f);
|
fract = Mathf.clamp(fract, 0.24f, 1f);
|
||||||
|
|
||||||
Vars.renderer.drawBar(Color.GREEN, tile.worldx(), tile.worldy() + 13, fract);
|
Vars.renderer.drawBar(Color.GREEN, tile.worldx(), tile.worldy() + 6, fract);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class Router extends Block{
|
|||||||
|
|
||||||
float fract = (float)tile.entity.totalItems()/maxitems;
|
float fract = (float)tile.entity.totalItems()/maxitems;
|
||||||
|
|
||||||
Vars.renderer.drawBar(Color.GREEN, tile.worldx(), tile.worldy() + 13, fract);
|
Vars.renderer.drawBar(Color.GREEN, tile.worldx(), tile.worldy() + 6, fract);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -62,6 +62,6 @@ public class Generator extends PowerBlock{
|
|||||||
//don't accept any power
|
//don't accept any power
|
||||||
@Override
|
@Override
|
||||||
public float addPower(Tile tile, float amount){
|
public float addPower(Tile tile, float amount){
|
||||||
return 0;
|
return amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class ItemPowerGenerator extends Generator{
|
|||||||
TileEntity entity = tile.entity;
|
TileEntity entity = tile.entity;
|
||||||
|
|
||||||
//TODO maybe don't draw it due to clutter
|
//TODO maybe don't draw it due to clutter
|
||||||
Vars.renderer.drawBar(Color.GREEN, tile.worldx(), tile.worldy() + 13 + 4, (float)entity.totalItems() / itemCapacity);
|
Vars.renderer.drawBar(Color.GREEN, tile.worldx(), tile.worldy() + 10, (float)entity.totalItems() / itemCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,33 +4,56 @@ import java.io.DataInputStream;
|
|||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.resource.Liquid;
|
import io.anuke.mindustry.resource.Liquid;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.types.LiquidBlock;
|
import io.anuke.mindustry.world.blocks.types.LiquidAcceptor;
|
||||||
|
import io.anuke.ucore.core.Draw;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
|
||||||
public class LiquidPowerGenerator extends LiquidBlock{
|
public class LiquidPowerGenerator extends Generator implements LiquidAcceptor{
|
||||||
|
public int generateTime = 5;
|
||||||
public Liquid generateLiquid;
|
public Liquid generateLiquid;
|
||||||
public float generatePower;
|
/**Power to generate per generateInput.*/
|
||||||
public float generateAmount = 1f;
|
public float generatePower = 1f;
|
||||||
|
/**How much liquid to consume to get one generatePower.*/
|
||||||
|
public float generateInput = 1f;
|
||||||
|
public float liquidCapacity = 30f;
|
||||||
|
|
||||||
public LiquidPowerGenerator(String name) {
|
public LiquidPowerGenerator(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void draw(Tile tile){
|
||||||
|
super.draw(tile);
|
||||||
|
|
||||||
LiquidPowerEntity entity = tile.entity();
|
LiquidPowerEntity entity = tile.entity();
|
||||||
|
|
||||||
if(entity.liquidAmount >= generateAmount){
|
if(entity.liquid == null) return;
|
||||||
entity.liquidAmount -= generateAmount;
|
|
||||||
//TODO actually add power
|
Vector2 offset = getPlaceOffset();
|
||||||
}
|
|
||||||
|
Draw.color(entity.liquid.color);
|
||||||
|
Draw.alpha(entity.liquidAmount / liquidCapacity);
|
||||||
|
Draw.rect("blank", tile.worldx() + offset.x, tile.worldy() + offset.y, 2, 2);
|
||||||
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
public void update(Tile tile){
|
||||||
return liquid == generateLiquid && super.acceptLiquid(tile, source, liquid, amount);
|
LiquidPowerEntity entity = tile.entity();
|
||||||
|
|
||||||
|
if(entity.liquidAmount >= generateInput && Timers.get(tile, "generate", generateTime)){
|
||||||
|
entity.liquidAmount -= generateInput;
|
||||||
|
entity.power += generatePower;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Timers.get(tile, "generate", generateTime)){
|
||||||
|
distributePower(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -38,19 +61,53 @@ public class LiquidPowerGenerator extends LiquidBlock{
|
|||||||
return new LiquidPowerEntity();
|
return new LiquidPowerEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LiquidPowerEntity extends LiquidEntity{
|
@Override
|
||||||
public float power;
|
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
|
LiquidPowerEntity entity = tile.entity();
|
||||||
|
|
||||||
|
if(liquid != generateLiquid){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity.liquidAmount + amount < liquidCapacity && (entity.liquid == liquid || entity.liquidAmount <= 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
|
||||||
|
LiquidPowerEntity entity = tile.entity();
|
||||||
|
entity.liquid = liquid;
|
||||||
|
entity.liquidAmount += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLiquid(Tile tile){
|
||||||
|
LiquidPowerEntity entity = tile.entity();
|
||||||
|
return entity.liquidAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLiquidCapacity(Tile tile){
|
||||||
|
return liquidCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LiquidPowerEntity extends PowerEntity{
|
||||||
|
public Liquid liquid;
|
||||||
|
public float liquidAmount;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutputStream stream) throws IOException{
|
public void write(DataOutputStream stream) throws IOException{
|
||||||
super.write(stream);
|
super.write(stream);
|
||||||
stream.writeFloat(power);
|
stream.writeByte(liquid == null ? -1 : liquid.ordinal());
|
||||||
|
stream.writeByte((byte)(liquidAmount));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInputStream stream) throws IOException{
|
public void read(DataInputStream stream) throws IOException{
|
||||||
super.read(stream);
|
super.read(stream);
|
||||||
power = stream.readFloat();
|
byte ordinal = stream.readByte();
|
||||||
|
liquid = ordinal == -1 ? null : Liquid.values()[ordinal];
|
||||||
|
liquidAmount = stream.readByte();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user