Schematic flipping + rotation

This commit is contained in:
Anuken
2019-10-18 14:38:43 -04:00
parent f7d98591c9
commit 6a12effd6a
7 changed files with 114 additions and 49 deletions

View File

@@ -33,6 +33,8 @@ public class Vars implements Loadable{
public static boolean loadLocales = true;
/** Maximum number of broken blocks. TODO implement or remove.*/
public static final int maxBrokenBlocks = 256;
/** Maximum schematic size.*/
public static final int maxSchematicSize = 32;
/** IO buffer size. */
public static final int bufferSize = 8192;
/** global charset, since Android doesn't support the Charsets class */

View File

@@ -278,7 +278,7 @@ public interface BuilderTrait extends Entity, TeamTrait{
/** Config int. Not used unless hasConfig is true.*/
public int config;
/** Original position, only used in schematics.*/
public int originalX, originalY;
public int originalX, originalY, originalWidth, originalHeight;
/** Last progress.*/
public float progress;
@@ -327,9 +327,11 @@ public interface BuilderTrait extends Entity, TeamTrait{
return copy;
}
public BuildRequest original(int x, int y){
public BuildRequest original(int x, int y, int originalWidth, int originalHeight){
originalX = x;
originalY = y;
this.originalWidth = originalWidth;
this.originalHeight = originalHeight;
return this;
}

View File

@@ -15,6 +15,8 @@ import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.traits.BuilderTrait.*;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.Schematic.*;
import io.anuke.mindustry.input.*;
import io.anuke.mindustry.input.PlaceUtils.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.*;
@@ -29,7 +31,6 @@ public class Schematics implements Loadable{
private static final byte version = 0;
private static final int padding = 2;
private static final int maxSize = 64;
private OptimizedByteArrayOutputStream out = new OptimizedByteArrayOutputStream(1024);
private Array<Schematic> all = new Array<>();
@@ -63,7 +64,7 @@ public class Schematics implements Loadable{
}
Core.app.post(() -> {
shadowBuffer = new FrameBuffer(maxSize + padding, maxSize + padding);
shadowBuffer = new FrameBuffer(maxSchematicSize + padding, maxSchematicSize + padding);
});
}
@@ -145,7 +146,7 @@ public class Schematics implements Loadable{
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
public Array<BuildRequest> toRequests(Schematic schem, int x, int y){
return schem.tiles.map(t -> new BuildRequest(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block).original(t.x, t.y).configure(t.config));
return schem.tiles.map(t -> new BuildRequest(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block).original(t.x, t.y, schem.width, schem.height).configure(t.config));
}
/** Adds a schematic to the list, also copying it into the files.*/
@@ -160,17 +161,11 @@ public class Schematics implements Loadable{
/** Creates a schematic from a world selection. */
public Schematic create(int x, int y, int x2, int y2){
if(x > x2){
int temp = x;
x = x2;
x2 = temp;
}
if(y > y2){
int temp = y;
y = y2;
y2 = temp;
}
NormalizeResult result = PlaceUtils.normalizeArea(x, y, x2, y2, 0, false, maxSchematicSize);
x = result.x;
y = result.y;
x2 = result.x2;
y2 = result.y2;
Array<Stile> tiles = new Array<>();

View File

@@ -10,6 +10,7 @@ import io.anuke.arc.scene.*;
import io.anuke.arc.scene.event.*;
import io.anuke.arc.scene.ui.*;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.*;
import io.anuke.mindustry.core.GameState.*;
import io.anuke.mindustry.entities.traits.BuilderTrait.*;
import io.anuke.mindustry.game.EventType.*;
@@ -91,7 +92,7 @@ public class DesktopInput extends InputHandler{
drawRequest(lineRequests.get(i));
}
}else if(mode == breaking){
drawSelection(selectX, selectY, cursorX, cursorY);
drawBreakSelection(selectX, selectY, cursorX, cursorY);
}else if(isPlacing()){
if(block.rotate){
drawArrow(block, cursorX, cursorY, rotation);
@@ -126,10 +127,7 @@ public class DesktopInput extends InputHandler{
}
if(Core.input.keyDown(Binding.schematic)){
Lines.stroke(2f);
Draw.color(Pal.accent);
Lines.rect(schemX * tilesize, schemY * tilesize, (cursorX - schemX) * tilesize, (cursorY - schemY) * tilesize);
drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize);
}
Draw.reset();
@@ -156,7 +154,7 @@ public class DesktopInput extends InputHandler{
if(state.is(State.menu) || Core.scene.hasDialog()) return;
//zoom things
if(Math.abs(Core.input.axisTap(Binding.zoom)) > 0 && (Core.input.keyDown(Binding.zoom_hold))){
if(Math.abs(Core.input.axisTap(Binding.zoom)) > 0 && Core.input.keyDown(Binding.zoom_hold)){
renderer.scaleCamera(Core.input.axisTap(Binding.zoom));
}
@@ -193,10 +191,12 @@ public class DesktopInput extends InputHandler{
sreq.rotation = Mathf.mod(sreq.rotation + (int)Core.input.axisTap(Binding.rotate), 4);
}
if(Math.abs((int)Core.input.axisTap(Binding.rotate)) > 0 && isPlacing() && mode == placing){
updateLine(selectX, selectY);
}else if(Math.abs((int)Core.input.axisTap(Binding.rotate)) > 0 && !selectRequests.isEmpty()){
rotateRequests(selectRequests, (int)Core.input.axisTap(Binding.rotate));
if(!Core.input.keyDown(Binding.zoom_hold) && Math.abs((int)Core.input.axisTap(Binding.rotate)) > 0){
if(isPlacing() && mode == placing){
updateLine(selectX, selectY);
}else if(!selectRequests.isEmpty()){
rotateRequests(selectRequests, (int)Core.input.axisTap(Binding.rotate));
}
}
Tile cursor = tileAt(Core.input.mouseX(), Core.input.mouseY());
@@ -288,6 +288,16 @@ public class DesktopInput extends InputHandler{
}
}
if(!selectRequests.isEmpty()){
if(Core.input.keyTap(Binding.schematic_flip_x)){
flipRequests(selectRequests, true);
}
if(Core.input.keyTap(Binding.schematic_flip_y)){
flipRequests(selectRequests, false);
}
}
//TODO remove
if(Core.input.keyTap(KeyCode.V)){
ui.schematics.show();

View File

@@ -227,11 +227,25 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
public void rotateRequests(Array<BuildRequest> requests, int direction){
int ox = tileX(getMouseX()), oy = tileY(getMouseY());
int ox = rawTileX(), oy = rawTileY();
requests.each(req -> {
//req.x -= ox;
//req.y -= oy;
//rotate config position
if(req.block.posConfig){
int cx = Pos.x(req.config) - req.originalX, cy = Pos.y(req.config) - req.originalY;
int lx = cx;
if(direction >= 0){
cx = -cy;
cy = lx;
}else{
cx = cy;
cy = -lx;
}
req.config = Pos.get(cx + req.originalX, cy + req.originalY);
}
//rotate actual request, centered on its multiblock position
float wx = (req.x - ox) * tilesize + req.block.offset(), wy = (req.y - oy) * tilesize + req.block.offset();
float x = wx;
if(direction >= 0){
@@ -243,7 +257,38 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
req.x = world.toTile(wx - req.block.offset()) + ox;
req.y = world.toTile(wy - req.block.offset()) + oy;
req.rotation += direction;
req.rotation = Mathf.mod(req.rotation + direction, 4);
});
}
public void flipRequests(Array<BuildRequest> requests, boolean x){
int origin = x ? rawTileX() : rawTileY();
requests.each(req -> {
int value = -((x ? req.x : req.y) - origin) + origin;
if(x){
req.x = value;
}else{
req.y = value;
}
if(req.block.posConfig){
int corigin = x ? req.originalWidth/2 : req.originalHeight/2;
int nvalue = -((x ? Pos.x(req.config) : Pos.y(req.config)) - corigin) + corigin;
if(x){
req.originalX = -(req.originalX - corigin) + corigin;
req.config = Pos.get(nvalue, Pos.y(req.config));
}else{
req.originalY = -(req.originalY - corigin) + corigin;
req.config = Pos.get(Pos.x(req.config), nvalue);
}
}
//flip rotation
if(x == (req.rotation % 2 == 0)){
req.rotation = Mathf.mod(req.rotation + 2, 4);
}
});
}
@@ -287,7 +332,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
return null;
}
protected void drawSelection(int x1, int y1, int x2, int y2){
protected void drawBreakSelection(int x1, int y1, int x2, int y2){
NormalizeDrawResult result = PlaceUtils.normalizeDrawArea(Blocks.air, x1, y1, x2, y2, false, maxLength, 1f);
NormalizeResult dresult = PlaceUtils.normalizeArea(x1, y1, x2, y2, rotation, false, maxLength);
@@ -335,6 +380,17 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
}
protected void drawSelection(int x1, int y1, int x2, int y2, int maxLength){
NormalizeDrawResult result = PlaceUtils.normalizeDrawArea(Blocks.air, x1, y1, x2, y2, false, maxLength, 1f);
Lines.stroke(2f);
Draw.color(Pal.accentBack);
Lines.rect(result.x, result.y - 1, result.x2 - result.x, result.y2 - result.y);
Draw.color(Pal.accent);
Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
}
protected void flushSelectRequests(Array<BuildRequest> requests){
for(BuildRequest req : requests){
if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){
@@ -480,14 +536,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
}
/*
//clear when the player taps on something else
if(!consumed && !mobile && player.isBuilding() && block == null){
//player.clearBuilding();
block = null;
return true;
}*/
if(!showedInventory){
frag.inv.hide();
}
@@ -531,6 +579,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
return world.tile(tileX(x), tileY(y));
}
int rawTileX(){
return world.toTile(Core.input.mouseWorld().x);
}
int rawTileY(){
return world.toTile(Core.input.mouseWorld().y);
}
int tileX(float cursorX){
Vector2 vec = Core.input.mouseWorld(cursorX, 0);
if(selectedBlock()){

View File

@@ -302,7 +302,7 @@ public class MobileInput extends InputHandler implements GestureListener{
drawRequest(lineRequests.get(i));
}
}else if(mode == breaking){
drawSelection(lineStartX, lineStartY, tileX, tileY);
drawBreakSelection(lineStartX, lineStartY, tileX, tileY);
}
}

View File

@@ -95,14 +95,14 @@ public class PlaceUtils{
}else{
endx = tilex;
}
}
if(Math.abs(endx - tilex) > maxLength){
endx = Mathf.sign(endx - tilex) * maxLength + tilex;
}
if(Math.abs(endx - tilex) > maxLength){
endx = Mathf.sign(endx - tilex) * maxLength + tilex;
}
if(Math.abs(endy - tiley) > maxLength){
endy = Mathf.sign(endy - tiley) * maxLength + tiley;
}
if(Math.abs(endy - tiley) > maxLength){
endy = Mathf.sign(endy - tiley) * maxLength + tiley;
}
int dx = endx - tilex, dy = endy - tiley;
@@ -141,12 +141,12 @@ public class PlaceUtils{
return result;
}
static class NormalizeDrawResult{
public static class NormalizeDrawResult{
float x, y, x2, y2;
}
static class NormalizeResult{
int x, y, x2, y2, rotation;
public static class NormalizeResult{
public int x, y, x2, y2, rotation;
boolean isX(){
return Math.abs(x2 - x) > Math.abs(y2 - y);