Implemented editor multiblock support

This commit is contained in:
Anuken
2018-05-21 17:45:12 -04:00
parent 5602cb8920
commit f6184004e5
15 changed files with 154 additions and 55 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2223,6 +2223,13 @@ casing
orig: 2, 4
offset: 0, 0
index: -1
clear
rotate: false
xy: 769, 490
size: 1, 1
orig: 1, 1
offset: 0, 0
index: -1
enemyarrow
rotate: false
xy: 707, 310
@ -3249,7 +3256,7 @@ scroll-knob-vertical-black
index: -1
selection
rotate: false
xy: 769, 490
xy: 566, 287
size: 1, 1
orig: 1, 1
offset: 0, 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View File

@ -81,10 +81,6 @@ public enum EditorTool{
int asInt(int x, int y, int width){
return x+y*width;
}
boolean colorEquals(int a, int b){
return a == b;
}
},
zoom;
boolean edit;

View File

@ -1,11 +1,12 @@
package io.anuke.mindustry.editor;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.io.MapTileData;
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.util.Bits;
import io.anuke.ucore.util.Mathf;
public class MapEditor{
@ -58,12 +59,12 @@ public class MapEditor{
return brushSize;
}
public void draw(int dx, int dy){
if(dx < 0 || dy < 0 || dx >= map.width() || dy >= map.height()){
public void draw(int x, int y){
if(x < 0 || y < 0 || x >= map.width() || y >= map.height()){
return;
}
TileDataMarker writer = map.readAt(dx, dy);
TileDataMarker writer = map.readAt(x, y);
if(drawBlock instanceof Floor){
writer.floor = (byte)drawBlock.id;
}else{
@ -74,18 +75,89 @@ public class MapEditor{
writer.team = (byte)drawTeam.ordinal();
}
for(int rx = -brushSize; rx <= brushSize; rx ++){
for(int ry = -brushSize; ry <= brushSize; ry ++){
if(Mathf.dst(rx, ry) <= brushSize - 0.5f){
if(dx + rx < 0 || dy + ry < 0 || dx + rx >= map.width() || dy + ry >= map.height()){
continue;
if(drawBlock.isMultiblock()){
int offsetx = -(drawBlock.size-1)/2;
int offsety = -(drawBlock.size-1)/2;
for(int dx = 0; dx < drawBlock.size; dx ++){
for(int dy = 0; dy < drawBlock.size; dy ++){
int worldx = dx + offsetx + x;
int worldy = dy + offsety + y;
if(!(worldx == x && worldy == y)){
if(Mathf.inBounds(worldx, worldy, map.width(), map.height())){
map.readAt(worldx, worldy);
byte floor = writer.floor;
if(writer.link != 0){
removeLinked(worldx - (Bits.getLeftByte(writer.link) - 8), worldy - (Bits.getRightByte(writer.link) - 8));
}
writer.wall = (byte)Blocks.blockpart.id;
writer.team = (byte)drawTeam.ordinal();
writer.floor = floor;
writer.link = Bits.packByte((byte) (dx + offsetx + 8), (byte) (dy + offsety + 8));
map.write(worldx, worldy, writer);
renderer.updatePoint(worldx, worldy);
}
}
}
}
map.readAt(x, y);
if(drawBlock instanceof Floor){
writer.floor = (byte)drawBlock.id;
}else{
writer.wall = (byte)drawBlock.id;
}
writer.team = (byte)drawTeam.ordinal();
writer.rotation = 0;
writer.link = 0;
map.write(x, y, writer);
renderer.updatePoint(x, y);
}else{
for (int rx = -brushSize; rx <= brushSize; rx++) {
for (int ry = -brushSize; ry <= brushSize; ry++) {
if (Mathf.dst(rx, ry) <= brushSize - 0.5f) {
if (x + rx < 0 || y + ry < 0 || x + rx >= map.width() || y + ry >= map.height()) {
continue;
}
map.write(x + rx, y + ry, writer);
renderer.updatePoint(x + rx, y + ry);
}
map.write(dx + rx, dy + ry, writer);
renderer.updatePoint(dx + rx, dy + ry);
}
}
}
}
private void removeLinked(int x, int y){
TileDataMarker marker = map.readAt(x, y);
Block block = Block.getByID(marker.wall);
int offsetx = -(block.size-1)/2;
int offsety = -(block.size-1)/2;
for(int dx = 0; dx < block.size; dx ++){
for(int dy = 0; dy < block.size; dy ++){
int worldx = x + dx + offsetx, worldy = y + dy + offsety;
if(Mathf.inBounds(worldx, worldy, map.width(), map.height())){
map.readAt(worldx, worldy);
marker.link = 0;
marker.wall = 0;
marker.rotation = 0;
marker.team = 0;
map.write(worldx, worldy, marker);
if(worldx == x && worldy == y){
renderer.updatePoint(worldx, worldy);
}
}
}
}
}
public MapRenderer renderer() {

View File

@ -3,7 +3,6 @@ package io.anuke.mindustry.editor;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.IntSet.IntSetIterator;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.core.Core;
@ -93,20 +92,20 @@ public class MapRenderer {
Block floor = Block.getByID(data.floor);
Block wall = Block.getByID(data.wall);
String fregion = Draw.hasRegion(floor.name) ? floor.name : floor.name + "1";
int offsetx = -(wall.size-1)/2;
int offsety = -(wall.size-1)/2;
if (floor != Blocks.air && Draw.hasRegion(fregion)) {
TextureRegion region = Draw.region(fregion);
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, -1f, 8, 8);
}
String fregion = Draw.hasRegion(floor.name) ? floor.name : (Draw.hasRegion(floor.name + "1") ? (floor.name + "1") : "clear");
String wregion = Draw.hasRegion(wall.name) ? wall.name : wall.name + "1";
TextureRegion region = Draw.region(fregion);
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, -1f, 8, 8);
String wregion = Draw.hasRegion(wall.name) ? wall.name : (Draw.hasRegion(wall.name + "1") ? (wall.name + "1") : "clear");
region = Draw.region(wregion);
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region,
wx * tilesize + offsetx*tilesize, wy * tilesize + offsety * tilesize, 0f,
region.getRegionWidth(), region.getRegionHeight());
if (wall != Blocks.air && Draw.hasRegion(wregion)) {
TextureRegion region = Draw.region(wregion);
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region,
wx * tilesize - Math.max(region.getRegionWidth()-16f, 0), wy * tilesize - Math.max(region.getRegionHeight()-16f, 0), 0f,
region.getRegionWidth(), region.getRegionHeight());
}
}
}

View File

@ -198,7 +198,12 @@ public class MapView extends Element implements GestureListener{
float sclheight = size * zoom * ratio;
x = (x - getWidth()/2 + sclwidth/2 - offsetx*zoom) / sclwidth * editor.getMap().width();
y = (y - getHeight()/2 + sclheight/2 - offsety*zoom) / sclheight * editor.getMap().height();
return Tmp.g1.set((int)x, (int)y);
if(editor.getDrawBlock().size % 2 == 0){
return Tmp.g1.set((int)(x - 0.5f), (int)(y - 0.5f));
}else{
return Tmp.g1.set((int)x, (int)y);
}
}
private Vector2 unproject(int x, int y){
@ -250,25 +255,36 @@ public class MapView extends Element implements GestureListener{
//todo is it really math.max?
float scaling = zoom * Math.min(width, height) / Math.max(editor.getMap().width(), editor.getMap().height());
if(tool == EditorTool.line && drawing){
Vector2 v1 = unproject(startx, starty).add(x, y);
float sx = v1.x, sy = v1.y;
Vector2 v2 = unproject(lastx, lasty).add(x, y);
Draw.color(Palette.accent);
Lines.stroke(Unit.dp.scl(1f * zoom));
Draw.color(Palette.accent);
Lines.stroke(Unit.dp.scl(1f * zoom));
Lines.poly(brushPolygons[index], sx, sy, scaling);
Lines.poly(brushPolygons[index], v2.x, v2.y, scaling);
if(!editor.getDrawBlock().isMultiblock()) {
if (tool == EditorTool.line && drawing) {
Vector2 v1 = unproject(startx, starty).add(x, y);
float sx = v1.x, sy = v1.y;
Vector2 v2 = unproject(lastx, lasty).add(x, y);
Lines.poly(brushPolygons[index], sx, sy, scaling);
Lines.poly(brushPolygons[index], v2.x, v2.y, scaling);
}
if (tool.edit && (!mobile || drawing)) {
GridPoint2 p = project(mousex, mousey);
Vector2 v = unproject(p.x, p.y).add(x, y);
Lines.poly(brushPolygons[index], v.x, v.y, scaling);
}
}else{
if((tool.edit || tool == EditorTool.line) && (!mobile || drawing)){
GridPoint2 p = project(mousex, mousey);
Vector2 v = unproject(p.x, p.y).add(x, y);
float offset = (editor.getDrawBlock().size % 2 == 0 ? scaling/2f : 0f);
Lines.square(
v.x + scaling/2f + offset,
v.y + scaling/2f + offset,
scaling * editor.getDrawBlock().size /2f);
}
}
if(tool.edit && (!mobile || drawing)){
GridPoint2 p = project(mousex, mousey);
Vector2 v = unproject(p.x, p.y).add(x, y);
Draw.color(Palette.accent);
Lines.stroke(Unit.dp.scl(1f * zoom));
Lines.poly(brushPolygons[index], v.x, v.y, scaling);
}
batch.flush();
if(pop) ScissorStack.popScissors();

View File

@ -6,11 +6,12 @@ import io.anuke.ucore.util.Bits;
import java.nio.ByteBuffer;
public class MapTileData {
/**Tile size: 3 bytes.
* 0: ground tile
* 1: wall tile
* 2: rotation + team*/
private final static int TILE_SIZE = 3;
/**Tile size: 3 bytes. <br>
* 0: ground tile <br>
* 1: wall tile <br>
* 2: rotation + team <br>
* 3: link (x/y) <br>*/
private final static int TILE_SIZE = 4;
private final ByteBuffer buffer;
private final TileDataMarker tile = new TileDataMarker();
@ -92,12 +93,14 @@ public class MapTileData {
public class TileDataMarker {
public byte floor, wall;
public byte link;
public byte rotation;
public byte team;
public void read(ByteBuffer buffer){
floor = buffer.get();
wall = buffer.get();
link = buffer.get();
byte rt = buffer.get();
rotation = Bits.getLeftByte(rt);
team = Bits.getRightByte(rt);
@ -112,8 +115,14 @@ public class MapTileData {
if(readOnly) throw new IllegalArgumentException("This data is read-only.");
buffer.put(floor);
buffer.put(wall);
byte rt = Bits.packByte(rotation, team);
buffer.put(rt);
buffer.put(link);
buffer.put(Bits.packByte(rotation, team));
}
public void writeWallLink(){
buffer.position(buffer.position() + 1);
buffer.put(wall);
buffer.put(link);
}
}
}

View File

@ -17,7 +17,7 @@ import static io.anuke.mindustry.Vars.mapExtension;
public class Maps implements Disposable{
/**List of all built-in maps.*/
private static final String[] defaultMapNames = {"test", "trinity", "routerhell", "conveyorhell", "pathfind"};
private static final String[] defaultMapNames = {"test"};
/**Tile format version.*/
private static final int version = 0;

View File

@ -30,7 +30,7 @@ public class WorldGenerator {
for(int y = 0; y < data.height(); y ++){
for(int x = 0; x < data.width(); x ++){
TileDataMarker tile = data.read();
tiles[x][y] = new Tile(x, y, tile.floor, tile.wall, tile.rotation, tile.team);
tiles[x][y] = new Tile(x, y, tile.floor, tile.wall == Blocks.blockpart.id ? 0 : tile.wall, tile.rotation, tile.team);
Team team = Team.values()[tile.team];