mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-09 23:37:51 +07:00
Implemented editor multiblock support
This commit is contained in:
BIN
core/assets-raw/sprites/effects/clear.png
Normal file
BIN
core/assets-raw/sprites/effects/clear.png
Normal file
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.
@ -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 |
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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];
|
||||
|
||||
|
Reference in New Issue
Block a user