mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-04-22 05:21:18 -07:00
New placement system without limits, queue block placements
This commit is contained in:
parent
97cac33773
commit
19e62786c9
20 changed files with 283 additions and 164 deletions
|
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
|
|
@ -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;
|
||||
40
core/assets/shaders/blockpreview.fragment
Normal file
40
core/assets/shaders/blockpreview.fragment
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}),
|
||||
|
||||
|
|
|
|||
|
|
@ -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("-------------------");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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()];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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){
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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){
|
||||
|
|
|
|||
|
|
@ -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){
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue