New placement system without limits, queue block placements

This commit is contained in:
Anuken 2018-05-17 20:36:43 -07:00
parent 97cac33773
commit 19e62786c9
20 changed files with 283 additions and 164 deletions

View file

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

Before After
Before After

View file

@ -16,17 +16,17 @@ varying vec4 v_color;
varying vec2 v_texCoord;
bool id(vec2 coords, vec4 base, float basediff){
bool id(vec2 coords, vec4 base){
vec4 target = texture2D(u_texture, coords);
return target.a < 0.1 || (coords.x < u_uv.x || coords.y < u_uv.y || coords.x > u_uv2.x || coords.y > u_uv2.y);
}
bool cont(vec2 T, vec2 v, float basediff){
bool cont(vec2 T, vec2 v){
float step = 1.0;
vec4 base = texture2D(u_texture, T);
return base.a > 0.1 &&
(id(T + vec2(0, step) * v, base, basediff) || id(T + vec2(0, -step) * v, base, basediff) ||
id(T + vec2(step, 0) * v, base, basediff) || id(T + vec2(-step, 0) * v, base, basediff));
(id(T + vec2(0, step) * v, base) || id(T + vec2(0, -step) * v, base) ||
id(T + vec2(step, 0) * v, base) || id(T + vec2(-step, 0) * v, base));
}
float rand(vec2 co){
@ -51,7 +51,7 @@ void main() {
chance = 1.0-(u_progress-0.8)*5.0;
}
if((mod(u_time / 1.5 + value, 20.0) < 5.0 && cont(t, v, 0.0)) && rand(coords) < chance){
if((mod(u_time / 1.5 + value, 20.0) < 5.0 && cont(t, v)) && rand(coords) < chance){
gl_FragColor = u_color;
}else if(dst > (1.0-u_progress) * (center.x)){
gl_FragColor = color;

View file

@ -0,0 +1,40 @@
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D u_texture;
uniform vec4 u_color;
uniform vec2 u_texsize;
uniform vec2 u_uv;
uniform vec2 u_uv2;
varying vec4 v_color;
varying vec2 v_texCoord;
bool id(vec2 coords, vec4 base){
vec4 target = texture2D(u_texture, coords);
return target.a < 0.1 || (coords.x < u_uv.x || coords.y < u_uv.y || coords.x > u_uv2.x || coords.y > u_uv2.y);
}
bool cont(vec2 T, vec2 v){
float step = 1.0;
vec4 base = texture2D(u_texture, T);
return base.a > 0.1 &&
(id(T + vec2(0, step) * v, base) || id(T + vec2(0, -step) * v, base) ||
id(T + vec2(step, 0) * v, base) || id(T + vec2(-step, 0) * v, base));
}
void main() {
vec2 t = v_texCoord.xy;
vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y);
vec2 coord = t / v;
vec4 c = texture2D(u_texture, t);
if(cont(t, v) ){
gl_FragColor = u_color;
}else{
gl_FragColor = vec4(0.0);
}
}

View file

@ -2,7 +2,6 @@ package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Colors;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
@ -17,9 +16,9 @@ public class Fx{
none = new Effect(0, 0f, e->{}),
place = new Effect(16, e -> {
placeBlock = new Effect(16, e -> {
Lines.stroke(3f - e.fin() * 2f);
Lines.square(e.x, e.y, tilesize / 2f + e.fin() * 3f);
Lines.square(e.x, e.y, tilesize / 2f * (float)(e.data) + e.fin() * 3f);
Draw.reset();
}),

View file

@ -4,10 +4,7 @@ import io.anuke.mindustry.content.*;
import io.anuke.mindustry.content.blocks.*;
import io.anuke.mindustry.entities.StatusEffect;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.resource.Mech;
import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.util.Log;
@ -51,6 +48,9 @@ public class ContentLoader {
//status effects
new StatusEffects(),
//recipes
new Recipes(),
};
for(Block block : Block.getAllBlocks()){
@ -58,9 +58,9 @@ public class ContentLoader {
}
Log.info("--- CONTENT INFO ---");
Log.info("Blocks loaded: {0}\nItems loaded: {1}\nLiquids loaded: {2}\nUpgrades loaded: {3}\nUnits loaded: {4}\nAmmo types loaded: {5}\nStatus effects loaded: {6}\nTotal content classes: {7}",
Log.info("Blocks loaded: {0}\nItems loaded: {1}\nLiquids loaded: {2}\nUpgrades loaded: {3}\nUnits loaded: {4}\nAmmo types loaded: {5}\nStatus effects loaded: {6}\nRecipes loaded: {7}\nTotal content classes: {8}",
Block.getAllBlocks().size, Item.getAllItems().size, Liquid.getAllLiquids().size,
Mech.getAllUpgrades().size, UnitType.getAllTypes().size, AmmoType.getAllTypes().size, StatusEffect.getAllEffects().size, content.length);
Mech.getAllUpgrades().size, UnitType.getAllTypes().size, AmmoType.getAllTypes().size, StatusEffect.getAllEffects().size, Recipe.all().size, content.length);
Log.info("-------------------");
}

View file

@ -163,7 +163,8 @@ public class NetClient extends Module {
Net.handleClient(PlacePacket.class, (packet) -> {
Player placer = playerGroup.getByID(packet.playerid);
Placement.placeBlock(placer, packet.x, packet.y, Recipe.getByID(packet.recipe), packet.rotation, true, Timers.get("placeblocksound", 10));
//todo make it work
// Placement.placeBlock(placer, packet.x, packet.y, Recipe.getByID(packet.recipe), packet.rotation, true, Timers.get("placeblocksound", 10));
for(Player player : players) {
if (packet.playerid == player.id) {

View file

@ -212,7 +212,8 @@ public class NetServer extends Module{
state.inventory.removeItems(recipe.requirements);
Placement.placeBlock(placer, packet.x, packet.y, recipe, packet.rotation, true, false);
//todo implement placing
//Placement.placeBlock(placer, packet.x, packet.y, recipe, packet.rotation, true, false);
TraceInfo trace = admins.getTraceByID(getUUID(id));

View file

@ -12,6 +12,7 @@ import com.badlogic.gdx.utils.FloatArray;
import com.badlogic.gdx.utils.Pools;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.BlockPlacer.PlaceRequest;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.effect.BelowLiquidEffect;
@ -21,16 +22,14 @@ import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Placement;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.EffectEntity;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.function.Callable;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Surface;
import io.anuke.ucore.graphics.*;
import io.anuke.ucore.modules.RendererModule;
import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.Mathf;
@ -74,6 +73,7 @@ public class Renderer extends RendererModule{
entity.color = color;
entity.rotation = rotation;
entity.lifetime = effect.lifetime;
entity.data = data;
entity.set(x, y).add(effectGroup);
if(data instanceof Entity){
@ -85,6 +85,7 @@ public class Renderer extends RendererModule{
entity.color = color;
entity.rotation = rotation;
entity.lifetime = effect.lifetime;
entity.data = data;
entity.set(x, y).add(groundEffectGroup);
}
}
@ -206,11 +207,13 @@ public class Renderer extends RendererModule{
blocks.drawBlocks(Layer.block);
//Graphics.surface(effectSurface, true);
Graphics.shader(Shaders.inline, false);
Graphics.shader(Shaders.blockbuild, false);
blocks.drawBlocks(Layer.placement);
Graphics.shader();
//Graphics.flushSurface();
drawPlaceRequests();
blocks.drawBlocks(Layer.overlay);
drawAllTeams(false);
@ -237,6 +240,22 @@ public class Renderer extends RendererModule{
batch.end();
}
private void drawPlaceRequests(){
Draw.color("accent");
for(Player player : playerGroup.all()) {
for (PlaceRequest request : player.getPlaceQueue()) {
if(Placement.validPlace(player.team, request.x, request.y, request.recipe.result, request.rotation)){
Lines.poly(request.x * tilesize + request.recipe.result.getPlaceOffset().x,
request.y * tilesize + request.recipe.result.getPlaceOffset().y,
4, request.recipe.result.size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f));
}
}
}
Draw.color();
}
private void drawAllTeams(boolean flying){
for(Team team : Team.values()){
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];

View file

@ -1,9 +1,21 @@
package io.anuke.mindustry.entities;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.Recipe;
public interface BlockPlacer {
void addPlaceBlock(Tile tile);
void addPlaceBlock(PlaceRequest place);
Team getTeam();
class PlaceRequest{
public final int x, y, rotation;
public final Recipe recipe;
public PlaceRequest(int x, int y, int rotation, Recipe recipe) {
this.x = x;
this.y = y;
this.rotation = rotation;
this.recipe = recipe;
}
}
}

View file

@ -3,6 +3,7 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Queue;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.Weapons;
@ -13,6 +14,7 @@ import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.world.Placement;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.BuildBlock;
import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity;
@ -39,7 +41,6 @@ public class Player extends Unit implements BlockPlacer{
static final float speed = 1.1f;
static final float dashSpeed = 1.8f;
public static final float placeDistance = 80f;
public static final int maxPlacing = 5;
static final int timerDash = 0;
static final int timerRegen = 3;
@ -64,7 +65,8 @@ public class Player extends Unit implements BlockPlacer{
public float walktime;
public float respawntime;
private Array<Tile> placeBlocks = new Array<>();
private Queue<PlaceRequest> placeQueue = new Queue<>();
private Tile currentPlace;
private Vector2 movement = new Vector2();
public Player(){
@ -110,10 +112,8 @@ public class Player extends Unit implements BlockPlacer{
}
@Override
public void addPlaceBlock(Tile tile){
if(placeBlocks.size < maxPlacing) {
placeBlocks.add(tile);
}
public void addPlaceBlock(PlaceRequest req){
placeQueue.addFirst(req);
}
@Override
@ -228,41 +228,42 @@ public class Player extends Unit implements BlockPlacer{
@Override
public void drawOver(){
if(!isShooting()) {
if(!isShooting() && currentPlace != null) {
Draw.color("accent");
float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f);
float px = x + Angles.trnsx(rotation, focusLen);
float py = y + Angles.trnsy(rotation, focusLen);
for (Tile tile : placeBlocks) {
float sz = Vars.tilesize*tile.block().size/2f;
float ang = angleTo(tile);
Tile tile = currentPlace;
tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz);
tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz);
tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz);
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
float sz = Vars.tilesize*tile.block().size/2f;
float ang = angleTo(tile);
Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(x, y, a.x, a.y), ang),
Angles.angleDist(Angles.angle(x, y, b.x, b.y), ang)));
tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz);
tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz);
tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz);
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
float x1 = tmptr[0].x, y1 = tmptr[0].y,
x3 = tmptr[1].x, y3 = tmptr[1].y;
Translator close = Geometry.findClosest(x, y, tmptr);
float x2 = close.x, y2 = close.y;
Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(x, y, a.x, a.y), ang),
Angles.angleDist(Angles.angle(x, y, b.x, b.y), ang)));
Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
float x1 = tmptr[0].x, y1 = tmptr[0].y,
x3 = tmptr[1].x, y3 = tmptr[1].y;
Translator close = Geometry.findClosest(x, y, tmptr);
float x2 = close.x, y2 = close.y;
Fill.tri(px, py, x2, y2, x1, y1);
Fill.tri(px, py, x2, y2, x3, y3);
Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f));
Draw.alpha(1f);
Fill.tri(px, py, x2, y2, x1, y1);
Fill.tri(px, py, x2, y2, x3, y3);
Lines.line(px, py, x1, y1);
Lines.line(px, py, x3, y3);
Draw.alpha(1f);
Lines.line(px, py, x1, y1);
Lines.line(px, py, x3, y3);
Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f));
Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f));
}
Draw.color();
}
}
@ -315,6 +316,14 @@ public class Player extends Unit implements BlockPlacer{
return control.input(playerIndex).canShoot() && control.input(playerIndex).isShooting() && inventory.hasAmmo();
}
public Iterable<PlaceRequest> getPlaceQueue(){
return placeQueue;
}
private boolean invalidPlaceBlock(Tile check){
return (!(check.block() instanceof BuildBlock) || distanceTo(check) > placeDistance);
}
protected void updateMech(){
Tile tile = world.tileWorld(x, y);
@ -325,14 +334,24 @@ public class Player extends Unit implements BlockPlacer{
}
if(!isShooting()) {
for (Tile check : placeBlocks) {
if (!(check.block() instanceof BuildBlock) || distanceTo(check) > placeDistance) {
placeBlocks.removeValue(check, true);
break;
if(currentPlace != null) {
Tile check = currentPlace;
if (invalidPlaceBlock(currentPlace)) {
currentPlace = null;
}else {
BuildEntity entity = check.entity();
entity.progress += 1f / entity.result.health;
rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f);
}
}else if(placeQueue.size > 0){
PlaceRequest check = placeQueue.removeLast();
if(Placement.validPlace(team, check.x, check.y, check.recipe.result, check.rotation)){
Placement.placeBlock(team, check.x, check.y, check.recipe, check.rotation, true, true);
currentPlace = world.tile(check.x, check.y);
}
BuildEntity entity = check.entity();
entity.progress += 1f / entity.result.health;
rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f);
}
}
@ -353,7 +372,7 @@ public class Player extends Unit implements BlockPlacer{
movement.set(0, 0);
String section = "player_"+(playerIndex + 1);
String section = "player_" + (playerIndex + 1);
float xa = Inputs.getAxis(section, "move_x");
float ya = Inputs.getAxis(section, "move_y");

View file

@ -23,8 +23,15 @@ public class Rubble extends TimedEntity implements BelowLiquidEffect{
@Override
public void draw(){
String region = "rubble-" + size + "-" + Mathf.randomSeed(id, 0, 1);
if(!Draw.hasRegion(region)){
remove();
return;
}
Draw.color(color.r, color.g, color.b, 1f-Mathf.curve(fin(), 0.98f));
Draw.rect("rubble-" + size + "-" + Mathf.randomSeed(id, 0, 1), x, y, Mathf.randomSeed(id, 0, 4) * 90);
Draw.rect(region, x, y, Mathf.randomSeed(id, 0, 4) * 90);
Draw.color();
}

View file

@ -15,7 +15,8 @@ import static io.anuke.mindustry.Vars.world;
public class Shaders{
public static final Outline outline = new Outline();
public static final Inline inline = new Inline();
public static final BlockBuild blockbuild = new BlockBuild();
public static final BlockPreview blockpreview = new BlockPreview();
public static final Shield shield = new Shield();
public static final SurfaceShader water = new SurfaceShader("water");
public static final SurfaceShader lava = new SurfaceShader("lava");
@ -73,12 +74,12 @@ public class Shaders{
}
}
public static class Inline extends Shader{
public static class BlockBuild extends Shader{
public Color color = new Color();
public float progress;
public Inline(){
super("inline-lines", "default");
public BlockBuild(){
super("blockbuild", "default");
}
@Override
@ -88,7 +89,25 @@ public class Shaders{
shader.setUniformf("u_uv", region.getU(), region.getV());
shader.setUniformf("u_uv2", region.getU2(), region.getV2());
shader.setUniformf("u_time", Timers.time());
shader.setUniformf("u_texsize", vec.set(region.getTexture().getWidth(), region.getTexture().getHeight()));
shader.setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight());
}
}
public static class BlockPreview extends Shader{
public Color color = new Color();
public BlockPreview(){
super("blockpreview", "default");
}
@Override
public void apply(){
// shader.setUniformf("u_progress", progress);
shader.setUniformf("u_color", color);
shader.setUniformf("u_uv", region.getU(), region.getV());
shader.setUniformf("u_uv2", region.getU2(), region.getV2());
//shader.setUniformf("u_time", Timers.time());
shader.setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight());
}
}

View file

@ -46,7 +46,7 @@ public class DesktopInput extends InputHandler{
if(player.isDead()) return;
if(Inputs.keyRelease(section, "select")){
if(Inputs.keyRelease(section, "select") && recipe != null){
placeMode.released(this, getBlockX(), getBlockY(), getBlockEndX(), getBlockEndY());
}

View file

@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.entities.BlockPlacer.PlaceRequest;
import io.anuke.mindustry.entities.ItemAnimationEffect;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.net.Net;
@ -201,8 +202,11 @@ public abstract class InputHandler extends InputAdapter{
}
public void placeBlock(int x, int y, Recipe recipe, int rotation, boolean effects, boolean sound){
//todo multiplayer support
player.addPlaceBlock(new PlaceRequest(x, y, rotation, recipe));
/*
if(!Net.client()){ //is server or singleplayer
threads.run(() -> Placement.placeBlock(player, x, y, recipe, rotation, effects, sound));
threads.run(() -> Placement.placeBlock(player.team, x, y, recipe, rotation, effects, sound));
}
if(Net.active()){
@ -213,7 +217,7 @@ public abstract class InputHandler extends InputAdapter{
if(!Net.client()){
//Tile tile = world.tile(x, y);
//if(tile != null) threads.run(() -> result.placed(tile));
}
}*/
}
public void breakBlock(int x, int y, boolean sound){

View file

@ -2,13 +2,18 @@ package io.anuke.mindustry.input;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.ui.fragments.ToolFragment;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Placement;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Mathf;
@ -219,11 +224,10 @@ public enum PlaceMode{
}
},
hold{
int maxlen = 20;
int tilex;
int tiley;
int endx;
int endy;
int rtilex;
int rtiley;
int rendx;
int rendy;
int rotation;
{
@ -243,22 +247,19 @@ public enum PlaceMode{
Vector2 offset = block.getPlaceOffset();
process(input, tilex, tiley, endx, endy);
int tx = tilex, ty = tiley, ex = endx, ey = endy;
tilex = this.tilex; tiley = this.tiley;
endx = this.endx; endy = this.endy;
float x = this.tilex * t, y = this.tiley * t,
x2 = this.endx * t, y2 = this.endy * t;
float x = rtilex * t, y = rtiley * t,
x2 = rendx * t, y2 = rendy * t;
if(x2 >= x){
x -= block.size * t/2;
x2 += block.size * t/2;
}
if(y2 >= y){
y -= block.size * t/2;
y2 += block.size * t/2;
}
x += offset.x;
y += offset.y;
x2 += offset.x;
@ -267,61 +268,47 @@ public enum PlaceMode{
if(tilex == endx && tiley == endy){
cursor.draw(input, tilex, tiley, endx, endy);
}else{
Lines.stroke(2f);
Draw.color(input.cursorNear() ? "place" : "placeInvalid");
Draw.color("place");
Lines.stroke(1f);
Lines.rect(x, y, x2 - x, y2 - y);
Draw.alpha(0.3f);
Draw.crect("blank", x, y, x2 - x, y2 - y);
Fill.crect(x, y, x2 - x, y2 - y);
Draw.alpha(0f);
int amount = 1;
boolean isX = Math.abs(endx - tilex) >= Math.abs(endy - tiley);
Graphics.shader(Shaders.blockpreview, false);
for(int cx = 0; cx <= Math.abs(endx - tilex); cx += (isX ? 0 : 1)){
for(int cy = 0; cy <= Math.abs(endy - tiley); cy += (isX ? 1 : 0)){
for(int py = 0; py <= Math.abs(this.rendy - this.rtiley); py += block.size){
for(int px = 0; px <= Math.abs(this.rendx - this.rtilex); px += block.size){
int px = tx + cx * Mathf.sign(ex - tx),
py = ty + cy * Mathf.sign(ey - ty);
int wx = tilex + px * Mathf.sign(endx - tilex),
wy = tiley + py * Mathf.sign(endy - tiley);
if(!Placement.validPlace(input.player.team, wx, wy, block, rotation)){
Draw.color("placeInvalid");
}else{
Draw.color("accent");
}
//step by the block size if it's valid
if(input.validPlace(px, py, input.recipe.result) && state.inventory.hasItems(input.recipe.requirements, amount)){
drawPreview(block, wx * t + offset.x, wy * t + offset.y);
}
}
if(isX){
cx += block.size;
}else{
cy += block.size;
}
amount ++;
}else{ //otherwise, step by 1 until it is valid
if(input.cursorNear()){
Lines.stroke(2f);
Draw.color("placeInvalid");
Lines.crect(
px * t + (isX ? 0 : offset.x) + (ex < tx && isX && block.size > 1 ? t : 0) - (block.size == 3 && ex > tx && isX ? t : 0),
py * t + (isX ? offset.y : 0) + (ey < ty && !isX && block.size > 1 ? t : 0) - (block.size == 3 && ey > ty && !isX ? t : 0),
t*(isX ? 1 : block.size),
t*(isX ? block.size : 1));
Draw.color("place");
}
if(isX){
cx += 1;
}else{
cy += 1;
}
}
}
}
if(input.recipe.result.rotate){
float cx = tx * t, cy = ty * t;
Lines.stroke(2f);
Draw.color(Colors.get("placeRotate"));
tr.trns(rotation * 90, 7, 0);
Lines.line(cx, cy, cx + tr.x, cy + tr.y);
}
Graphics.shader();
Draw.reset();
}
}
public void drawPreview(Block block, float x, float y){
for(TextureRegion region : block.getBlockIcon()){
Shaders.blockpreview.region = region;
Shaders.blockpreview.color.set(Colors.get("accent"));
Shaders.blockpreview.apply();
Draw.rect(region, x, y);
Graphics.flush();
}
//Lines.crect(x, y, block.size * tilesize, block.size * tilesize);
}
public void released(InputHandler input, int tilex, int tiley, int endx, int endy){
process(input, tilex, tiley, endx, endy);
@ -329,8 +316,8 @@ public enum PlaceMode{
input.rotation = this.rotation;
boolean first = true;
for(int x = 0; x <= Math.abs(this.endx - this.tilex); x ++){
for(int y = 0; y <= Math.abs(this.endy - this.tiley); y ++){
for(int x = 0; x <= Math.abs(this.rendx - this.rtilex); x += input.recipe.result.size){
for(int y = 0; y <= Math.abs(this.rendy - this.rtiley); y += input.recipe.result.size){
if(input.tryPlaceBlock(
tilex + x * Mathf.sign(endx - tilex),
tiley + y * Mathf.sign(endy - tiley), first)){
@ -342,19 +329,20 @@ public enum PlaceMode{
}
void process(InputHandler input, int tilex, int tiley, int endx, int endy){
/*
if(Math.abs(tilex - endx) > Math.abs(tiley - endy)){
endy = tiley;
}else{
endx = tilex;
}
if(Math.abs(endx - tilex) > maxlen){
endx = Mathf.sign(endx - tilex) * maxlen + tilex;
}
if(Math.abs(endy - tiley) > maxlen){
endy = Mathf.sign(endy - tiley) * maxlen + tiley;
}
}*/
if(endx > tilex)
rotation = 0;
@ -378,10 +366,10 @@ public enum PlaceMode{
tiley = t;
}
this.endx = endx;
this.endy = endy;
this.tilex = tilex;
this.tiley = tiley;
this.rendx = endx;
this.rendy = endy;
this.rtilex = tilex;
this.rtiley = tiley;
}
};
public boolean lockCamera;

View file

@ -2,11 +2,8 @@ package io.anuke.mindustry.resource;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Block;
import static io.anuke.mindustry.Vars.debug;
public class Recipe {
private static int lastid;
private static Array<Recipe> allRecipes = new Array<>();
@ -41,7 +38,7 @@ public class Recipe {
public static Array<Recipe> getBySection(Section section, Array<Recipe> r){
for(Recipe recipe : allRecipes){
if(recipe.section == section && !(Vars.mobile && recipe.desktopOnly) && !(!debug && recipe.debugOnly)) {
if(recipe.section == section ) {
r.add(recipe);
}
}

View file

@ -40,6 +40,10 @@ public class Block extends BaseBlock {
protected Vector2 tempVector = new Vector2();
protected Color tempColor = new Color();
protected TextureRegion[] blockIcon;
protected TextureRegion[] icon;
protected TextureRegion[] compactIcon;
/**internal name*/
public final String name;
/**internal ID*/
@ -295,13 +299,17 @@ public class Block extends BaseBlock {
}
public TextureRegion[] getIcon(){
if(Draw.hasRegion(name + "-icon")){
return new TextureRegion[]{Draw.region(name + "-icon")};
}else if(Draw.hasRegion(name + "1")){
return new TextureRegion[]{Draw.region(name+ "1")};
}else{
return new TextureRegion[]{Draw.region(name)};
}
if(icon == null) {
if (Draw.hasRegion(name + "-icon")) {
icon = new TextureRegion[]{Draw.region(name + "-icon")};
} else if (Draw.hasRegion(name + "1")) {
icon = new TextureRegion[]{Draw.region(name + "1")};
} else {
icon = new TextureRegion[]{Draw.region(name)};
}
}
return icon;
}
public TextureRegion[] getBlockIcon(){
@ -309,11 +317,13 @@ public class Block extends BaseBlock {
}
public TextureRegion[] getCompactIcon(){
TextureRegion[] out = getIcon();
for(int i = 0; i < out.length; i ++){
out[i] = iconRegion(out[i]);
}
return out;
if(compactIcon == null) {
compactIcon = new TextureRegion[getIcon().length];
for (int i = 0; i < compactIcon.length; i++) {
compactIcon[i] = iconRegion(getIcon()[i]);
}
}
return compactIcon;
}
protected TextureRegion iconRegion(TextureRegion src){

View file

@ -5,7 +5,6 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.BlockPlacer;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.ItemStack;
@ -57,9 +56,8 @@ public class Placement {
return block;
}
public static void placeBlock(BlockPlacer placer, int x, int y, Recipe recipe, int rotation, boolean effects, boolean sound){
public static void placeBlock(Team team, int x, int y, Recipe recipe, int rotation, boolean effects, boolean sound){
Tile tile = world.tile(x, y);
Team team = placer.getTeam();
Block result = recipe.result;
//just in case
@ -87,14 +85,12 @@ public class Placement {
}
}
if(effects) Effects.effect(Fx.place, worldx * tilesize, worldy * tilesize);
if(effects) Effects.effect(Fx.none, worldx * tilesize, worldy * tilesize);
}
}
}else if(effects) Effects.effect(Fx.place, x * tilesize, y * tilesize);
}else if(effects) Effects.effect(Fx.none, x * tilesize, y * tilesize);
if(effects && sound) threads.run(() -> Effects.sound("place", x * tilesize, y * tilesize));
placer.addPlaceBlock(tile);
}
public static boolean validPlace(Team team, int x, int y, Block type, int rotation){

View file

@ -3,6 +3,7 @@ package io.anuke.mindustry.world.blocks.types;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.effect.Rubble;
import io.anuke.mindustry.game.Team;
@ -52,13 +53,15 @@ public class BuildBlock extends Block {
public void drawLayer(Tile tile) {
BuildEntity entity = tile.entity();
Shaders.inline.color = Colors.get("accent");
Shaders.blockbuild.color = Colors.get("accent");
for(TextureRegion region : entity.result.getBlockIcon()){
Shaders.inline.region = region;
Shaders.inline.progress = entity.progress;
Shaders.inline.apply();
Draw.rect(region, tile.drawx(), tile.drawy());
Shaders.blockbuild.region = region;
Shaders.blockbuild.progress = entity.progress;
Shaders.blockbuild.apply();
Draw.rect(region, tile.drawx(), tile.drawy(), entity.result.rotate ? tile.getRotation() * 90 : 0);
Graphics.flush();
}
}
@ -78,6 +81,7 @@ public class BuildBlock extends Block {
Team team = tile.getTeam();
tile.setBlock(entity.result);
tile.setTeam(team);
Effects.effect(Fx.placeBlock, tile.drawx(), tile.drawy(), 0f, (float)size);
}else if(entity.progress < 0f){
entity.damage(entity.health + 1);
}

View file

@ -118,7 +118,10 @@ public abstract class Turret extends Block{
@Override
public TextureRegion[] getBlockIcon(){
return new TextureRegion[]{Draw.region("block-" + size), Draw.region(name)};
if(blockIcon == null){
blockIcon = new TextureRegion[]{Draw.region("block-" + size), Draw.region(name)};
}
return blockIcon;
}
@Override