mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-01-03 13:30:25 +07:00
Recipe class removed completely
This commit is contained in:
parent
750388a425
commit
0478af2564
@ -416,7 +416,7 @@ mode.attack.descrption = No waves, with the goal to destroy the enemy base.
|
||||
content.item.name = Items
|
||||
content.liquid.name = Liquids
|
||||
content.unit.name = Units
|
||||
content.recipe.name = Blocks
|
||||
content.block.name = Blocks
|
||||
content.mech.name = Mechs
|
||||
item.copper.name = Copper
|
||||
item.copper.description = A useful structure material. Used extensively in all types of blocks.
|
||||
|
@ -729,6 +729,7 @@ public class Blocks implements ContentList{
|
||||
launchThreshold = 500;
|
||||
launchTime = 60f * 10;
|
||||
launchChunkSize = 100;
|
||||
alwaysUnlocked = true;
|
||||
}};
|
||||
|
||||
vault = new Vault("vault"){{
|
||||
|
@ -1,16 +1,12 @@
|
||||
package io.anuke.mindustry.content;
|
||||
|
||||
import io.anuke.mindustry.game.ContentList;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.type.Recipe.RecipeVisibility;
|
||||
|
||||
import static io.anuke.mindustry.type.Category.*;
|
||||
|
||||
public class Recipes implements ContentList{
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
/*
|
||||
//DEBUG
|
||||
new Recipe(distribution, Blocks.itemSource).setVisible(RecipeVisibility.sandboxOnly).setHidden(true).setAlwaysUnlocked(true);
|
||||
new Recipe(distribution, Blocks.itemVoid).setVisible(RecipeVisibility.sandboxOnly).setHidden(true).setAlwaysUnlocked(true);
|
||||
@ -174,5 +170,6 @@ public class Recipes implements ContentList{
|
||||
new Recipe(liquid, Blocks.mechanicalPump, new ItemStack(Items.copper, 30), new ItemStack(Items.lead, 20));
|
||||
new Recipe(liquid, Blocks.rotaryPump, new ItemStack(Items.copper, 140), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 40), new ItemStack(Items.titanium, 70));
|
||||
new Recipe(liquid, Blocks.thermalPump, new ItemStack(Items.copper, 160), new ItemStack(Items.lead, 130), new ItemStack(Items.silicon, 60), new ItemStack(Items.titanium, 80), new ItemStack(Items.thorium, 70));
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package io.anuke.mindustry.content;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.mindustry.game.ContentList;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
|
||||
import static io.anuke.mindustry.type.ItemStack.with;
|
||||
@ -264,7 +263,6 @@ public class TechTree implements ContentList{
|
||||
public final Array<TechNode> children = new Array<>();
|
||||
|
||||
TechNode(Block block, ItemStack[] requirements, Runnable children){
|
||||
if(block != null && Recipe.getByResult(block) == null) throw new IllegalArgumentException("Block " + block + " does not have a recipe.");
|
||||
if(context != null){
|
||||
context.children.add(this);
|
||||
}
|
||||
@ -277,9 +275,5 @@ public class TechTree implements ContentList{
|
||||
children.run();
|
||||
context = last;
|
||||
}
|
||||
|
||||
public Recipe recipe(){
|
||||
return Recipe.getByResult(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ public class ContentLoader{
|
||||
new Mechs(),
|
||||
new UnitTypes(),
|
||||
new Blocks(),
|
||||
new Recipes(),
|
||||
new TechTree(),
|
||||
new Zones(),
|
||||
|
||||
@ -185,14 +184,6 @@ public class ContentLoader{
|
||||
return (Block) getByID(ContentType.block, id);
|
||||
}
|
||||
|
||||
public Array<Recipe> recipes(){
|
||||
return getBy(ContentType.recipe);
|
||||
}
|
||||
|
||||
public Recipe recipe(int id){
|
||||
return (Recipe) getByID(ContentType.recipe, id);
|
||||
}
|
||||
|
||||
public Array<Item> items(){
|
||||
return getBy(ContentType.item);
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@ -30,8 +29,8 @@ public class Logic implements ApplicationListener{
|
||||
|
||||
public Logic(){
|
||||
Events.on(TileChangeEvent.class, event -> {
|
||||
if(event.tile.getTeam() == defaultTeam && Recipe.getByResult(event.tile.block()) != null){
|
||||
handleContent(Recipe.getByResult(event.tile.block()));
|
||||
if(event.tile.getTeam() == defaultTeam && event.tile.block().isVisible()){
|
||||
handleContent(event.tile.block());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ public class NetServer implements ApplicationListener{
|
||||
//auto-skip done requests
|
||||
if(req.breaking && world.tile(req.x, req.y).block() == Blocks.air){
|
||||
continue;
|
||||
}else if(!req.breaking && world.tile(req.x, req.y).block() == req.recipe.result && (!req.recipe.result.rotate || world.tile(req.x, req.y).getRotation() == req.rotation)){
|
||||
}else if(!req.breaking && world.tile(req.x, req.y).block() == req.block && (!req.block.rotate || world.tile(req.x, req.y).getRotation() == req.rotation)){
|
||||
continue;
|
||||
}
|
||||
player.getPlaceQueue().addLast(req);
|
||||
|
@ -461,28 +461,28 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
request.y * tilesize + block.offset(),
|
||||
rad);
|
||||
}else{
|
||||
float rad = Mathf.absin(Time.time(), 7f, 1f) - 1.5f + request.recipe.result.size * tilesize / 2f;
|
||||
float rad = Mathf.absin(Time.time(), 7f, 1f) - 1.5f + request.block.size * tilesize / 2f;
|
||||
|
||||
//draw place request
|
||||
Lines.stroke(1f, Palette.accentBack);
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset() - 1,
|
||||
request.x * tilesize + request.block.offset(),
|
||||
request.y * tilesize + request.block.offset() - 1,
|
||||
rad);
|
||||
|
||||
Draw.color();
|
||||
|
||||
Draw.rect(request.recipe.result.icon(Icon.full),
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset(), rad*2, rad*2, request.rotation * 90);
|
||||
Draw.rect(request.block.icon(Icon.full),
|
||||
request.x * tilesize + request.block.offset(),
|
||||
request.y * tilesize + request.block.offset(), rad*2, rad*2, request.rotation * 90);
|
||||
|
||||
|
||||
Draw.color(Palette.accent);
|
||||
|
||||
Lines.square(
|
||||
request.x * tilesize + request.recipe.result.offset(),
|
||||
request.y * tilesize + request.recipe.result.offset(),
|
||||
request.x * tilesize + request.block.offset(),
|
||||
request.y * tilesize + request.block.offset(),
|
||||
rad);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Shapes;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
import io.anuke.mindustry.world.Pos;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@ -81,7 +81,7 @@ public interface BuilderTrait extends Entity{
|
||||
output.writeInt(Pos.get(request.x, request.y));
|
||||
output.writeFloat(request.progress);
|
||||
if(!request.breaking){
|
||||
output.writeByte(request.recipe.id);
|
||||
output.writeByte(request.block.id);
|
||||
output.writeByte(request.rotation);
|
||||
}
|
||||
}else{
|
||||
@ -105,9 +105,9 @@ public interface BuilderTrait extends Entity{
|
||||
if(type == 1){ //remove
|
||||
request = new BuildRequest(Pos.x(position), Pos.y(position));
|
||||
}else{ //place
|
||||
byte recipe = input.readByte();
|
||||
byte block = input.readByte();
|
||||
byte rotation = input.readByte();
|
||||
request = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.recipe(recipe));
|
||||
request = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.block(block));
|
||||
}
|
||||
|
||||
request.progress = progress;
|
||||
@ -129,7 +129,7 @@ public interface BuilderTrait extends Entity{
|
||||
* If a place request matching this signature is present, it is removed.
|
||||
* Otherwise, a new place request is added to the queue.
|
||||
*/
|
||||
default void replaceBuilding(int x, int y, int rotation, Recipe recipe){
|
||||
default void replaceBuilding(int x, int y, int rotation, Block block){
|
||||
for(BuildRequest request : getPlaceQueue()){
|
||||
if(request.x == x && request.y == y){
|
||||
clearBuilding();
|
||||
@ -138,7 +138,7 @@ public interface BuilderTrait extends Entity{
|
||||
}
|
||||
}
|
||||
|
||||
addBuildRequest(new BuildRequest(x, y, rotation, recipe));
|
||||
addBuildRequest(new BuildRequest(x, y, rotation, block));
|
||||
}
|
||||
|
||||
/**Clears the placement queue.*/
|
||||
@ -184,8 +184,8 @@ public interface BuilderTrait extends Entity{
|
||||
for(BuildRequest request : removal){
|
||||
if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
|
||||
(!request.breaking &&
|
||||
(world.tile(request.x, request.y).getRotation() == request.rotation || !request.recipe.result.rotate)
|
||||
&& world.tile(request.x, request.y).block() == request.recipe.result))){
|
||||
(world.tile(request.x, request.y).getRotation() == request.rotation || !request.block.rotate)
|
||||
&& world.tile(request.x, request.y).block() == request.block))){
|
||||
getPlaceQueue().addLast(request);
|
||||
}
|
||||
}
|
||||
@ -209,8 +209,8 @@ public interface BuilderTrait extends Entity{
|
||||
}
|
||||
|
||||
if(!(tile.block() instanceof BuildBlock)){
|
||||
if(canCreateBlocks() && !current.breaking && Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)){
|
||||
Build.beginPlace(unit.getTeam(), current.x, current.y, current.recipe, current.rotation);
|
||||
if(canCreateBlocks() && !current.breaking && Build.validPlace(unit.getTeam(), current.x, current.y, current.block, current.rotation)){
|
||||
Build.beginPlace(unit.getTeam(), current.x, current.y, current.block, current.rotation);
|
||||
}else if(canCreateBlocks() && current.breaking && Build.validBreak(unit.getTeam(), current.x, current.y)){
|
||||
Build.beginBreak(unit.getTeam(), current.x, current.y);
|
||||
}else{
|
||||
@ -370,18 +370,18 @@ public interface BuilderTrait extends Entity{
|
||||
/**Class for storing build requests. Can be either a place or remove request.*/
|
||||
class BuildRequest{
|
||||
public final int x, y, rotation;
|
||||
public final Recipe recipe;
|
||||
public final Block block;
|
||||
public final boolean breaking;
|
||||
|
||||
public float progress;
|
||||
public boolean initialized;
|
||||
|
||||
/**This creates a build request.*/
|
||||
public BuildRequest(int x, int y, int rotation, Recipe recipe){
|
||||
public BuildRequest(int x, int y, int rotation, Block block){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
this.recipe = recipe;
|
||||
this.block = block;
|
||||
this.breaking = false;
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ public interface BuilderTrait extends Entity{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = -1;
|
||||
this.recipe = Recipe.getByResult(world.tile(x, y).block());
|
||||
this.block = world.tile(x, y).block();
|
||||
this.breaking = true;
|
||||
}
|
||||
|
||||
@ -400,7 +400,7 @@ public interface BuilderTrait extends Entity{
|
||||
"x=" + x +
|
||||
", y=" + y +
|
||||
", rotation=" + rotation +
|
||||
", recipe=" + recipe +
|
||||
", recipe=" + block +
|
||||
", breaking=" + breaking +
|
||||
", progress=" + progress +
|
||||
", initialized=" + initialized +
|
||||
|
@ -65,13 +65,13 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
||||
if(isBreaking){
|
||||
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y));
|
||||
}else{
|
||||
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.getRotation(), entity.recipe));
|
||||
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.getRotation(), entity.block));
|
||||
}
|
||||
}
|
||||
|
||||
//if it's missing requirements, try and mine them
|
||||
if(entity.recipe != null){
|
||||
for(ItemStack stack : entity.recipe.requirements){
|
||||
if(entity.block != null){
|
||||
for(ItemStack stack : entity.block.buildRequirements){
|
||||
if(!core.items.has(stack.item, stack.amount) && type.toMine.contains(stack.item)){
|
||||
targetItem = stack.item;
|
||||
getPlaceQueue().clear();
|
||||
|
@ -89,7 +89,7 @@ public class OverlayRenderer{
|
||||
Draw.reset();
|
||||
|
||||
//draw selected block bars and info
|
||||
if(input.recipe == null && !Core.scene.hasMouse()){
|
||||
if(input.block == null && !Core.scene.hasMouse()){
|
||||
Vector2 vec = Core.input.mouseWorld(input.getMouseX(), input.getMouseY());
|
||||
Tile tile = world.tileWorld(vec.x, vec.y);
|
||||
|
||||
|
@ -41,7 +41,7 @@ public class Palette{
|
||||
heal = Color.valueOf("98ffa9"),
|
||||
bar = Color.SLATE,
|
||||
accent = Color.valueOf("ffd37f"),
|
||||
locked = Color.valueOf("6b6b6b"),
|
||||
locked = Color.valueOf("989aa4"),
|
||||
accentBack = Color.valueOf("d4816b"),
|
||||
place = Color.valueOf("6335f8"),
|
||||
remove = Color.valueOf("e55454"),
|
||||
|
@ -60,7 +60,7 @@ public class DesktopInput extends InputHandler{
|
||||
|
||||
@Override
|
||||
public boolean isDrawing(){
|
||||
return mode != none || recipe != null;
|
||||
return mode != none || block != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -70,30 +70,30 @@ public class DesktopInput extends InputHandler{
|
||||
int cursorY = tileY(Core.input.mouseY());
|
||||
|
||||
//draw selection(s)
|
||||
if(mode == placing && recipe != null){
|
||||
if(mode == placing && block != null){
|
||||
NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursorX, cursorY, rotation, true, maxLength);
|
||||
|
||||
for(int i = 0; i <= result.getLength(); i += recipe.result.size){
|
||||
for(int i = 0; i <= result.getLength(); i += block.size){
|
||||
int x = selectX + i * Mathf.sign(cursorX - selectX) * Mathf.num(result.isX());
|
||||
int y = selectY + i * Mathf.sign(cursorY - selectY) * Mathf.num(!result.isX());
|
||||
|
||||
if(i + recipe.result.size > result.getLength() && recipe.result.rotate){
|
||||
Draw.color(!validPlace(x, y, recipe.result, result.rotation) ? Palette.removeBack : Palette.accentBack);
|
||||
if(i + block.size > result.getLength() && block.rotate){
|
||||
Draw.color(!validPlace(x, y, block, result.rotation) ? Palette.removeBack : Palette.accentBack);
|
||||
Draw.rect(Core.atlas.find("place-arrow"),
|
||||
x * tilesize + recipe.result.offset(),
|
||||
y * tilesize + recipe.result.offset() - 1,
|
||||
x * tilesize + block.offset(),
|
||||
y * tilesize + block.offset() - 1,
|
||||
Core.atlas.find("place-arrow").getWidth() * Draw.scl,
|
||||
Core.atlas.find("place-arrow").getHeight() * Draw.scl, result.rotation * 90 - 90);
|
||||
|
||||
Draw.color(!validPlace(x, y, recipe.result, result.rotation) ? Palette.remove : Palette.accent);
|
||||
Draw.color(!validPlace(x, y, block, result.rotation) ? Palette.remove : Palette.accent);
|
||||
Draw.rect(Core.atlas.find("place-arrow"),
|
||||
x * tilesize + recipe.result.offset(),
|
||||
y * tilesize + recipe.result.offset(),
|
||||
x * tilesize + block.offset(),
|
||||
y * tilesize + block.offset(),
|
||||
Core.atlas.find("place-arrow").getWidth() * Draw.scl,
|
||||
Core.atlas.find("place-arrow").getHeight() * Draw.scl, result.rotation * 90 - 90);
|
||||
}
|
||||
|
||||
drawPlace(x, y, recipe.result, result.rotation);
|
||||
drawPlace(x, y, block, result.rotation);
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
@ -119,23 +119,23 @@ public class DesktopInput extends InputHandler{
|
||||
Draw.color(Palette.remove);
|
||||
Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
|
||||
}else if(isPlacing()){
|
||||
if(recipe.result.rotate){
|
||||
Draw.color(!validPlace(cursorX, cursorY, recipe.result, rotation) ? Palette.removeBack : Palette.accentBack);
|
||||
if(block.rotate){
|
||||
Draw.color(!validPlace(cursorX, cursorY, block, rotation) ? Palette.removeBack : Palette.accentBack);
|
||||
Draw.rect(Core.atlas.find("place-arrow"),
|
||||
cursorX * tilesize + recipe.result.offset(),
|
||||
cursorY * tilesize + recipe.result.offset() - 1,
|
||||
cursorX * tilesize + block.offset(),
|
||||
cursorY * tilesize + block.offset() - 1,
|
||||
Core.atlas.find("place-arrow").getWidth() * Draw.scl,
|
||||
Core.atlas.find("place-arrow").getHeight() * Draw.scl, rotation * 90 - 90);
|
||||
|
||||
Draw.color(!validPlace(cursorX, cursorY, recipe.result, rotation) ? Palette.remove : Palette.accent);
|
||||
Draw.color(!validPlace(cursorX, cursorY, block, rotation) ? Palette.remove : Palette.accent);
|
||||
Draw.rect(Core.atlas.find("place-arrow"),
|
||||
cursorX * tilesize + recipe.result.offset(),
|
||||
cursorY * tilesize + recipe.result.offset(),
|
||||
cursorX * tilesize + block.offset(),
|
||||
cursorY * tilesize + block.offset(),
|
||||
Core.atlas.find("place-arrow").getWidth() * Draw.scl,
|
||||
Core.atlas.find("place-arrow").getHeight() * Draw.scl, rotation * 90 - 90);
|
||||
}
|
||||
drawPlace(cursorX, cursorY, recipe.result, rotation);
|
||||
recipe.result.drawPlace(cursorX, cursorY, rotation, validPlace(cursorX, cursorY, recipe.result, rotation));
|
||||
drawPlace(cursorX, cursorY, block, rotation);
|
||||
block.drawPlace(cursorX, cursorY, rotation, validPlace(cursorX, cursorY, block, rotation));
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
@ -234,13 +234,13 @@ public class DesktopInput extends InputHandler{
|
||||
}else if(!ui.chatfrag.chatOpen()){ //if it's out of bounds, shooting is just fine
|
||||
player.isShooting = true;
|
||||
}
|
||||
}else if(Core.input.keyTap(Binding.deselect) && (recipe != null || mode != none || player.isBuilding()) &&
|
||||
}else if(Core.input.keyTap(Binding.deselect) && (block != null || mode != none || player.isBuilding()) &&
|
||||
!(player.getCurrentRequest() != null && player.getCurrentRequest().breaking && Core.keybinds.get(Binding.deselect) == Core.keybinds.get(Binding.break_block))){
|
||||
if(recipe == null){
|
||||
if(block == null){
|
||||
player.clearBuilding();
|
||||
}
|
||||
|
||||
recipe = null;
|
||||
block = null;
|
||||
mode = none;
|
||||
}else if(Core.input.keyTap(Binding.break_block) && !Core.scene.hasMouse()){
|
||||
//is recalculated because setting the mode to breaking removes potential multiblock cursor offset
|
||||
@ -252,10 +252,10 @@ public class DesktopInput extends InputHandler{
|
||||
|
||||
if(Core.input.keyRelease(Binding.break_block) || Core.input.keyRelease(Binding.select)){
|
||||
|
||||
if(mode == placing && recipe != null){ //touch up while placing, place everything in selection
|
||||
if(mode == placing && block != null){ //touch up while placing, place everything in selection
|
||||
NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursorX, cursorY, rotation, true, maxLength);
|
||||
|
||||
for(int i = 0; i <= result.getLength(); i += recipe.result.size){
|
||||
for(int i = 0; i <= result.getLength(); i += block.size){
|
||||
int x = selectX + i * Mathf.sign(cursorX - selectX) * Mathf.num(result.isX());
|
||||
int y = selectY + i * Mathf.sign(cursorY - selectY) * Mathf.num(!result.isX());
|
||||
|
||||
|
@ -21,7 +21,6 @@ import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.ValidateException;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.ui.fragments.OverlayFragment;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Build;
|
||||
@ -41,7 +40,7 @@ public abstract class InputHandler implements InputProcessor{
|
||||
public final Player player;
|
||||
public final OverlayFragment frag = new OverlayFragment(this);
|
||||
|
||||
public Recipe recipe;
|
||||
public Block block;
|
||||
public int rotation;
|
||||
public boolean droppingItem;
|
||||
|
||||
@ -199,7 +198,7 @@ public abstract class InputHandler implements InputProcessor{
|
||||
|
||||
if(!consumed && player.isBuilding()){
|
||||
player.clearBuilding();
|
||||
recipe = null;
|
||||
block = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -245,7 +244,7 @@ public abstract class InputHandler implements InputProcessor{
|
||||
int tileX(float cursorX){
|
||||
Vector2 vec = Core.input.mouseWorld(cursorX, 0);
|
||||
if(selectedBlock()){
|
||||
vec.sub(recipe.result.offset(), recipe.result.offset());
|
||||
vec.sub(block.offset(), block.offset());
|
||||
}
|
||||
return world.toTile(vec.x);
|
||||
}
|
||||
@ -253,7 +252,7 @@ public abstract class InputHandler implements InputProcessor{
|
||||
int tileY(float cursorY){
|
||||
Vector2 vec = Core.input.mouseWorld(0, cursorY);
|
||||
if(selectedBlock()){
|
||||
vec.sub(recipe.result.offset(), recipe.result.offset());
|
||||
vec.sub(block.offset(), block.offset());
|
||||
}
|
||||
return world.toTile(vec.y);
|
||||
}
|
||||
@ -263,7 +262,7 @@ public abstract class InputHandler implements InputProcessor{
|
||||
}
|
||||
|
||||
public boolean isPlacing(){
|
||||
return recipe != null;
|
||||
return block != null;
|
||||
}
|
||||
|
||||
public float mouseAngle(float x, float y){
|
||||
@ -276,7 +275,7 @@ public abstract class InputHandler implements InputProcessor{
|
||||
}
|
||||
|
||||
public boolean canShoot(){
|
||||
return recipe == null && !Core.scene.hasMouse() && !onConfigurable() && !isDroppingItem();
|
||||
return block == null && !Core.scene.hasMouse() && !onConfigurable() && !isDroppingItem();
|
||||
}
|
||||
|
||||
public boolean onConfigurable(){
|
||||
@ -309,8 +308,8 @@ public abstract class InputHandler implements InputProcessor{
|
||||
}
|
||||
|
||||
public void tryPlaceBlock(int x, int y){
|
||||
if(recipe != null && validPlace(x, y, recipe.result, rotation) && cursorNear()){
|
||||
placeBlock(x, y, recipe, rotation);
|
||||
if(block != null && validPlace(x, y, block, rotation) && cursorNear()){
|
||||
placeBlock(x, y, block, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,8 +328,8 @@ public abstract class InputHandler implements InputProcessor{
|
||||
return Build.validBreak(player.getTeam(), x, y) && Mathf.dst(player.x, player.y, x * tilesize, y * tilesize) < Player.placeDistance;
|
||||
}
|
||||
|
||||
public void placeBlock(int x, int y, Recipe recipe, int rotation){
|
||||
player.addBuildRequest(new BuildRequest(x, y, rotation, recipe));
|
||||
public void placeBlock(int x, int y, Block block, int rotation){
|
||||
player.addBuildRequest(new BuildRequest(x, y, rotation, block));
|
||||
}
|
||||
|
||||
public void breakBlock(int x, int y){
|
||||
|
@ -30,7 +30,6 @@ import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult;
|
||||
import io.anuke.mindustry.input.PlaceUtils.NormalizeResult;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
@ -73,7 +72,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
/** Current place mode. */
|
||||
private PlaceMode mode = none;
|
||||
/** Whether no recipe was available when switching to break mode. */
|
||||
private Recipe lastRecipe;
|
||||
private Block lastBlock;
|
||||
/** Last placed request. Used for drawing block overlay. */
|
||||
private PlaceRequest lastPlaced;
|
||||
|
||||
@ -121,8 +120,8 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
if(other == null || req.remove) continue;
|
||||
|
||||
r1.setSize(req.recipe.result.size * tilesize);
|
||||
r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset());
|
||||
r1.setSize(req.block.size * tilesize);
|
||||
r1.setCenter(other.worldx() + req.block.offset(), other.worldy() + req.block.offset());
|
||||
|
||||
if(r2.overlaps(r1)){
|
||||
return true;
|
||||
@ -142,8 +141,8 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
if(other == null) continue;
|
||||
|
||||
if(!req.remove){
|
||||
r1.setSize(req.recipe.result.size * tilesize);
|
||||
r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset());
|
||||
r1.setSize(req.block.size * tilesize);
|
||||
r1.setCenter(other.worldx() + req.block.offset(), other.worldy() + req.block.offset());
|
||||
|
||||
if(r2.overlaps(r1)){
|
||||
return req;
|
||||
@ -171,8 +170,8 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
if(!request.remove){
|
||||
//draw placing request
|
||||
float offset = request.recipe.result.offset();
|
||||
TextureRegion region = request.recipe.result.icon(Icon.full);
|
||||
float offset = request.block.offset();
|
||||
TextureRegion region = request.block.icon(Icon.full);
|
||||
|
||||
Draw.alpha(Mathf.clamp((1f - request.scale) / 0.5f));
|
||||
Draw.tint(Color.WHITE, Palette.breakInvalid, request.redness);
|
||||
@ -180,7 +179,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset,
|
||||
region.getWidth() * request.scale * Draw.scl,
|
||||
region.getHeight() * request.scale * Draw.scl,
|
||||
request.recipe.result.rotate ? request.rotation * 90 : 0);
|
||||
request.block.rotate ? request.rotation * 90 : 0);
|
||||
}else{
|
||||
float rad = (tile.block().size * tilesize / 2f - 1) * request.scale;
|
||||
Draw.alpha(0f);
|
||||
@ -219,8 +218,8 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
table.left().margin(0f).defaults().size(48f);
|
||||
|
||||
table.addImageButton("icon-break", "clear-toggle-partial", 16 * 2f, () -> {
|
||||
mode = mode == breaking ? recipe == null ? none : placing : breaking;
|
||||
lastRecipe = recipe;
|
||||
mode = mode == breaking ? block == null ? none : placing : breaking;
|
||||
lastBlock = block;
|
||||
if(mode == breaking){
|
||||
showGuide("deconstruction");
|
||||
}
|
||||
@ -230,13 +229,13 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
table.addImageButton("icon-cancel", "clear-partial", 16 * 2f, () -> {
|
||||
player.clearBuilding();
|
||||
mode = none;
|
||||
recipe = null;
|
||||
}).visible(() -> player.isBuilding() || recipe != null || mode == breaking);
|
||||
block = null;
|
||||
}).visible(() -> player.isBuilding() || block != null || mode == breaking);
|
||||
|
||||
//rotate button
|
||||
table.addImageButton("icon-arrow", "clear-partial", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4))
|
||||
.update(i -> i.getImage().setRotationOrigin(rotation * 90, Align.center))
|
||||
.visible(() -> recipe != null && recipe.result.rotate);
|
||||
.visible(() -> block != null && block.rotate);
|
||||
|
||||
//confirm button
|
||||
table.addImageButton("icon-check", "clear-partial", 16 * 2f, () -> {
|
||||
@ -247,10 +246,10 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
if(tile != null){
|
||||
if(!request.remove){
|
||||
rotation = request.rotation;
|
||||
Recipe before = recipe;
|
||||
recipe = request.recipe;
|
||||
Block before = block;
|
||||
block = request.block;
|
||||
tryPlaceBlock(tile.x, tile.y);
|
||||
recipe = before;
|
||||
block = before;
|
||||
}else{
|
||||
tryBreakBlock(tile.x, tile.y);
|
||||
}
|
||||
@ -299,7 +298,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
if(tile == null) continue;
|
||||
|
||||
if((!request.remove && validPlace(tile.x, tile.y, request.recipe.result, request.rotation))
|
||||
if((!request.remove && validPlace(tile.x, tile.y, request.block, request.rotation))
|
||||
|| (request.remove && validBreak(tile.x, tile.y))){
|
||||
request.scale = Mathf.lerpDelta(request.scale, 1f, 0.2f);
|
||||
request.redness = Mathf.lerpDelta(request.redness, 0f, 0.2f);
|
||||
@ -312,8 +311,8 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
drawRequest(request);
|
||||
|
||||
//draw last placed request
|
||||
if(!request.remove && request == lastPlaced && request.recipe != null){
|
||||
request.recipe.result.drawPlace(tile.x, tile.y, rotation, validPlace(tile.x, tile.y, request.recipe.result, rotation));
|
||||
if(!request.remove && request == lastPlaced && request.block != null){
|
||||
request.block.drawPlace(tile.x, tile.y, rotation, validPlace(tile.x, tile.y, request.block, rotation));
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,32 +326,32 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
int tileY = tileY(Core.input.mouseY());
|
||||
|
||||
//draw placing
|
||||
if(mode == placing && recipe != null){
|
||||
NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(recipe.result, lineStartX, lineStartY, tileX, tileY, true, maxLength, lineScale);
|
||||
if(mode == placing && block != null){
|
||||
NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(block, lineStartX, lineStartY, tileX, tileY, true, maxLength, lineScale);
|
||||
|
||||
Lines.rect(dresult.x, dresult.y, dresult.x2 - dresult.x, dresult.y2 - dresult.y);
|
||||
|
||||
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tileX, tileY, rotation, true, maxLength);
|
||||
|
||||
//go through each cell and draw the block to place if valid
|
||||
for(int i = 0; i <= result.getLength(); i += recipe.result.size){
|
||||
for(int i = 0; i <= result.getLength(); i += block.size){
|
||||
int x = lineStartX + i * Mathf.sign(tileX - lineStartX) * Mathf.num(result.isX());
|
||||
int y = lineStartY + i * Mathf.sign(tileY - lineStartY) * Mathf.num(!result.isX());
|
||||
|
||||
if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){
|
||||
if(!checkOverlapPlacement(x, y, block) && validPlace(x, y, block, result.rotation)){
|
||||
Draw.color();
|
||||
|
||||
TextureRegion region = recipe.result.icon(Icon.full);
|
||||
TextureRegion region = block.icon(Icon.full);
|
||||
|
||||
Draw.rect(region, x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(),
|
||||
Draw.rect(region, x * tilesize + block.offset(), y * tilesize + block.offset(),
|
||||
region.getWidth() * lineScale * Draw.scl,
|
||||
region.getHeight() * lineScale * Draw.scl,
|
||||
recipe.result.rotate ? result.rotation * 90 : 0);
|
||||
block.rotate ? result.rotation * 90 : 0);
|
||||
}else{
|
||||
Draw.color(Palette.removeBack);
|
||||
Lines.square(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset() - 1, recipe.result.size * tilesize / 2f);
|
||||
Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset() - 1, block.size * tilesize / 2f);
|
||||
Draw.color(Palette.remove);
|
||||
Lines.square(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), recipe.result.size * tilesize / 2f);
|
||||
Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset(), block.size * tilesize / 2f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,7 +440,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
int tileX = tileX(screenX);
|
||||
int tileY = tileY(screenY);
|
||||
|
||||
if(mode == placing && recipe != null){
|
||||
if(mode == placing && block != null){
|
||||
|
||||
//normalize area
|
||||
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tileX, tileY, rotation, true, 100);
|
||||
@ -449,12 +448,12 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
rotation = result.rotation;
|
||||
|
||||
//place blocks on line
|
||||
for(int i = 0; i <= result.getLength(); i += recipe.result.size){
|
||||
for(int i = 0; i <= result.getLength(); i += block.size){
|
||||
int x = lineStartX + i * Mathf.sign(tileX - lineStartX) * Mathf.num(result.isX());
|
||||
int y = lineStartY + i * Mathf.sign(tileY - lineStartY) * Mathf.num(!result.isX());
|
||||
|
||||
if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){
|
||||
PlaceRequest request = new PlaceRequest(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), recipe, result.rotation);
|
||||
if(!checkOverlapPlacement(x, y, block) && validPlace(x, y, block, result.rotation)){
|
||||
PlaceRequest request = new PlaceRequest(x * tilesize + block.offset(), y * tilesize + block.offset(), block, result.rotation);
|
||||
request.scale = 1f;
|
||||
selection.add(request);
|
||||
}
|
||||
@ -517,8 +516,8 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
if(mode == breaking){
|
||||
Effects.effect(Fx.tapBlock, cursor.worldx(), cursor.worldy(), 1f);
|
||||
}else if(recipe != null){
|
||||
Effects.effect(Fx.tapBlock, cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe.result.size);
|
||||
}else if(block != null){
|
||||
Effects.effect(Fx.tapBlock, cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block.size);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -541,9 +540,9 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
//remove if request present
|
||||
if(hasRequest(cursor)){
|
||||
removeRequest(getRequest(cursor));
|
||||
}else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, recipe.result, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, recipe.result)){
|
||||
}else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, block, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, block)){
|
||||
//add to selection queue if it's a valid place position
|
||||
selection.add(lastPlaced = new PlaceRequest(cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe, rotation));
|
||||
selection.add(lastPlaced = new PlaceRequest(cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block, rotation));
|
||||
}else if(mode == breaking && validBreak(cursor.target().x, cursor.target().y) && !hasRequest(cursor.target())){
|
||||
//add to selection queue if it's a valid BREAK position
|
||||
cursor = cursor.target();
|
||||
@ -590,27 +589,27 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
selection.clear();
|
||||
}
|
||||
|
||||
if(lineMode && mode == placing && recipe == null){
|
||||
if(lineMode && mode == placing && block == null){
|
||||
lineMode = false;
|
||||
}
|
||||
|
||||
//if there is no mode and there's a recipe, switch to placing
|
||||
if(recipe != null && mode == none){
|
||||
if(block != null && mode == none){
|
||||
mode = placing;
|
||||
}
|
||||
|
||||
if(recipe != null){
|
||||
if(block != null){
|
||||
showGuide("construction");
|
||||
}
|
||||
|
||||
if(recipe == null && mode == placing){
|
||||
if(block == null && mode == placing){
|
||||
mode = none;
|
||||
}
|
||||
|
||||
//automatically switch to placing after a new recipe is selected
|
||||
if(lastRecipe != recipe && mode == breaking && recipe != null){
|
||||
if(lastBlock != block && mode == breaking && block != null){
|
||||
mode = placing;
|
||||
lastRecipe = recipe;
|
||||
lastBlock = block;
|
||||
}
|
||||
|
||||
if(lineMode){
|
||||
@ -712,7 +711,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
class PlaceRequest{
|
||||
float x, y;
|
||||
Recipe recipe;
|
||||
Block block;
|
||||
int rotation;
|
||||
boolean remove;
|
||||
|
||||
@ -720,10 +719,10 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
float scale;
|
||||
float redness;
|
||||
|
||||
PlaceRequest(float x, float y, Recipe recipe, int rotation){
|
||||
PlaceRequest(float x, float y, Block block, int rotation){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.recipe = recipe;
|
||||
this.block = block;
|
||||
this.rotation = rotation;
|
||||
this.remove = false;
|
||||
}
|
||||
@ -735,7 +734,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
}
|
||||
|
||||
Tile tile(){
|
||||
return world.tileWorld(x - (recipe == null ? 0 : recipe.result.offset()), y - (recipe == null ? 0 : recipe.result.offset()));
|
||||
return world.tileWorld(x - (block == null ? 0 : block.offset()), y - (block == null ? 0 : block.offset()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ public class TypeIO{
|
||||
buffer.put(request.breaking ? (byte) 1 : 0);
|
||||
buffer.putInt(Pos.get(request.x, request.y));
|
||||
if(!request.breaking){
|
||||
buffer.put(request.recipe.id);
|
||||
buffer.put(request.block.id);
|
||||
buffer.put((byte) request.rotation);
|
||||
}
|
||||
}
|
||||
@ -190,9 +190,9 @@ public class TypeIO{
|
||||
if(type == 1){ //remove
|
||||
currentRequest = new BuildRequest(Pos.x(position), Pos.y(position));
|
||||
}else{ //place
|
||||
byte recipe = buffer.get();
|
||||
byte block = buffer.get();
|
||||
byte rotation = buffer.get();
|
||||
currentRequest = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.recipe(recipe));
|
||||
currentRequest = new BuildRequest(Pos.x(position), Pos.y(position), rotation, content.block(block));
|
||||
}
|
||||
|
||||
reqs[i] = (currentRequest);
|
||||
@ -302,16 +302,6 @@ public class TypeIO{
|
||||
return id == -1 ? null : content.item(id);
|
||||
}
|
||||
|
||||
@WriteClass(Recipe.class)
|
||||
public static void writeRecipe(ByteBuffer buffer, Recipe recipe){
|
||||
buffer.put(recipe.id);
|
||||
}
|
||||
|
||||
@ReadClass(Recipe.class)
|
||||
public static Recipe readRecipe(ByteBuffer buffer){
|
||||
return content.recipe(buffer.get());
|
||||
}
|
||||
|
||||
@WriteClass(String.class)
|
||||
public static void writeString(ByteBuffer buffer, String string){
|
||||
if(string != null){
|
||||
|
@ -3,7 +3,6 @@ package io.anuke.mindustry.type;
|
||||
/**Do not rearrange, ever!*/
|
||||
public enum ContentType {
|
||||
item,
|
||||
recipe,
|
||||
block,
|
||||
mech,
|
||||
bullet,
|
||||
|
@ -1,170 +0,0 @@
|
||||
package io.anuke.mindustry.type;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.ObjectMap;
|
||||
import io.anuke.arc.collection.OrderedMap;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Log;
|
||||
import io.anuke.arc.util.Strings;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.ui.ContentDisplay;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
import io.anuke.mindustry.world.meta.BlockStat;
|
||||
import io.anuke.mindustry.world.meta.ContentStatValue;
|
||||
import io.anuke.mindustry.world.meta.StatValue;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Recipe extends UnlockableContent{
|
||||
private static ObjectMap<Block, Recipe> recipeMap = new ObjectMap<>();
|
||||
private static Array<Recipe> returnArray = new Array<>();
|
||||
|
||||
public final Block result;
|
||||
public final ItemStack[] requirements;
|
||||
public final Category category;
|
||||
public final float cost;
|
||||
|
||||
public RecipeVisibility visibility = RecipeVisibility.all;
|
||||
public boolean hidden;
|
||||
public boolean alwaysUnlocked;
|
||||
|
||||
public Recipe(Category category, Block result, ItemStack... requirements){
|
||||
this.result = result;
|
||||
this.requirements = requirements;
|
||||
this.category = category;
|
||||
|
||||
Arrays.sort(requirements, (a, b) -> Integer.compare(a.item.id, b.item.id));
|
||||
|
||||
float timeToPlace = 0f;
|
||||
for(ItemStack stack : requirements){
|
||||
timeToPlace += stack.amount * stack.item.cost;
|
||||
}
|
||||
|
||||
this.cost = timeToPlace;
|
||||
|
||||
recipeMap.put(result, this);
|
||||
}
|
||||
|
||||
/**Returns all non-hidden recipes in a category.*/
|
||||
public static Array<Recipe> getByCategory(Category category){
|
||||
returnArray.clear();
|
||||
for(Recipe recipe : content.recipes()){
|
||||
if(recipe.category == category && recipe.visibility.shown()){
|
||||
returnArray.add(recipe);
|
||||
}
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
public static Recipe getByResult(Block block){
|
||||
return recipeMap.get(block);
|
||||
}
|
||||
|
||||
public Recipe setVisible(RecipeVisibility visibility){
|
||||
this.visibility = visibility;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Recipe setHidden(boolean hidden){
|
||||
this.hidden = hidden;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Recipe setAlwaysUnlocked(boolean unlocked){
|
||||
this.alwaysUnlocked = unlocked;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alwaysUnlocked(){
|
||||
return alwaysUnlocked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden(){
|
||||
return !visibility.shown() || hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayInfo(Table table){
|
||||
ContentDisplay.displayBlock(table, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String localizedName(){
|
||||
return result.formalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getContentIcon(){
|
||||
return result.icon(Icon.large);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
if(!Core.bundle.has("block." + result.name + ".name")){
|
||||
Log.err("WARNING: Recipe block '{0}' does not have a formal name defined. Add the following to bundle.properties:", result.name);
|
||||
Log.err("block.{0}.name={1}", result.name, Strings.capitalize(result.name.replace('-', '_')));
|
||||
}/*else if(result.fullDescription == null){
|
||||
Log.err("WARNING: Recipe block '{0}' does not have a description defined.", result.name);
|
||||
}*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentName(){
|
||||
return result.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType getContentType(){
|
||||
return ContentType.recipe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnlock(){
|
||||
for(OrderedMap<BlockStat, StatValue> map : result.stats.toMap().values()){
|
||||
for(StatValue value : map.values()){
|
||||
if(value instanceof ContentStatValue){
|
||||
ContentStatValue stat = (ContentStatValue) value;
|
||||
UnlockableContent[] content = stat.getValueContent();
|
||||
for(UnlockableContent c : content){
|
||||
data.unlockContent(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum RecipeVisibility{
|
||||
mobileOnly(true, false),
|
||||
desktopOnly(false, true),
|
||||
all(true, true),
|
||||
sandboxOnly(true, true){
|
||||
@Override
|
||||
public boolean usable(){
|
||||
return state.rules.infiniteResources;
|
||||
}
|
||||
};
|
||||
|
||||
public final boolean mobile, desktop;
|
||||
|
||||
RecipeVisibility(boolean mobile, boolean desktop){
|
||||
this.mobile = mobile;
|
||||
this.desktop = desktop;
|
||||
}
|
||||
|
||||
public boolean usable(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean shown(){
|
||||
return usable() && ((Vars.mobile && mobile) || (!Vars.mobile && desktop));
|
||||
}
|
||||
}
|
||||
}
|
@ -24,10 +24,9 @@ import io.anuke.mindustry.content.TechTree;
|
||||
import io.anuke.mindustry.content.TechTree.TechNode;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.type.Recipe.RecipeVisibility;
|
||||
import io.anuke.mindustry.ui.TreeLayout;
|
||||
import io.anuke.mindustry.ui.TreeLayout.TreeNode;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@ -50,15 +49,15 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
cont.add(new View()).grow();
|
||||
|
||||
{ //debug code; TODO remove
|
||||
ObjectSet<Recipe> used = new ObjectSet<Recipe>().select(t -> true);
|
||||
ObjectSet<Block> used = new ObjectSet<Block>().select(t -> true);
|
||||
for(TechTreeNode node : nodes){
|
||||
used.add(node.node.recipe());
|
||||
used.add(node.node.block);
|
||||
}
|
||||
Array<Recipe> recipes = content.recipes().select(r -> r.visibility == RecipeVisibility.all && !used.contains(r));
|
||||
recipes.sort(Structs.comparing(r -> r.cost));
|
||||
Array<Block> recipes = content.blocks().select(r -> r.isVisible() && !used.contains(r));
|
||||
recipes.sort(Structs.comparing(r -> r.buildCost));
|
||||
|
||||
if(recipes.size > 0){
|
||||
Log.info("Recipe tree coverage: {0}%", (int)((float)nodes.size / content.recipes().select(r -> r.visibility == RecipeVisibility.all).size * 100));
|
||||
Log.info("Recipe tree coverage: {0}%", (int)((float)nodes.size / content.blocks().select(Block::isVisible).size * 100));
|
||||
Log.info("Missing items: ");
|
||||
recipes.forEach(r -> Log.info(" {0}", r));
|
||||
}
|
||||
@ -111,7 +110,7 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
}
|
||||
|
||||
boolean locked(TechNode node){
|
||||
return !data.isUnlocked(node.recipe());
|
||||
return !data.isUnlocked(node.block);
|
||||
}
|
||||
|
||||
class TechTreeNode extends TreeNode{
|
||||
@ -199,7 +198,7 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
}
|
||||
|
||||
void unlock(TechNode node){
|
||||
data.unlockContent(node.recipe());
|
||||
data.unlockContent(node.block);
|
||||
data.removeItems(node.requirements);
|
||||
showToast(Core.bundle.format("researched", node.block.formalName));
|
||||
checkNodes(root);
|
||||
@ -230,7 +229,7 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
|
||||
infoTable.margin(0).left().defaults().left();
|
||||
|
||||
infoTable.addImageButton("icon-info", "node", 14*2, () -> ui.content.show(node.recipe())).growY().width(50f);
|
||||
infoTable.addImageButton("icon-info", "node", 14*2, () -> ui.content.show(node.block)).growY().width(50f);
|
||||
|
||||
infoTable.add().grow();
|
||||
|
||||
|
@ -22,7 +22,6 @@ import io.anuke.mindustry.input.Binding;
|
||||
import io.anuke.mindustry.input.InputHandler;
|
||||
import io.anuke.mindustry.type.Category;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@ -33,6 +32,7 @@ import static io.anuke.mindustry.Vars.*;
|
||||
public class PlacementFragment extends Fragment{
|
||||
final int rowWidth = 4;
|
||||
|
||||
Array<Block> returnArray = new Array<>();
|
||||
Category currentCategory = Category.turret;
|
||||
Block hovered, lastDisplay;
|
||||
Tile hoverTile;
|
||||
@ -68,8 +68,8 @@ public class PlacementFragment extends Fragment{
|
||||
int i = 0;
|
||||
for(KeyCode key : inputCatGrid){
|
||||
if(Core.input.keyDown(key)){
|
||||
input.recipe = Recipe.getByCategory(Category.values()[i]).first();
|
||||
currentCategory = input.recipe.category;
|
||||
input.block = getByCategory(Category.values()[i]).first();
|
||||
currentCategory = input.block.buildCategory;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@ -79,19 +79,19 @@ public class PlacementFragment extends Fragment{
|
||||
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
Recipe tryRecipe = Recipe.getByResult(tile.block());
|
||||
if(tryRecipe != null && data.isUnlocked(tryRecipe)){
|
||||
input.recipe = tryRecipe;
|
||||
currentCategory = input.recipe.category;
|
||||
Block tryRecipe = tile.block();
|
||||
if(tryRecipe.isVisible() && data.isUnlocked(tryRecipe)){
|
||||
input.block = tryRecipe;
|
||||
currentCategory = input.block.buildCategory;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}else{ //select block
|
||||
int i = 0;
|
||||
Array<Recipe> recipes = Recipe.getByCategory(currentCategory);
|
||||
Array<Block> recipes = getByCategory(currentCategory);
|
||||
for(KeyCode key : inputGrid){
|
||||
if(Core.input.keyDown(key))
|
||||
input.recipe = (i < recipes.size && data.isUnlocked(recipes.get(i))) ? recipes.get(i) : null;
|
||||
input.block = (i < recipes.size && data.isUnlocked(recipes.get(i))) ? recipes.get(i) : null;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -117,7 +117,7 @@ public class PlacementFragment extends Fragment{
|
||||
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
||||
group.setMinCheckCount(0);
|
||||
|
||||
for(Recipe recipe : Recipe.getByCategory(currentCategory)){
|
||||
for(Block block : getByCategory(currentCategory)){
|
||||
|
||||
if(index++ % rowWidth == 0){
|
||||
blockTable.row();
|
||||
@ -126,17 +126,17 @@ public class PlacementFragment extends Fragment{
|
||||
boolean[] unlocked = {false};
|
||||
|
||||
ImageButton button = blockTable.addImageButton("icon-locked", "select", 8 * 4, () -> {
|
||||
if(data.isUnlocked(recipe)){
|
||||
input.recipe = input.recipe == recipe ? null : recipe;
|
||||
if(data.isUnlocked(block)){
|
||||
input.block = input.block == block ? null : block;
|
||||
}
|
||||
}).size(46f).group(group).get();
|
||||
|
||||
button.update(() -> { //color unplacable things gray
|
||||
boolean ulock = data.isUnlocked(recipe);
|
||||
boolean ulock = data.isUnlocked(block);
|
||||
TileEntity core = players[0].getClosestCore();
|
||||
Color color = core != null && (core.items.has(recipe.requirements) || state.rules.infiniteResources) ? Color.WHITE : ulock ? Color.GRAY : Color.WHITE;
|
||||
Color color = core != null && (core.items.has(block.buildRequirements) || state.rules.infiniteResources) ? Color.WHITE : ulock ? Color.GRAY : Color.WHITE;
|
||||
button.forEach(elem -> elem.setColor(color));
|
||||
button.setChecked(input.recipe == recipe);
|
||||
button.setChecked(input.block == block);
|
||||
|
||||
if(ulock == unlocked[0]) return;
|
||||
unlocked[0] = ulock;
|
||||
@ -144,13 +144,13 @@ public class PlacementFragment extends Fragment{
|
||||
if(!ulock){
|
||||
button.replaceImage(new Image("icon-locked"));
|
||||
}else{
|
||||
button.replaceImage(new Image(recipe.result.icon(Icon.medium)));
|
||||
button.replaceImage(new Image(block.icon(Icon.medium)));
|
||||
}
|
||||
});
|
||||
|
||||
button.hovered(() -> hovered = recipe.result);
|
||||
button.hovered(() -> hovered = block);
|
||||
button.exited(() -> {
|
||||
if(hovered == recipe.result){
|
||||
if(hovered == block){
|
||||
hovered = null;
|
||||
}
|
||||
});
|
||||
@ -176,11 +176,11 @@ public class PlacementFragment extends Fragment{
|
||||
header.left();
|
||||
header.add(new Image(lastDisplay.icon(Icon.medium))).size(8 * 4);
|
||||
header.labelWrap(() ->
|
||||
!data.isUnlocked(Recipe.getByResult(lastDisplay)) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName)
|
||||
!data.isUnlocked(lastDisplay) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName)
|
||||
.left().width(190f).padLeft(5);
|
||||
header.add().growX();
|
||||
if(data.isUnlocked(Recipe.getByResult(lastDisplay))){
|
||||
header.addButton("?", "clear-partial", () -> ui.content.show(Recipe.getByResult(lastDisplay)))
|
||||
if(data.isUnlocked(lastDisplay)){
|
||||
header.addButton("?", "clear-partial", () -> ui.content.show(lastDisplay))
|
||||
.size(8 * 5).padTop(-5).padRight(-5).right().grow();
|
||||
}
|
||||
}).growX().left();
|
||||
@ -189,7 +189,7 @@ public class PlacementFragment extends Fragment{
|
||||
topTable.table(req -> {
|
||||
req.top().left();
|
||||
|
||||
for(ItemStack stack : Recipe.getByResult(lastDisplay).requirements){
|
||||
for(ItemStack stack : lastDisplay.buildRequirements){
|
||||
req.table(line -> {
|
||||
line.left();
|
||||
line.addImage(stack.item.region).size(8 * 2);
|
||||
@ -230,7 +230,7 @@ public class PlacementFragment extends Fragment{
|
||||
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
||||
|
||||
for(Category cat : Category.values()){
|
||||
if(Recipe.getByCategory(cat).isEmpty()) continue;
|
||||
if(getByCategory(cat).isEmpty()) continue;
|
||||
|
||||
categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16 * 2, () -> {
|
||||
currentCategory = cat;
|
||||
@ -248,6 +248,16 @@ public class PlacementFragment extends Fragment{
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Array<Block> getByCategory(Category cat){
|
||||
returnArray.clear();
|
||||
for(Block block : content.blocks()){
|
||||
if(block.buildCategory == cat && block.isVisible()){
|
||||
returnArray.add(block);
|
||||
}
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/** Returns the currently displayed block in the top box. */
|
||||
Block getSelected(){
|
||||
@ -268,8 +278,8 @@ public class PlacementFragment extends Fragment{
|
||||
}
|
||||
|
||||
//block currently selected
|
||||
if(control.input(0).recipe != null){
|
||||
toDisplay = control.input(0).recipe.result;
|
||||
if(control.input(0).block != null){
|
||||
toDisplay = control.input(0).block;
|
||||
}
|
||||
|
||||
//block hovered on in build menu
|
||||
|
@ -6,6 +6,7 @@ import io.anuke.arc.Graphics.Cursor.SystemCursor;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.EnumSet;
|
||||
import io.anuke.arc.collection.IntArray;
|
||||
import io.anuke.arc.function.BooleanProvider;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.Lines;
|
||||
@ -20,19 +21,26 @@ import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.entities.bullet.Bullet;
|
||||
import io.anuke.mindustry.entities.effect.Puddle;
|
||||
import io.anuke.mindustry.entities.effect.RubbleDecal;
|
||||
import io.anuke.mindustry.game.Content;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.graphics.CacheLayer;
|
||||
import io.anuke.mindustry.graphics.Layer;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.Category;
|
||||
import io.anuke.mindustry.type.ContentType;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.ui.ContentDisplay;
|
||||
import io.anuke.mindustry.world.consumers.ConsumePower;
|
||||
import io.anuke.mindustry.world.meta.*;
|
||||
import io.anuke.mindustry.world.meta.BlockFlag;
|
||||
import io.anuke.mindustry.world.meta.BlockGroup;
|
||||
import io.anuke.mindustry.world.meta.BlockStat;
|
||||
import io.anuke.mindustry.world.meta.StatUnit;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Block extends BaseBlock {
|
||||
public class Block extends BlockStorage{
|
||||
/** internal name */
|
||||
public final String name;
|
||||
/** display name */
|
||||
@ -77,8 +85,6 @@ public class Block extends BaseBlock {
|
||||
public boolean instantTransfer = false;
|
||||
/** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */
|
||||
public BlockGroup group = BlockGroup.none;
|
||||
/** List of block stats. */
|
||||
public BlockStats stats = new BlockStats(this);
|
||||
/** List of block flags. Used for AI indexing. */
|
||||
public EnumSet<BlockFlag> flags;
|
||||
/** Whether the block can be tapped and selected to configure. */
|
||||
@ -92,6 +98,16 @@ public class Block extends BaseBlock {
|
||||
/**Whether the overdrive core has any effect on this block.*/
|
||||
public boolean canOverdrive = true;
|
||||
|
||||
/**Cost of constructing this block.*/
|
||||
public ItemStack[] buildRequirements = new ItemStack[]{};
|
||||
/**Category in place menu.*/
|
||||
public Category buildCategory = Category.distribution;
|
||||
/**Cost of building this block; do not modify directly!*/
|
||||
public float buildCost;
|
||||
/**Whether this block is visible and can currently be built.*/
|
||||
public BooleanProvider buildVisibility = () -> false;
|
||||
public boolean alwaysUnlocked = false;
|
||||
|
||||
protected Array<Tile> tempTiles = new Array<>();
|
||||
protected TextureRegion[] icons = new TextureRegion[Icon.values().length];
|
||||
protected TextureRegion[] generatedIcons;
|
||||
@ -104,16 +120,6 @@ public class Block extends BaseBlock {
|
||||
this.solid = false;
|
||||
}
|
||||
|
||||
/**Populates the array with all blocks that produce this content.*/
|
||||
public static void getByProduction(Array<Block> arr, Content result){
|
||||
arr.clear();
|
||||
for(Block block : content.blocks()){
|
||||
if(block.produces.get() == result){
|
||||
arr.add(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canBreak(Tile tile){
|
||||
return true;
|
||||
}
|
||||
@ -194,6 +200,14 @@ public class Block extends BaseBlock {
|
||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||
}
|
||||
|
||||
public void draw(Tile tile){
|
||||
Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.getRotation() * 90 : 0);
|
||||
}
|
||||
|
||||
public void drawShadow(Tile tile){
|
||||
draw(tile);
|
||||
}
|
||||
|
||||
/** Called after the block is placed by this client. */
|
||||
public void playerPlaced(Tile tile){
|
||||
}
|
||||
@ -221,6 +235,21 @@ public class Block extends BaseBlock {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String localizedName(){
|
||||
return formalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getContentIcon(){
|
||||
return icon(Icon.medium);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayInfo(Table table){
|
||||
ContentDisplay.displayBlock(table, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType getContentType(){
|
||||
return ContentType.block;
|
||||
@ -239,6 +268,11 @@ public class Block extends BaseBlock {
|
||||
health = size * size * 40;
|
||||
}
|
||||
|
||||
buildCost = 0f;
|
||||
for(ItemStack stack : buildRequirements){
|
||||
buildCost += stack.amount * stack.item.cost;
|
||||
}
|
||||
|
||||
setStats();
|
||||
|
||||
consumes.checkRequired(this);
|
||||
@ -319,10 +353,6 @@ public class Block extends BaseBlock {
|
||||
if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity, StatUnit.items);
|
||||
}
|
||||
|
||||
public String name(){
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isSolidFor(Tile tile){
|
||||
return false;
|
||||
}
|
||||
@ -458,14 +488,6 @@ public class Block extends BaseBlock {
|
||||
return new TileEntity();
|
||||
}
|
||||
|
||||
public void draw(Tile tile){
|
||||
Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.getRotation() * 90 : 0);
|
||||
}
|
||||
|
||||
public void drawShadow(Tile tile){
|
||||
draw(tile);
|
||||
}
|
||||
|
||||
/** Offset for placing and drawing multiblocks. */
|
||||
public float offset(){
|
||||
return ((size + 1) % 2) * tilesize / 2f;
|
||||
@ -475,19 +497,26 @@ public class Block extends BaseBlock {
|
||||
return size > 1;
|
||||
}
|
||||
|
||||
public Array<Object> getDebugInfo(Tile tile){
|
||||
return Array.with(
|
||||
"block", tile.block().name,
|
||||
"floor", tile.floor().name,
|
||||
"x", tile.x,
|
||||
"y", tile.y,
|
||||
"entity.name", tile.entity.getClass(),
|
||||
"entity.x", tile.entity.x,
|
||||
"entity.y", tile.entity.y,
|
||||
"entity.id", tile.entity.id,
|
||||
"entity.items.total", hasItems ? tile.entity.items.total() : null,
|
||||
"entity.graph", tile.entity.power != null && tile.entity.power.graph != null ? tile.entity.power.graph.getID() : null
|
||||
);
|
||||
public boolean isVisible(){
|
||||
return buildVisibility.get() && !isHidden();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alwaysUnlocked(){
|
||||
return alwaysUnlocked;
|
||||
}
|
||||
|
||||
protected void requirements(Category cat, ItemStack[] stacks){
|
||||
requirements(cat, () -> true, stacks);
|
||||
}
|
||||
|
||||
/**Sets up requirements. Use only this method to set up requirements.*/
|
||||
protected void requirements(Category cat, BooleanProvider visible, ItemStack[] stacks){
|
||||
this.buildCategory = cat;
|
||||
this.buildRequirements = stacks;
|
||||
this.buildVisibility = visible;
|
||||
|
||||
Arrays.sort(buildRequirements, (a, b) -> Integer.compare(a.item.id, b.item.id));
|
||||
}
|
||||
|
||||
public enum Icon{
|
||||
|
@ -10,15 +10,16 @@ import io.anuke.mindustry.content.Fx;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.entities.effect.Puddle;
|
||||
import io.anuke.mindustry.game.MappableContent;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.world.consumers.ConsumeItem;
|
||||
import io.anuke.mindustry.world.consumers.ConsumeLiquid;
|
||||
import io.anuke.mindustry.world.consumers.Consumers;
|
||||
import io.anuke.mindustry.world.meta.BlockStats;
|
||||
import io.anuke.mindustry.world.meta.Producers;
|
||||
|
||||
public abstract class BaseBlock extends MappableContent{
|
||||
public abstract class BlockStorage extends UnlockableContent{
|
||||
public boolean hasItems;
|
||||
public boolean hasLiquids;
|
||||
public boolean hasPower;
|
||||
@ -32,6 +33,7 @@ public abstract class BaseBlock extends MappableContent{
|
||||
public float liquidCapacity = 10f;
|
||||
public float liquidFlowFactor = 4.9f;
|
||||
|
||||
public BlockStats stats = new BlockStats();
|
||||
public Consumers consumes = new Consumers();
|
||||
public Producers produces = new Producers();
|
||||
|
@ -11,7 +11,6 @@ import io.anuke.mindustry.entities.Units;
|
||||
import io.anuke.mindustry.game.EventType.BlockBuildBeginEvent;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.type.ContentType;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@ -64,8 +63,8 @@ public class Build{
|
||||
}
|
||||
|
||||
/**Places a BuildBlock at this location.*/
|
||||
public static void beginPlace(Team team, int x, int y, Recipe recipe, int rotation){
|
||||
if(!validPlace(team, x, y, recipe.result, rotation)){
|
||||
public static void beginPlace(Team team, int x, int y, Block result, int rotation){
|
||||
if(!validPlace(team, x, y, result, rotation)){
|
||||
return;
|
||||
}
|
||||
|
||||
@ -74,13 +73,12 @@ public class Build{
|
||||
//just in case
|
||||
if(tile == null) return;
|
||||
|
||||
Block result = recipe.result;
|
||||
Block previous = tile.block();
|
||||
|
||||
Block sub = content.getByName(ContentType.block, "build" + result.size);
|
||||
|
||||
tile.setBlock(sub, rotation);
|
||||
tile.<BuildEntity>entity().setConstruct(previous, recipe);
|
||||
tile.<BuildEntity>entity().setConstruct(previous, result);
|
||||
tile.setTeam(team);
|
||||
|
||||
if(result.isMultiblock()){
|
||||
@ -107,9 +105,7 @@ public class Build{
|
||||
|
||||
/**Returns whether a tile can be placed at this location by this team.*/
|
||||
public static boolean validPlace(Team team, int x, int y, Block type, int rotation){
|
||||
Recipe recipe = Recipe.getByResult(type);
|
||||
|
||||
if(recipe == null || (!recipe.visibility.usable())){
|
||||
if(!type.isVisible() || type.isHidden()){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -418,7 +418,7 @@ public class Tile implements Position, TargetTrait{
|
||||
Block block = block();
|
||||
Block floor = floor();
|
||||
|
||||
return floor.name() + ":" + block.name() + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) +
|
||||
return floor.name + ":" + block.name + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) +
|
||||
(link != 0 ? " link=[" + (Pack.leftByte(link) - 8) + ", " + (Pack.rightByte(link) - 8) + "]" : "");
|
||||
}
|
||||
}
|
@ -23,7 +23,6 @@ import io.anuke.mindustry.graphics.Layer;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.modules.ItemModule;
|
||||
@ -74,19 +73,19 @@ public class BuildBlock extends Block{
|
||||
@Override
|
||||
public String getDisplayName(Tile tile){
|
||||
BuildEntity entity = tile.entity();
|
||||
return Core.bundle.format("block.constructing", entity.recipe == null ? entity.previous.formalName : entity.recipe.result.formalName);
|
||||
return Core.bundle.format("block.constructing", entity.block == null ? entity.previous.formalName : entity.block.formalName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getDisplayIcon(Tile tile){
|
||||
BuildEntity entity = tile.entity();
|
||||
return (entity.recipe == null ? entity.previous : entity.recipe.result).icon(Icon.full);
|
||||
return (entity.block == null ? entity.previous : entity.block).icon(Icon.full);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolidFor(Tile tile){
|
||||
BuildEntity entity = tile.entity();
|
||||
return entity == null || (entity.recipe != null && entity.recipe.result.solid) || entity.previous == null || entity.previous.solid;
|
||||
return entity == null || (entity.block != null && entity.block.solid) || entity.previous == null || entity.previous.solid;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,9 +98,9 @@ public class BuildBlock extends Block{
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
//if the target is constructible, begin constructing
|
||||
if(entity.recipe != null){
|
||||
if(entity.block != null){
|
||||
player.clearBuilding();
|
||||
player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.getRotation(), entity.recipe));
|
||||
player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.getRotation(), entity.block));
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +118,7 @@ public class BuildBlock extends Block{
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
//When breaking, don't draw the previous block... since it's the thing you were breaking
|
||||
if(entity.recipe != null && entity.previous == entity.recipe.result){
|
||||
if(entity.block != null && entity.previous == entity.block){
|
||||
return;
|
||||
}
|
||||
|
||||
@ -135,7 +134,7 @@ public class BuildBlock extends Block{
|
||||
|
||||
Shaders.blockbuild.color = Palette.accent;
|
||||
|
||||
Block target = entity.recipe == null ? entity.previous : entity.recipe.result;
|
||||
Block target = entity.block == null ? entity.previous : entity.block;
|
||||
|
||||
if(target == null) return;
|
||||
|
||||
@ -163,7 +162,7 @@ public class BuildBlock extends Block{
|
||||
* The recipe of the block that is being constructed.
|
||||
* If there is no recipe for this block, as is the case with rocks, 'previous' is used.
|
||||
*/
|
||||
public Recipe recipe;
|
||||
public Block block;
|
||||
|
||||
public float progress = 0;
|
||||
public float buildCost;
|
||||
@ -178,16 +177,16 @@ public class BuildBlock extends Block{
|
||||
private float[] totalAccumulator;
|
||||
|
||||
public void construct(Unit builder, TileEntity core, float amount){
|
||||
if(recipe == null){
|
||||
if(block == null){
|
||||
damage(99999);
|
||||
return;
|
||||
}
|
||||
|
||||
float maxProgress = checkRequired(core.items, amount, false);
|
||||
|
||||
for(int i = 0; i < recipe.requirements.length; i++){
|
||||
accumulator[i] += Math.min(recipe.requirements[i].amount * maxProgress, recipe.requirements[i].amount - totalAccumulator[i] + 0.00001f); //add min amount progressed to the accumulator
|
||||
totalAccumulator[i] = Math.min(totalAccumulator[i] + recipe.requirements[i].amount * maxProgress, recipe.requirements[i].amount);
|
||||
for(int i = 0; i < block.buildRequirements.length; i++){
|
||||
accumulator[i] += Math.min(block.buildRequirements[i].amount * maxProgress, block.buildRequirements[i].amount - totalAccumulator[i] + 0.00001f); //add min amount progressed to the accumulator
|
||||
totalAccumulator[i] = Math.min(totalAccumulator[i] + block.buildRequirements[i].amount * maxProgress, block.buildRequirements[i].amount);
|
||||
}
|
||||
|
||||
maxProgress = checkRequired(core.items, maxProgress, true);
|
||||
@ -199,24 +198,23 @@ public class BuildBlock extends Block{
|
||||
}
|
||||
|
||||
if(progress >= 1f || state.rules.infiniteResources){
|
||||
Call.onConstructFinish(tile, recipe.result, builderID, tile.getRotation(), builder.getTeam());
|
||||
Call.onConstructFinish(tile, block, builderID, tile.getRotation(), builder.getTeam());
|
||||
}
|
||||
}
|
||||
|
||||
public void deconstruct(Unit builder, TileEntity core, float amount){
|
||||
Recipe recipe = Recipe.getByResult(previous);
|
||||
|
||||
if(recipe != null){
|
||||
ItemStack[] requirements = recipe.requirements;
|
||||
if(block != null){
|
||||
ItemStack[] requirements = block.buildRequirements;
|
||||
if(requirements.length != accumulator.length || totalAccumulator.length != requirements.length){
|
||||
setDeconstruct(previous);
|
||||
}
|
||||
|
||||
for(int i = 0; i < requirements.length; i++){
|
||||
accumulator[i] += Math.min(requirements[i].amount * amount / 2f, requirements[i].amount/2f - totalAccumulator[i]); //add scaled amount progressed to the accumulator
|
||||
accumulator[i] += Math.min(requirements[i].amount * amount / 2f, requirements[i].amount / 2f - totalAccumulator[i]); //add scaled amount progressed to the accumulator
|
||||
totalAccumulator[i] = Math.min(totalAccumulator[i] + requirements[i].amount * amount / 2f, requirements[i].amount);
|
||||
|
||||
int accumulated = (int) (accumulator[i]); //get amount
|
||||
int accumulated = (int)(accumulator[i]); //get amount
|
||||
|
||||
if(amount > 0 && accumulated > 0){ //if it's positive, add it to the core
|
||||
int accepting = core.tile.block().acceptStack(requirements[i].item, accumulated, core.tile, builder);
|
||||
@ -230,21 +228,21 @@ public class BuildBlock extends Block{
|
||||
progress = Mathf.clamp(progress - amount);
|
||||
|
||||
if(progress <= 0 || state.rules.infiniteResources){
|
||||
Call.onDeconstructFinish(tile, this.recipe == null ? previous : this.recipe.result);
|
||||
Call.onDeconstructFinish(tile, this.block == null ? previous : this.block);
|
||||
}
|
||||
}
|
||||
|
||||
private float checkRequired(ItemModule inventory, float amount, boolean remove){
|
||||
float maxProgress = amount;
|
||||
|
||||
for(int i = 0; i < recipe.requirements.length; i++){
|
||||
for(int i = 0; i < block.buildRequirements.length; i++){
|
||||
int required = (int) (accumulator[i]); //calculate items that are required now
|
||||
|
||||
if(inventory.get(recipe.requirements[i].item) == 0){
|
||||
if(inventory.get(block.buildRequirements[i].item) == 0){
|
||||
maxProgress = 0f;
|
||||
}else if(required > 0){ //if this amount is positive...
|
||||
//calculate how many items it can actually use
|
||||
int maxUse = Math.min(required, inventory.get(recipe.requirements[i].item));
|
||||
int maxUse = Math.min(required, inventory.get(block.buildRequirements[i].item));
|
||||
//get this as a fraction
|
||||
float fraction = maxUse / (float) required;
|
||||
|
||||
@ -255,7 +253,7 @@ public class BuildBlock extends Block{
|
||||
|
||||
//remove stuff that is actually used
|
||||
if(remove){
|
||||
inventory.remove(recipe.requirements[i].item, maxUse);
|
||||
inventory.remove(block.buildRequirements[i].item, maxUse);
|
||||
}
|
||||
}
|
||||
//else, no items are required yet, so just keep going
|
||||
@ -268,24 +266,24 @@ public class BuildBlock extends Block{
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setConstruct(Block previous, Recipe recipe){
|
||||
this.recipe = recipe;
|
||||
public void setConstruct(Block previous, Block block){
|
||||
this.block = block;
|
||||
this.previous = previous;
|
||||
this.accumulator = new float[recipe.requirements.length];
|
||||
this.totalAccumulator = new float[recipe.requirements.length];
|
||||
this.buildCost = recipe.cost;
|
||||
this.accumulator = new float[block.buildRequirements.length];
|
||||
this.totalAccumulator = new float[block.buildRequirements.length];
|
||||
this.buildCost = block.buildCost;
|
||||
}
|
||||
|
||||
public void setDeconstruct(Block previous){
|
||||
this.previous = previous;
|
||||
this.progress = 1f;
|
||||
if(Recipe.getByResult(previous) != null){
|
||||
this.recipe = Recipe.getByResult(previous);
|
||||
this.accumulator = new float[Recipe.getByResult(previous).requirements.length];
|
||||
this.totalAccumulator = new float[Recipe.getByResult(previous).requirements.length];
|
||||
this.buildCost = Recipe.getByResult(previous).cost;
|
||||
if(previous.buildCost > 1f){
|
||||
this.block = previous;
|
||||
this.accumulator = new float[previous.buildRequirements.length];
|
||||
this.totalAccumulator = new float[previous.buildRequirements.length];
|
||||
this.buildCost = previous.buildCost;
|
||||
}else{
|
||||
this.buildCost = 20f; //default no-recipe build cost is 20
|
||||
this.buildCost = 20f; //default no-requirement build cost is 20
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,7 +291,7 @@ public class BuildBlock extends Block{
|
||||
public void write(DataOutput stream) throws IOException{
|
||||
stream.writeFloat(progress);
|
||||
stream.writeShort(previous == null ? -1 : previous.id);
|
||||
stream.writeShort(recipe == null ? -1 : recipe.result.id);
|
||||
stream.writeShort(block == null ? -1 : block.id);
|
||||
|
||||
if(accumulator == null){
|
||||
stream.writeByte(-1);
|
||||
@ -323,10 +321,10 @@ public class BuildBlock extends Block{
|
||||
}
|
||||
|
||||
if(pid != -1) previous = content.block(pid);
|
||||
if(rid != -1) recipe = Recipe.getByResult(content.block(rid));
|
||||
if(rid != -1) block = content.block(rid);
|
||||
|
||||
if(recipe != null){
|
||||
buildCost = recipe.cost;
|
||||
if(block != null){
|
||||
buildCost = block.buildCost;
|
||||
}else{
|
||||
buildCost = 20f;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class LiquidBlock extends Block{
|
||||
|
||||
@Override
|
||||
public TextureRegion[] generateIcons(){
|
||||
return new TextureRegion[]{Core.atlas.find(name() + "-bottom"), Core.atlas.find(name() + "-top")};
|
||||
return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name + "-top")};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.anuke.mindustry.world.blocks.distribution;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.LongArray;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
@ -333,17 +332,6 @@ public class Conveyor extends Block{
|
||||
entity.lastInserted = (byte)(entity.convey.size-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array<Object> getDebugInfo(Tile tile){
|
||||
ConveyorEntity entity = tile.entity();
|
||||
Array<Object> arr = super.getDebugInfo(tile);
|
||||
arr.addAll(Array.<Object>with(
|
||||
"clogHeat", entity.clogHeat,
|
||||
"sleeping", entity.isSleeping()
|
||||
));
|
||||
return arr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity newEntity(){
|
||||
return new ConveyorEntity();
|
||||
|
@ -23,7 +23,7 @@ public class LiquidJunction extends LiquidBlock{
|
||||
|
||||
@Override
|
||||
public void draw(Tile tile){
|
||||
Draw.rect(name(), tile.worldx(), tile.worldy());
|
||||
Draw.rect(name, tile.worldx(), tile.worldy());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,7 +50,7 @@ public class GenericCrafter extends Block{
|
||||
|
||||
@Override
|
||||
public void draw(Tile tile){
|
||||
Draw.rect(name(), tile.drawx(), tile.drawy());
|
||||
Draw.rect(name, tile.drawx(), tile.drawy());
|
||||
|
||||
if(!hasLiquids) return;
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class Pump extends LiquidBlock{
|
||||
|
||||
@Override
|
||||
public void draw(Tile tile){
|
||||
Draw.rect(name(), tile.drawx(), tile.drawy());
|
||||
Draw.rect(name, tile.drawx(), tile.drawy());
|
||||
|
||||
Draw.color(tile.entity.liquids.current().color);
|
||||
Draw.alpha(tile.entity.liquids.total() / liquidCapacity);
|
||||
|
@ -103,7 +103,7 @@ public class UnitFactory extends Block{
|
||||
UnitFactoryEntity entity = tile.entity();
|
||||
TextureRegion region = type.iconRegion;
|
||||
|
||||
Draw.rect(name(), tile.drawx(), tile.drawy());
|
||||
Draw.rect(name, tile.drawx(), tile.drawy());
|
||||
|
||||
Shaders.build.region = region;
|
||||
Shaders.build.progress = entity.buildTime / produceTime;
|
||||
|
@ -7,7 +7,6 @@ import io.anuke.arc.util.Log;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.meta.values.*;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -17,13 +16,8 @@ public class BlockStats{
|
||||
private static final boolean errorWhenMissing = false;
|
||||
|
||||
private final OrderedMap<StatCategory, OrderedMap<BlockStat, StatValue>> map = new OrderedMap<>();
|
||||
private final Block block;
|
||||
private boolean dirty;
|
||||
|
||||
public BlockStats(Block block){
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
/**Adds a single float value with this stat, formatted to 2 decimal places.*/
|
||||
public void add(BlockStat stat, float value, StatUnit unit){
|
||||
add(stat, new NumberValue(value, unit));
|
||||
@ -73,7 +67,7 @@ public class BlockStats{
|
||||
}
|
||||
|
||||
if(map.containsKey(stat.category) && map.get(stat.category).containsKey(stat)){
|
||||
throw new RuntimeException("Duplicate stat entry: \"" + stat + "\" in block '" + block.name + "'");
|
||||
throw new RuntimeException("Duplicate stat entry: \"" + stat + "\" in block.");
|
||||
}
|
||||
|
||||
if(!map.containsKey(stat.category)){
|
||||
@ -88,7 +82,7 @@ public class BlockStats{
|
||||
/**Removes a stat, if it exists.*/
|
||||
public void remove(BlockStat stat){
|
||||
if(!map.containsKey(stat.category) || !map.get(stat.category).containsKey(stat)){
|
||||
throw new RuntimeException("No stat entry found: \"" + stat + "\" in block '" + block.name + "'!");
|
||||
throw new RuntimeException("No stat entry found: \"" + stat + "\" in block.");
|
||||
}
|
||||
|
||||
map.get(stat.category).remove(stat);
|
||||
|
@ -22,7 +22,6 @@ import io.anuke.mindustry.io.SaveIO;
|
||||
import io.anuke.mindustry.maps.Map;
|
||||
import io.anuke.mindustry.type.ContentType;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Edges;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
Loading…
Reference in New Issue
Block a user