Support for schematic random rotation
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
mschxœ-ŒÑ
|
||||||
|
à E¯U»BÊ>ć}’³aZ‹Õ�ýý’v ¹9¹$Á„›‚Ù|&¨Çˆ{(ûNÕ}|J.ùú"èµÌ±QvGé5–}£ž}‹Á5¦„y�G«ñÙ[©˜BÙÞôe."ê’�SIÓPÂÆŠ¯™þÀaΙ␍-hY¸ Ÿ+özdå‡:—øh”ƒA›M
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
mschxœ%‹Ñ
|
||||||
|
à E¯Z»BÊ>Ä—ý‘³2[‹Õ•ýýr)!9 çL
|
||||||
|
Ãî·õñå8bu—ÏÙe_?fíóšÎVÓ»·R1…²ãO¶9µ¸¹³ô"–c�}ó-·Ö”3€E
|
||||||
|
†07,¡y+�‡aJ‹ÝHgèË×�71@sXF�©oHàIc
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
mschxś%LŃ
|
||||||
|
Ă <›*…AÇ>ħ}‘kC+ŘV˘˛ßźYIrwÜ%Á„É`<ĂÁ0o‡×rĺĚâż!%ź‚lŚq1á+ľ\MĆ3źÜŽPăâW‰©§k,Uâ§ŐK0oňŢ÷}.ŔÜ�‚ąače”Fµµ€%ęĘuKAwB*ţ™˝?X=V"5ť~˙[ë
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
mschxś%LŃ
|
||||||
|
Ă <›*…AÇ>Ä·ý�kC+ŘV˘˛ßźYIrwÜ%Á„É`<ĂÁ0o‡×rĺĚâż!%ź‚lŚq1á+ľ\MĆ3źÜŽPăâW‰©§k,Uâ§ŐK0oňŢ÷}.ŔÜ�‚ąače”Fµµ€%ęĘuKAwB*ţ™˝?X=V"5ť~˙[Öě
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -8,12 +8,15 @@ import mindustry.game.*;
|
|||||||
import mindustry.game.Schematic.*;
|
import mindustry.game.Schematic.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.production.*;
|
||||||
import mindustry.world.blocks.sandbox.*;
|
import mindustry.world.blocks.sandbox.*;
|
||||||
import mindustry.world.blocks.storage.*;
|
import mindustry.world.blocks.storage.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class BaseRegistry{
|
public class BaseRegistry{
|
||||||
public Array<BasePart> cores = new Array<>();
|
public Array<BasePart> cores = new Array<>();
|
||||||
public Array<BasePart> parts = new Array<>();
|
public Array<BasePart> parts = new Array<>();
|
||||||
@@ -35,6 +38,8 @@ public class BaseRegistry{
|
|||||||
Schematic schem = Schematics.read(Core.files.internal("baseparts/" + name));
|
Schematic schem = Schematics.read(Core.files.internal("baseparts/" + name));
|
||||||
|
|
||||||
BasePart part = new BasePart(schem);
|
BasePart part = new BasePart(schem);
|
||||||
|
Tmp.v1.setZero();
|
||||||
|
int drills = 0;
|
||||||
|
|
||||||
for(Stile tile : schem.tiles){
|
for(Stile tile : schem.tiles){
|
||||||
//make note of occupied positions
|
//make note of occupied positions
|
||||||
@@ -56,6 +61,12 @@ public class BaseRegistry{
|
|||||||
Liquid config = (Liquid)tile.config;
|
Liquid config = (Liquid)tile.config;
|
||||||
if(config != null) part.requiredLiquid = config;
|
if(config != null) part.requiredLiquid = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//calculate averages
|
||||||
|
if(tile.block instanceof Drill){
|
||||||
|
Tmp.v1.add(tile.x*tilesize + tile.block.offset(), tile.y*tilesize + tile.block.offset());
|
||||||
|
drills ++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
schem.tiles.removeAll(s -> s.block.buildVisibility == BuildVisibility.sandboxOnly);
|
schem.tiles.removeAll(s -> s.block.buildVisibility == BuildVisibility.sandboxOnly);
|
||||||
|
|
||||||
@@ -63,6 +74,15 @@ public class BaseRegistry{
|
|||||||
|
|
||||||
(part.core != null ? cores : parts).add(part);
|
(part.core != null ? cores : parts).add(part);
|
||||||
|
|
||||||
|
if(drills > 0){
|
||||||
|
Tmp.v1.scl(1f / drills).scl(1f / tilesize);
|
||||||
|
part.centerX = (int)Tmp.v1.x;
|
||||||
|
part.centerY = (int)Tmp.v1.y;
|
||||||
|
}else{
|
||||||
|
part.centerX = part.schematic.width/2;
|
||||||
|
part.centerY = part.schematic.height/2;
|
||||||
|
}
|
||||||
|
|
||||||
if(part.requiredItem != null){
|
if(part.requiredItem != null){
|
||||||
itemParts.get(part.requiredItem, Array::new).add(part);
|
itemParts.get(part.requiredItem, Array::new).add(part);
|
||||||
}
|
}
|
||||||
@@ -80,6 +100,9 @@ public class BaseRegistry{
|
|||||||
public final Schematic schematic;
|
public final Schematic schematic;
|
||||||
public final GridBits occupied;
|
public final GridBits occupied;
|
||||||
|
|
||||||
|
//offsets for drills
|
||||||
|
public int centerX, centerY;
|
||||||
|
|
||||||
public @Nullable Liquid requiredLiquid;
|
public @Nullable Liquid requiredLiquid;
|
||||||
public @Nullable Item requiredItem;
|
public @Nullable Item requiredItem;
|
||||||
public @Nullable Block core;
|
public @Nullable Block core;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package mindustry.game;
|
package mindustry.game;
|
||||||
|
|
||||||
|
import arc.files.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.struct.IntIntMap.*;
|
import arc.struct.IntIntMap.*;
|
||||||
import arc.files.*;
|
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
|
import mindustry.content.*;
|
||||||
import mindustry.mod.Mods.*;
|
import mindustry.mod.Mods.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -125,5 +126,23 @@ public class Schematic implements Publishable, Comparable<Schematic>{
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//pooling only
|
||||||
|
public Stile(){
|
||||||
|
block = Blocks.air;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stile set(Stile other){
|
||||||
|
block = other.block;
|
||||||
|
x = other.x;
|
||||||
|
y = other.y;
|
||||||
|
config = other.config;
|
||||||
|
rotation = other.rotation;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stile copy(){
|
||||||
|
return new Stile(block, x, y, config, rotation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ package mindustry.maps.generators;
|
|||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.pooling.*;
|
||||||
import mindustry.ai.BaseRegistry.*;
|
import mindustry.ai.BaseRegistry.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Schematic.*;
|
import mindustry.game.Schematic.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -17,6 +19,10 @@ import mindustry.world.blocks.production.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class BaseGenerator{
|
public class BaseGenerator{
|
||||||
|
private static final Schematic tmpSchem = new Schematic(new Array<>(), new StringMap(), 0, 0);
|
||||||
|
private static final Schematic tmpSchem2 = new Schematic(new Array<>(), new StringMap(), 0, 0);
|
||||||
|
private static final Vec2 axis = new Vec2(), rotator = new Vec2();
|
||||||
|
|
||||||
private Tiles tiles;
|
private Tiles tiles;
|
||||||
private Team team;
|
private Team team;
|
||||||
private ObjectMap<Item, OreBlock> ores = new ObjectMap<>();
|
private ObjectMap<Item, OreBlock> ores = new ObjectMap<>();
|
||||||
@@ -36,12 +42,12 @@ public class BaseGenerator{
|
|||||||
|
|
||||||
float bracket = 0.1f;
|
float bracket = 0.1f;
|
||||||
int range = 200;
|
int range = 200;
|
||||||
int wallAngle = 180;
|
int wallAngle = 70; //180 for full coverage
|
||||||
BasePart coreschem = bases.cores.getFrac(bracket);
|
BasePart coreschem = bases.cores.getFrac(bracket);
|
||||||
|
|
||||||
Block wall = wallsSmall.getFrac(bracket), wallLarge = wallsLarge.getFrac(bracket);
|
Block wall = wallsSmall.getFrac(bracket), wallLarge = wallsLarge.getFrac(bracket);
|
||||||
|
|
||||||
//TODO random flipping and rotation
|
//TODO random rotation
|
||||||
|
|
||||||
for(Tile tile : cores){
|
for(Tile tile : cores){
|
||||||
tile.clearOverlay();
|
tile.clearOverlay();
|
||||||
@@ -67,67 +73,81 @@ public class BaseGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//second pass: small walls
|
if(wallAngle > 0){
|
||||||
for(Tile core : cores){
|
//second pass: small walls
|
||||||
core.circle(range, (x, y) -> {
|
for(Tile core : cores){
|
||||||
Tile tile = tiles.getn(x, y);
|
core.circle(range, (x, y) -> {
|
||||||
if(tile.block().alwaysReplace){
|
Tile tile = tiles.getn(x, y);
|
||||||
boolean any = false;
|
if(tile.block().alwaysReplace){
|
||||||
|
boolean any = false;
|
||||||
|
|
||||||
for(Point2 p : Geometry.d8){
|
for(Point2 p : Geometry.d8){
|
||||||
if(Angles.angleDist(Angles.angle(p.x, p.y), spawn.angleTo(core)) > wallAngle){
|
if(Angles.angleDist(Angles.angle(p.x, p.y), spawn.angleTo(core)) > wallAngle){
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tile o = tiles.get(tile.x + p.x, tile.y + p.y);
|
||||||
|
if(o != null && o.team() == team && !(o.block() instanceof Wall)){
|
||||||
|
any = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile o = tiles.get(tile.x + p.x, tile.y + p.y);
|
if(any){
|
||||||
if(o != null && o.team() == team && !(o.block() instanceof Wall)){
|
tile.setBlock(wall, team);
|
||||||
any = true;
|
}
|
||||||
break;
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//third pass: large walls
|
||||||
|
for(Tile core : cores){
|
||||||
|
core.circle(range, (x, y) -> {
|
||||||
|
int walls = 0;
|
||||||
|
for(int cx = 0; cx < 2; cx++){
|
||||||
|
for(int cy = 0; cy < 2; cy++){
|
||||||
|
Tile tile = tiles.get(x + cx, y + cy);
|
||||||
|
if(tile == null || tile.block().size != 1 || (tile.block() != wall && !tile.block().alwaysReplace)) return;
|
||||||
|
|
||||||
|
if(tile.block() == wall){
|
||||||
|
walls ++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(any){
|
if(walls >= 3){
|
||||||
tile.setBlock(wall, team);
|
tiles.getn(x, y).setBlock(wallLarge, team);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//third pass: large walls
|
|
||||||
for(Tile core : cores){
|
|
||||||
core.circle(range, (x, y) -> {
|
|
||||||
int walls = 0;
|
|
||||||
for(int cx = 0; cx < 2; cx++){
|
|
||||||
for(int cy = 0; cy < 2; cy++){
|
|
||||||
Tile tile = tiles.get(x + cx, y + cy);
|
|
||||||
if(tile == null || tile.block().size != 1 || (tile.block() != wall && !tile.block().alwaysReplace)) return;
|
|
||||||
|
|
||||||
if(tile.block() == wall){
|
|
||||||
walls ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(walls >= 3){
|
|
||||||
tiles.getn(x, y).setBlock(wallLarge, team);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean tryPlace(BasePart part, int x, int y){
|
boolean tryPlace(BasePart part, int x, int y){
|
||||||
int cx = x - part.schematic.width/2, cy = y - part.schematic.height/2;
|
int rotation = 0;
|
||||||
for(int rx = cx; rx <= cx + part.schematic.width; rx++){
|
axis.set((int)(part.schematic.width / 2f), (int)(part.schematic.height / 2f));
|
||||||
for(int ry = cy; ry <= cy + part.schematic.height; ry++){
|
Schematic result = rotate(part.schematic, rotation);
|
||||||
|
|
||||||
|
rotator.set(part.centerX, part.centerY).rotateAround(axis, rotation * 90);
|
||||||
|
int cx = x - (int)rotator.x;
|
||||||
|
int cy = y - (int)rotator.y;
|
||||||
|
|
||||||
|
for(int rx = cx; rx <= cx + result.width; rx++){
|
||||||
|
for(int ry = cy; ry <= cy + result.height; ry++){
|
||||||
Tile tile = tiles.get(rx, ry);
|
Tile tile = tiles.get(rx, ry);
|
||||||
if(tile == null || ((!tile.block().alwaysReplace || world.getDarkness(rx, ry) > 0) && part.occupied.get(rx - cx, ry - cy))){
|
int ox = rx - cx, oy = ry - cy;
|
||||||
|
rotator.set(ox, oy).rotateAround(axis, rotation * 90);
|
||||||
|
ox = (int)rotator.x;
|
||||||
|
oy = (int)rotator.y;
|
||||||
|
|
||||||
|
if(tile == null || ((!tile.block().alwaysReplace || world.getDarkness(rx, ry) > 0) && part.occupied.get(ox, oy))){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(part.requiredItem != null){
|
if(part.requiredItem != null){
|
||||||
for(Stile tile : part.schematic.tiles){
|
for(Stile tile : result.tiles){
|
||||||
if(tile.block instanceof Drill){
|
if(tile.block instanceof Drill){
|
||||||
tile.block.iterateTaken(tile.x + cx, tile.y + cy, (ex, ey) -> {
|
tile.block.iterateTaken(tile.x + cx, tile.y + cy, (ex, ey) -> {
|
||||||
tiles.getn(ex, ey).setOverlay(ores.get(part.requiredItem));
|
tiles.getn(ex, ey).setOverlay(ores.get(part.requiredItem));
|
||||||
@@ -136,8 +156,68 @@ public class BaseGenerator{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Schematics.place(part.schematic, x, y, team);
|
Schematics.place(result, cx + result.width/2, cy + result.height/2, team);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Schematic rotate(Schematic input, int times){
|
||||||
|
if(times == 0) return input;
|
||||||
|
|
||||||
|
boolean sign = times < 0;
|
||||||
|
for(int i = 0; i < Math.abs(times); i++){
|
||||||
|
input = rotated(input, sign);
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
Schematic rotated(Schematic input, boolean counter){
|
||||||
|
int direction = Mathf.sign(counter);
|
||||||
|
Schematic schem = input == tmpSchem ? tmpSchem2 : tmpSchem2;
|
||||||
|
schem.width = input.width;
|
||||||
|
schem.height = input.height;
|
||||||
|
Pools.freeAll(schem.tiles);
|
||||||
|
schem.tiles.clear();
|
||||||
|
for(Stile tile : input.tiles){
|
||||||
|
schem.tiles.add(Pools.obtain(Stile.class, Stile::new).set(tile));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ox = schem.width/2, oy = schem.height/2;
|
||||||
|
|
||||||
|
schem.tiles.each(req -> {
|
||||||
|
req.config = BuildRequest.pointConfig(req.config, p -> {
|
||||||
|
int cx = p.x, cy = p.y;
|
||||||
|
int lx = cx;
|
||||||
|
|
||||||
|
if(direction >= 0){
|
||||||
|
cx = -cy;
|
||||||
|
cy = lx;
|
||||||
|
}else{
|
||||||
|
cx = cy;
|
||||||
|
cy = -lx;
|
||||||
|
}
|
||||||
|
p.set(cx, cy);
|
||||||
|
});
|
||||||
|
|
||||||
|
//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){
|
||||||
|
wx = -wy;
|
||||||
|
wy = x;
|
||||||
|
}else{
|
||||||
|
wx = wy;
|
||||||
|
wy = -x;
|
||||||
|
}
|
||||||
|
req.x = (short)(world.toTile(wx - req.block.offset()) + ox);
|
||||||
|
req.y = (short)(world.toTile(wy - req.block.offset()) + oy);
|
||||||
|
req.rotation = (byte)Mathf.mod(req.rotation + direction, 4);
|
||||||
|
});
|
||||||
|
|
||||||
|
//assign flipped values, since it's rotated
|
||||||
|
schem.width = input.height;
|
||||||
|
schem.height = input.width;
|
||||||
|
|
||||||
|
return schem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=1fc9e8ef5ecca01e058eab1ff4d7fd673aa5431d
|
archash=02f15d353cddc9725ad46bafeeae77c3f2719bac
|
||||||
|
|||||||
Reference in New Issue
Block a user