Certain team-specific rules
This commit is contained in:
@@ -19,6 +19,8 @@ public class EntityIO{
|
|||||||
final static Json json = new Json();
|
final static Json json = new Json();
|
||||||
//suffixes for sync fields
|
//suffixes for sync fields
|
||||||
final static String targetSuf = "_TARGET_", lastSuf = "_LAST_";
|
final static String targetSuf = "_TARGET_", lastSuf = "_LAST_";
|
||||||
|
//replacements after refactoring
|
||||||
|
final static StringMap replacements = StringMap.of("mindustry.entities.units.BuildRequest", "mindustry.entities.units.BuildPlan");
|
||||||
|
|
||||||
final ClassSerializer serializer;
|
final ClassSerializer serializer;
|
||||||
final String name;
|
final String name;
|
||||||
@@ -198,6 +200,7 @@ public class EntityIO{
|
|||||||
|
|
||||||
private void io(String type, String field) throws Exception{
|
private void io(String type, String field) throws Exception{
|
||||||
type = type.replace("mindustry.gen.", "");
|
type = type.replace("mindustry.gen.", "");
|
||||||
|
type = replacements.get(type, type);
|
||||||
|
|
||||||
if(BaseProcessor.isPrimitive(type)){
|
if(BaseProcessor.isPrimitive(type)){
|
||||||
s(type.equals("boolean") ? "bool" : type.charAt(0) + "", field);
|
s(type.equals("boolean") ? "bool" : type.charAt(0) + "", field);
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:armor,type:float,size:4},{name:baseRotation,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:payloads,type:arc.struct.Seq<mindustry.world.blocks.payloads.Payload>,size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:1,fields:[{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -14,7 +14,6 @@ import mindustry.type.*;
|
|||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.defense.*;
|
import mindustry.world.blocks.defense.*;
|
||||||
import mindustry.world.blocks.production.*;
|
import mindustry.world.blocks.production.*;
|
||||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -48,10 +47,13 @@ public class BaseAI{
|
|||||||
|
|
||||||
for(int i = 0; i < attempts; i++){
|
for(int i = 0; i < attempts; i++){
|
||||||
int range = 150;
|
int range = 150;
|
||||||
CoreEntity core = data.cores.random();
|
|
||||||
|
Position pos = randomPosition();
|
||||||
|
//when there are no random positions, do nothing.
|
||||||
|
if(pos == null) return;
|
||||||
|
|
||||||
Tmp.v1.rnd(Mathf.random(range));
|
Tmp.v1.rnd(Mathf.random(range));
|
||||||
int wx = (int)(core.tileX() + Tmp.v1.x), wy = (int)(core.tileY() + Tmp.v1.y);
|
int wx = (int)(world.toTile(pos.getX()) + Tmp.v1.x), wy = (int)(world.toTile(pos.getY()) + Tmp.v1.y);
|
||||||
Tile tile = world.tiles.getc(wx, wy);
|
Tile tile = world.tiles.getc(wx, wy);
|
||||||
|
|
||||||
Seq<BasePart> parts = null;
|
Seq<BasePart> parts = null;
|
||||||
@@ -74,7 +76,17 @@ public class BaseAI{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean tryPlace(BasePart part, int x, int y){
|
/** @return a random position from which to seed building. */
|
||||||
|
private Position randomPosition(){
|
||||||
|
if(data.hasCore()){
|
||||||
|
return data.cores.random();
|
||||||
|
}else if(data.team == state.rules.waveTeam){
|
||||||
|
return spawner.getSpawns().random();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean tryPlace(BasePart part, int x, int y){
|
||||||
int rotation = Mathf.range(2);
|
int rotation = Mathf.range(2);
|
||||||
axis.set((int)(part.schematic.width / 2f), (int)(part.schematic.height / 2f));
|
axis.set((int)(part.schematic.width / 2f), (int)(part.schematic.height / 2f));
|
||||||
Schematic result = Schematics.rotate(part.schematic, rotation);
|
Schematic result = Schematics.rotate(part.schematic, rotation);
|
||||||
@@ -131,7 +143,7 @@ public class BaseAI{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tryWalls(){
|
private void tryWalls(){
|
||||||
Block wall = Blocks.copperWall;
|
Block wall = Blocks.copperWall;
|
||||||
Tile spawn = state.rules.defaultTeam.core() != null ? state.rules.defaultTeam.core().tile : data.team.core().tile;
|
Tile spawn = state.rules.defaultTeam.core() != null ? state.rules.defaultTeam.core().tile : data.team.core().tile;
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ public class BuilderAI extends AIController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//approach request if building
|
//approach request if building
|
||||||
if(builder.buildRequest() != null){
|
if(builder.buildPlan() != null){
|
||||||
BuildRequest req = builder.buildRequest();
|
BuildPlan req = builder.buildPlan();
|
||||||
|
|
||||||
boolean valid =
|
boolean valid =
|
||||||
(req.tile().entity instanceof BuildEntity && req.tile().<BuildEntity>ent().cblock == req.block) ||
|
(req.tile().entity instanceof BuildEntity && req.tile().<BuildEntity>ent().cblock == req.block) ||
|
||||||
@@ -37,7 +37,7 @@ public class BuilderAI extends AIController{
|
|||||||
moveTo(req.tile(), buildingRange - 20f);
|
moveTo(req.tile(), buildingRange - 20f);
|
||||||
}else{
|
}else{
|
||||||
//discard invalid request
|
//discard invalid request
|
||||||
builder.requests().removeFirst();
|
builder.plans().removeFirst();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
//find new request
|
//find new request
|
||||||
@@ -50,7 +50,7 @@ public class BuilderAI extends AIController{
|
|||||||
blocks.removeFirst();
|
blocks.removeFirst();
|
||||||
}else if(Build.validPlace(content.block(block.block), unit.team(), block.x, block.y, block.rotation)){ //it's valid.
|
}else if(Build.validPlace(content.block(block.block), unit.team(), block.x, block.y, block.rotation)){ //it's valid.
|
||||||
//add build request.
|
//add build request.
|
||||||
BuildRequest req = new BuildRequest(block.x, block.y, block.rotation, content.block(block.block));
|
BuildPlan req = new BuildPlan(block.x, block.y, block.rotation, content.block(block.block));
|
||||||
if(block.config != null){
|
if(block.config != null){
|
||||||
req.configure(block.config);
|
req.configure(block.config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,17 +311,9 @@ public class Logic implements ApplicationListener{
|
|||||||
updateWeather();
|
updateWeather();
|
||||||
|
|
||||||
for(TeamData data : state.teams.getActive()){
|
for(TeamData data : state.teams.getActive()){
|
||||||
if(data.hasAI() && data.hasCore()){
|
if(data.hasAI()){
|
||||||
data.ai.update();
|
data.ai.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO this is terrible
|
|
||||||
//fills enemy core with resources
|
|
||||||
if(state.rules.enemyInfiniteResources && state.rules.waves && data.team == state.rules.waveTeam && data.hasCore()){
|
|
||||||
for(Item item : content.items()){
|
|
||||||
data.core().items.set(item, data.core().block.itemCapacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -552,14 +552,14 @@ public class NetClient implements ApplicationListener{
|
|||||||
|
|
||||||
void sync(){
|
void sync(){
|
||||||
if(timer.get(0, playerSyncTime)){
|
if(timer.get(0, playerSyncTime)){
|
||||||
BuildRequest[] requests = null;
|
BuildPlan[] requests = null;
|
||||||
if(player.isBuilder() && control.input.isBuilding){
|
if(player.isBuilder() && control.input.isBuilding){
|
||||||
//limit to 10 to prevent buffer overflows
|
//limit to 10 to prevent buffer overflows
|
||||||
int usedRequests = Math.min(player.builder().requests().size, 10);
|
int usedRequests = Math.min(player.builder().plans().size, 10);
|
||||||
|
|
||||||
requests = new BuildRequest[usedRequests];
|
requests = new BuildPlan[usedRequests];
|
||||||
for(int i = 0; i < usedRequests; i++){
|
for(int i = 0; i < usedRequests; i++){
|
||||||
requests[i] = player.builder().requests().get(i);
|
requests[i] = player.builder().plans().get(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -533,7 +533,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
float xVelocity, float yVelocity,
|
float xVelocity, float yVelocity,
|
||||||
Tile mining,
|
Tile mining,
|
||||||
boolean boosting, boolean shooting, boolean chatting,
|
boolean boosting, boolean shooting, boolean chatting,
|
||||||
@Nullable BuildRequest[] requests,
|
@Nullable BuildPlan[] requests,
|
||||||
float viewX, float viewY, float viewWidth, float viewHeight
|
float viewX, float viewY, float viewWidth, float viewHeight
|
||||||
){
|
){
|
||||||
NetConnection connection = player.con();
|
NetConnection connection = player.con();
|
||||||
@@ -571,7 +571,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(requests != null){
|
if(requests != null){
|
||||||
for(BuildRequest req : requests){
|
for(BuildPlan req : requests){
|
||||||
if(req == null) continue;
|
if(req == null) continue;
|
||||||
Tile tile = world.tile(req.x, req.y);
|
Tile tile = world.tile(req.x, req.y);
|
||||||
if(tile == null || (!req.breaking && req.block == null)) continue;
|
if(tile == null || (!req.breaking && req.block == null)) continue;
|
||||||
@@ -592,7 +592,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
connection.rejectedRequests.add(req);
|
connection.rejectedRequests.add(req);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
player.builder().requests().addLast(req);
|
player.builder().plans().addLast(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ abstract class BuilderComp implements Unitc{
|
|||||||
|
|
||||||
@Import float x, y, rotation;
|
@Import float x, y, rotation;
|
||||||
|
|
||||||
Queue<BuildRequest> requests = new Queue<>();
|
Queue<BuildPlan> plans = new Queue<>();
|
||||||
transient float buildSpeed = 1f;
|
transient float buildSpeed = 1f;
|
||||||
transient boolean building = true;
|
transient boolean building = true;
|
||||||
|
|
||||||
@@ -44,32 +44,32 @@ abstract class BuilderComp implements Unitc{
|
|||||||
|
|
||||||
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange;
|
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange;
|
||||||
|
|
||||||
Iterator<BuildRequest> it = requests.iterator();
|
Iterator<BuildPlan> it = plans.iterator();
|
||||||
while(it.hasNext()){
|
while(it.hasNext()){
|
||||||
BuildRequest req = it.next();
|
BuildPlan req = it.next();
|
||||||
Tile tile = world.tile(req.x, req.y);
|
Tile tile = world.tile(req.x, req.y);
|
||||||
if(tile == null || (req.breaking && tile.block() == Blocks.air) || (!req.breaking && (tile.rotation() == req.rotation || !req.block.rotate) && tile.block() == req.block)){
|
if(tile == null || (req.breaking && tile.block() == Blocks.air) || (!req.breaking && (tile.rotation() == req.rotation || !req.block.rotate) && tile.block() == req.block)){
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tilec core = closestCore();
|
Tilec core = core();
|
||||||
|
|
||||||
//nothing to build.
|
//nothing to build.
|
||||||
if(buildRequest() == null) return;
|
if(buildPlan() == null) return;
|
||||||
|
|
||||||
//find the next build request
|
//find the next build request
|
||||||
if(requests.size > 1){
|
if(plans.size > 1){
|
||||||
int total = 0;
|
int total = 0;
|
||||||
BuildRequest req;
|
BuildPlan req;
|
||||||
while((dst((req = buildRequest()).tile()) > finalPlaceDst || shouldSkip(req, core)) && total < requests.size){
|
while((dst((req = buildPlan()).tile()) > finalPlaceDst || shouldSkip(req, core)) && total < plans.size){
|
||||||
requests.removeFirst();
|
plans.removeFirst();
|
||||||
requests.addLast(req);
|
plans.addLast(req);
|
||||||
total++;
|
total++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildRequest current = buildRequest();
|
BuildPlan current = buildPlan();
|
||||||
|
|
||||||
if(dst(current.tile()) > finalPlaceDst) return;
|
if(dst(current.tile()) > finalPlaceDst) return;
|
||||||
|
|
||||||
@@ -91,11 +91,11 @@ abstract class BuilderComp implements Unitc{
|
|||||||
}else if(!current.initialized && current.breaking && Build.validBreak(team(), current.x, current.y)){
|
}else if(!current.initialized && current.breaking && Build.validBreak(team(), current.x, current.y)){
|
||||||
Build.beginBreak(team(), current.x, current.y);
|
Build.beginBreak(team(), current.x, current.y);
|
||||||
}else{
|
}else{
|
||||||
requests.removeFirst();
|
plans.removeFirst();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}else if(tile.team() != team()){
|
}else if(tile.team() != team()){
|
||||||
requests.removeFirst();
|
plans.removeFirst();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +130,8 @@ abstract class BuilderComp implements Unitc{
|
|||||||
/** Draw all current build requests. Does not draw the beam effect, only the positions. */
|
/** Draw all current build requests. Does not draw the beam effect, only the positions. */
|
||||||
void drawBuildRequests(){
|
void drawBuildRequests(){
|
||||||
|
|
||||||
for(BuildRequest request : requests){
|
for(BuildPlan request : plans){
|
||||||
if(request.progress > 0.01f || (buildRequest() == request && request.initialized && (dst(request.x * tilesize, request.y * tilesize) <= buildingRange || state.isEditor()))) continue;
|
if(request.progress > 0.01f || (buildPlan() == request && request.initialized && (dst(request.x * tilesize, request.y * tilesize) <= buildingRange || state.isEditor()))) continue;
|
||||||
|
|
||||||
request.animScale = 1f;
|
request.animScale = 1f;
|
||||||
if(request.breaking){
|
if(request.breaking){
|
||||||
@@ -146,7 +146,7 @@ abstract class BuilderComp implements Unitc{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether this request should be skipped, in favor of the next one. */
|
/** @return whether this request should be skipped, in favor of the next one. */
|
||||||
boolean shouldSkip(BuildRequest request, @Nullable Tilec core){
|
boolean shouldSkip(BuildPlan request, @Nullable Tilec core){
|
||||||
//requests that you have at least *started* are considered
|
//requests that you have at least *started* are considered
|
||||||
if(state.rules.infiniteResources || request.breaking || core == null) return false;
|
if(state.rules.infiniteResources || request.breaking || core == null) return false;
|
||||||
//TODO these are bad criteria
|
//TODO these are bad criteria
|
||||||
@@ -155,53 +155,54 @@ abstract class BuilderComp implements Unitc{
|
|||||||
|
|
||||||
void removeBuild(int x, int y, boolean breaking){
|
void removeBuild(int x, int y, boolean breaking){
|
||||||
//remove matching request
|
//remove matching request
|
||||||
int idx = requests.indexOf(req -> req.breaking == breaking && req.x == x && req.y == y);
|
int idx = plans.indexOf(req -> req.breaking == breaking && req.x == x && req.y == y);
|
||||||
if(idx != -1){
|
if(idx != -1){
|
||||||
requests.removeIndex(idx);
|
plans.removeIndex(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return whether this builder's place queue contains items. */
|
/** Return whether this builder's place queue contains items. */
|
||||||
boolean isBuilding(){
|
boolean isBuilding(){
|
||||||
return requests.size != 0;
|
return plans.size != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clears the placement queue. */
|
/** Clears the placement queue. */
|
||||||
void clearBuilding(){
|
void clearBuilding(){
|
||||||
requests.clear();
|
plans.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add another build requests to the tail of the queue, if it doesn't exist there yet. */
|
/** Add another build requests to the tail of the queue, if it doesn't exist there yet. */
|
||||||
void addBuild(BuildRequest place){
|
void addBuild(BuildPlan place){
|
||||||
addBuild(place, true);
|
addBuild(place, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add another build requests to the queue, if it doesn't exist there yet. */
|
/** Add another build requests to the queue, if it doesn't exist there yet. */
|
||||||
void addBuild(BuildRequest place, boolean tail){
|
void addBuild(BuildPlan place, boolean tail){
|
||||||
BuildRequest replace = null;
|
BuildPlan replace = null;
|
||||||
for(BuildRequest request : requests){
|
for(BuildPlan request : plans){
|
||||||
if(request.x == place.x && request.y == place.y){
|
if(request.x == place.x && request.y == place.y){
|
||||||
replace = request;
|
replace = request;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(replace != null){
|
if(replace != null){
|
||||||
requests.remove(replace);
|
plans.remove(replace);
|
||||||
}
|
}
|
||||||
Tile tile = world.tile(place.x, place.y);
|
Tile tile = world.tile(place.x, place.y);
|
||||||
if(tile != null && tile.entity instanceof BuildEntity){
|
if(tile != null && tile.entity instanceof BuildEntity){
|
||||||
place.progress = tile.<BuildEntity>ent().progress;
|
place.progress = tile.<BuildEntity>ent().progress;
|
||||||
}
|
}
|
||||||
if(tail){
|
if(tail){
|
||||||
requests.addLast(place);
|
plans.addLast(place);
|
||||||
}else{
|
}else{
|
||||||
requests.addFirst(place);
|
plans.addFirst(place);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the build requests currently active, or the one at the top of the queue.*/
|
/** Return the build request currently active, or the one at the top of the queue.*/
|
||||||
@Nullable BuildRequest buildRequest(){
|
@Nullable
|
||||||
return requests.size == 0 ? null : requests.first();
|
BuildPlan buildPlan(){
|
||||||
|
return plans.size == 0 ? null : plans.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -211,15 +212,15 @@ abstract class BuilderComp implements Unitc{
|
|||||||
//TODO check correctness
|
//TODO check correctness
|
||||||
Draw.z(Layer.flyingUnit);
|
Draw.z(Layer.flyingUnit);
|
||||||
|
|
||||||
BuildRequest request = buildRequest();
|
BuildPlan plan = buildPlan();
|
||||||
Tile tile = world.tile(request.x, request.y);
|
Tile tile = world.tile(plan.x, plan.y);
|
||||||
|
|
||||||
if(dst(tile) > buildingRange && !state.isEditor()){
|
if(dst(tile) > buildingRange && !state.isEditor()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = request.breaking ? tile.block().size : request.block.size;
|
int size = plan.breaking ? tile.block().size : plan.block.size;
|
||||||
float tx = request.drawx(), ty = request.drawy();
|
float tx = plan.drawx(), ty = plan.drawy();
|
||||||
|
|
||||||
Lines.stroke(1f, Pal.accent);
|
Lines.stroke(1f, Pal.accent);
|
||||||
float focusLen = 3.8f + Mathf.absin(Time.time(), 1.1f, 0.6f);
|
float focusLen = 3.8f + Mathf.absin(Time.time(), 1.1f, 0.6f);
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void absorb(){
|
public void absorb(){
|
||||||
//TODO
|
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
return state.teams.closestCore(x(), y(), team);
|
return state.teams.closestCore(x(), y(), team);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable CoreEntity core(){
|
||||||
|
return team.core();
|
||||||
|
}
|
||||||
|
|
||||||
public void reset(){
|
public void reset(){
|
||||||
team = state.rules.defaultTeam;
|
team = state.rules.defaultTeam;
|
||||||
admin = typing = false;
|
admin = typing = false;
|
||||||
@@ -87,8 +91,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
CoreEntity core = closestCore();
|
CoreEntity core = closestCore();
|
||||||
|
|
||||||
if(!dead()){
|
if(!dead()){
|
||||||
x(unit.x());
|
set(unit);
|
||||||
y(unit.y());
|
|
||||||
unit.team(team);
|
unit.team(team);
|
||||||
deathTimer = 0;
|
deathTimer = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,14 @@ abstract class TeamComp implements Posc{
|
|||||||
|
|
||||||
Team team = Team.derelict;
|
Team team = Team.derelict;
|
||||||
|
|
||||||
|
public boolean cheating(){
|
||||||
|
return team.rules().cheat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Tilec core(){
|
||||||
|
return team.core();
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable Tilec closestCore(){
|
public @Nullable Tilec closestCore(){
|
||||||
return state.teams.closestCore(x, y, team);
|
return state.teams.closestCore(x, y, team);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import mindustry.world.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
/** Class for storing build requests. Can be either a place or remove request. */
|
/** Class for storing build requests. Can be either a place or remove request. */
|
||||||
public class BuildRequest{
|
public class BuildPlan{
|
||||||
/** Position and rotation of this request. */
|
/** Position and rotation of this request. */
|
||||||
public int x, y, rotation;
|
public int x, y, rotation;
|
||||||
/** Block being placed. If null, this is a breaking request.*/
|
/** Block being placed. If null, this is a breaking request.*/
|
||||||
@@ -31,7 +31,7 @@ public class BuildRequest{
|
|||||||
public float animScale = 0f;
|
public float animScale = 0f;
|
||||||
|
|
||||||
/** This creates a build request. */
|
/** This creates a build request. */
|
||||||
public BuildRequest(int x, int y, int rotation, Block block){
|
public BuildPlan(int x, int y, int rotation, Block block){
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
@@ -40,7 +40,7 @@ public class BuildRequest{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** This creates a remove request. */
|
/** This creates a remove request. */
|
||||||
public BuildRequest(int x, int y){
|
public BuildPlan(int x, int y){
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.rotation = -1;
|
this.rotation = -1;
|
||||||
@@ -48,7 +48,7 @@ public class BuildRequest{
|
|||||||
this.breaking = true;
|
this.breaking = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BuildRequest(){
|
public BuildPlan(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,8 +74,8 @@ public class BuildRequest{
|
|||||||
this.config = pointConfig(this.config, cons);
|
this.config = pointConfig(this.config, cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BuildRequest copy(){
|
public BuildPlan copy(){
|
||||||
BuildRequest copy = new BuildRequest();
|
BuildPlan copy = new BuildPlan();
|
||||||
copy.x = x;
|
copy.x = x;
|
||||||
copy.y = y;
|
copy.y = y;
|
||||||
copy.rotation = rotation;
|
copy.rotation = rotation;
|
||||||
@@ -91,7 +91,7 @@ public class BuildRequest{
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BuildRequest original(int x, int y, int originalWidth, int originalHeight){
|
public BuildPlan original(int x, int y, int originalWidth, int originalHeight){
|
||||||
originalX = x;
|
originalX = x;
|
||||||
originalY = y;
|
originalY = y;
|
||||||
this.originalWidth = originalWidth;
|
this.originalWidth = originalWidth;
|
||||||
@@ -107,7 +107,7 @@ public class BuildRequest{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BuildRequest set(int x, int y, int rotation, Block block){
|
public BuildPlan set(int x, int y, int rotation, Block block){
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
@@ -124,7 +124,7 @@ public class BuildRequest{
|
|||||||
return y*tilesize + block.offset();
|
return y*tilesize + block.offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BuildRequest configure(Object config){
|
public BuildPlan configure(Object config){
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.hasConfig = true;
|
this.hasConfig = true;
|
||||||
return this;
|
return this;
|
||||||
@@ -3,6 +3,8 @@ package mindustry.game;
|
|||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.serialization.*;
|
||||||
|
import arc.util.serialization.Json.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
@@ -14,18 +16,26 @@ import mindustry.world.*;
|
|||||||
* Does not store game state, just configuration.
|
* Does not store game state, just configuration.
|
||||||
*/
|
*/
|
||||||
public class Rules{
|
public class Rules{
|
||||||
/** Whether the player team has infinite resources. */
|
/** Whether ever team has infinite resources and instant build speed. */
|
||||||
public boolean infiniteResources;
|
public boolean infiniteResources;
|
||||||
|
/** Team-specific rules. */
|
||||||
|
public TeamRules teams = new TeamRules();
|
||||||
/** Whether the waves come automatically on a timer. If not, waves come when the play button is pressed. */
|
/** Whether the waves come automatically on a timer. If not, waves come when the play button is pressed. */
|
||||||
public boolean waveTimer = true;
|
public boolean waveTimer = true;
|
||||||
/** Whether waves are spawnable at all. */
|
/** Whether waves are spawnable at all. */
|
||||||
public boolean waves;
|
public boolean waves;
|
||||||
/** Whether the enemy AI has infinite resources in most of their buildings and turrets. */
|
|
||||||
public boolean enemyCheat;
|
|
||||||
/** Whether the enemy AI has infinite resources in their core only. TODO remove */
|
|
||||||
public boolean enemyInfiniteResources = true;
|
|
||||||
/** Whether the game objective is PvP. Note that this enables automatic hosting. */
|
/** Whether the game objective is PvP. Note that this enables automatic hosting. */
|
||||||
public boolean pvp;
|
public boolean pvp;
|
||||||
|
/** Whether to pause the wave timer until all enemies are destroyed. */
|
||||||
|
public boolean waitEnemies = false;
|
||||||
|
/** Determinates if gamemode is attack mode */
|
||||||
|
public boolean attackMode = false;
|
||||||
|
/** Whether this is the editor gamemode. */
|
||||||
|
public boolean editor = false;
|
||||||
|
/** Whether the tutorial is enabled. False by default. */
|
||||||
|
public boolean tutorial = false;
|
||||||
|
/** Whether a gameover can happen at all. Set this to false to implement custom gameover conditions. */
|
||||||
|
public boolean canGameOver = true;
|
||||||
/** Whether reactors can explode and damage other blocks. */
|
/** Whether reactors can explode and damage other blocks. */
|
||||||
public boolean reactorExplosions = true;
|
public boolean reactorExplosions = true;
|
||||||
/** How fast unit pads build units. */
|
/** How fast unit pads build units. */
|
||||||
@@ -60,18 +70,6 @@ public class Rules{
|
|||||||
public @Nullable Sector sector;
|
public @Nullable Sector sector;
|
||||||
/** Spawn layout. */
|
/** Spawn layout. */
|
||||||
public Seq<SpawnGroup> spawns = new Seq<>();
|
public Seq<SpawnGroup> spawns = new Seq<>();
|
||||||
/** Whether to pause the wave timer until all enemies are destroyed. */
|
|
||||||
public boolean waitEnemies = false;
|
|
||||||
/** Determinates if gamemode is attack mode */
|
|
||||||
public boolean attackMode = false;
|
|
||||||
/** Whether this is the editor gamemode. */
|
|
||||||
public boolean editor = false;
|
|
||||||
/** Whether the tutorial is enabled. False by default. */
|
|
||||||
public boolean tutorial = false;
|
|
||||||
/** Whether a gameover can happen at all. Set this to false to implement custom gameover conditions. */
|
|
||||||
public boolean canGameOver = true;
|
|
||||||
/** EXPERIMENTAL building AI. TODO remove */
|
|
||||||
public boolean buildAI = true;
|
|
||||||
/** Starting items put in cores */
|
/** Starting items put in cores */
|
||||||
public Seq<ItemStack> loadout = Seq.with(ItemStack.with(Items.copper, 100));
|
public Seq<ItemStack> loadout = Seq.with(ItemStack.with(Items.copper, 100));
|
||||||
/** Weather events that occur here. */
|
/** Weather events that occur here. */
|
||||||
@@ -92,6 +90,16 @@ public class Rules{
|
|||||||
/** special tags for additional info */
|
/** special tags for additional info */
|
||||||
public StringMap tags = new StringMap();
|
public StringMap tags = new StringMap();
|
||||||
|
|
||||||
|
/** A team-specific ruleset. */
|
||||||
|
public static class TeamRule{
|
||||||
|
/** Whether to use building AI. */
|
||||||
|
public boolean ai;
|
||||||
|
/** If true, blocks don't require power or resources. */
|
||||||
|
public boolean cheat;
|
||||||
|
/** If true, resources are not consumed when building. */
|
||||||
|
public boolean infiniteResources;
|
||||||
|
}
|
||||||
|
|
||||||
/** Copies this ruleset exactly. Not efficient at all, do not use often. */
|
/** Copies this ruleset exactly. Not efficient at all, do not use often. */
|
||||||
public Rules copy(){
|
public Rules copy(){
|
||||||
return JsonIO.copy(this);
|
return JsonIO.copy(this);
|
||||||
@@ -111,4 +119,31 @@ public class Rules{
|
|||||||
return Gamemode.survival;
|
return Gamemode.survival;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A simple map for storing TeamRules in an efficient way without hashing. */
|
||||||
|
public static class TeamRules implements Serializable{
|
||||||
|
final TeamRule[] values = new TeamRule[Team.all.length];
|
||||||
|
|
||||||
|
public TeamRule get(Team team){
|
||||||
|
TeamRule out = values[team.uid];
|
||||||
|
if(out == null) values[team.uid] = (out = new TeamRule());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(Json json){
|
||||||
|
for(Team team : Team.all){
|
||||||
|
if(values[team.uid] != null){
|
||||||
|
json.writeValue(team.uid + "", values[team.uid], TeamRule.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(Json json, JsonValue jsonData){
|
||||||
|
for(JsonValue value : jsonData){
|
||||||
|
values[Integer.parseInt(value.name)] = json.readValue(TeamRule.class, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ public class Schematics implements Loadable{
|
|||||||
Draw.rect(Tmp.tr1, buffer.getWidth()/2f, buffer.getHeight()/2f, buffer.getWidth(), -buffer.getHeight());
|
Draw.rect(Tmp.tr1, buffer.getWidth()/2f, buffer.getHeight()/2f, buffer.getWidth(), -buffer.getHeight());
|
||||||
Draw.color();
|
Draw.color();
|
||||||
|
|
||||||
Seq<BuildRequest> requests = schematic.tiles.map(t -> new BuildRequest(t.x, t.y, t.rotation, t.block).configure(t.config));
|
Seq<BuildPlan> requests = schematic.tiles.map(t -> new BuildPlan(t.x, t.y, t.rotation, t.block).configure(t.config));
|
||||||
|
|
||||||
Draw.flush();
|
Draw.flush();
|
||||||
//scale each request to fit schematic
|
//scale each request to fit schematic
|
||||||
@@ -276,8 +276,8 @@ public class Schematics implements Loadable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
|
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
|
||||||
public Seq<BuildRequest> toRequests(Schematic schem, int x, int y){
|
public Seq<BuildPlan> 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, schem.width, schem.height).configure(t.config))
|
return schem.tiles.map(t -> new BuildPlan(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))
|
||||||
.removeAll(s -> !s.block.isVisible() || !s.block.unlockedCur());
|
.removeAll(s -> !s.block.isVisible() || !s.block.unlockedCur());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,7 +558,7 @@ public class Schematics implements Loadable{
|
|||||||
int ox = schem.width/2, oy = schem.height/2;
|
int ox = schem.width/2, oy = schem.height/2;
|
||||||
|
|
||||||
schem.tiles.each(req -> {
|
schem.tiles.each(req -> {
|
||||||
req.config = BuildRequest.pointConfig(req.config, p -> {
|
req.config = BuildPlan.pointConfig(req.config, p -> {
|
||||||
int cx = p.x, cy = p.y;
|
int cx = p.x, cy = p.y;
|
||||||
int lx = cx;
|
int lx = cx;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.math.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import mindustry.game.Rules.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
import mindustry.world.blocks.storage.CoreBlock.*;
|
||||||
@@ -55,6 +56,11 @@ public class Team implements Comparable<Team>{
|
|||||||
all[us] = this;
|
all[us] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the team-specific rules. */
|
||||||
|
public TeamRule rules(){
|
||||||
|
return state.rules.teams.get(this);
|
||||||
|
}
|
||||||
|
|
||||||
public Seq<Team> enemies(){
|
public Seq<Team> enemies(){
|
||||||
return state.teams.enemiesOf(this);
|
return state.teams.enemiesOf(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ public class Teams{
|
|||||||
|
|
||||||
/** @return whether this team is controlled by the AI and builds bases. */
|
/** @return whether this team is controlled by the AI and builds bases. */
|
||||||
public boolean hasAI(){
|
public boolean hasAI(){
|
||||||
return state.rules.attackMode && team == state.rules.waveTeam && state.rules.buildAI;
|
return state.rules.attackMode && team.rules().ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
/** Animation scale for line. */
|
/** Animation scale for line. */
|
||||||
private float selectScale;
|
private float selectScale;
|
||||||
/** Selected build request for movement. */
|
/** Selected build request for movement. */
|
||||||
private @Nullable BuildRequest sreq;
|
private @Nullable BuildPlan sreq;
|
||||||
/** Whether player is currently deleting removal requests. */
|
/** Whether player is currently deleting removal requests. */
|
||||||
private boolean deleting = false, shouldShoot = false;
|
private boolean deleting = false, shouldShoot = false;
|
||||||
|
|
||||||
@@ -124,19 +124,19 @@ public class DesktopInput extends InputHandler{
|
|||||||
|
|
||||||
//draw hover request
|
//draw hover request
|
||||||
if(mode == none && !isPlacing()){
|
if(mode == none && !isPlacing()){
|
||||||
BuildRequest req = getRequest(cursorX, cursorY);
|
BuildPlan req = getRequest(cursorX, cursorY);
|
||||||
if(req != null){
|
if(req != null){
|
||||||
drawSelected(req.x, req.y, req.breaking ? req.tile().block() : req.block, Pal.accent);
|
drawSelected(req.x, req.y, req.breaking ? req.tile().block() : req.block, Pal.accent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw schematic requests
|
//draw schematic requests
|
||||||
for(BuildRequest request : selectRequests){
|
for(BuildPlan request : selectRequests){
|
||||||
request.animScale = 1f;
|
request.animScale = 1f;
|
||||||
drawRequest(request);
|
drawRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(BuildRequest request : selectRequests){
|
for(BuildPlan request : selectRequests){
|
||||||
drawOverRequest(request);
|
drawOverRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
//draw things that may be placed soon
|
//draw things that may be placed soon
|
||||||
if(mode == placing && block != null){
|
if(mode == placing && block != null){
|
||||||
for(int i = 0; i < lineRequests.size; i++){
|
for(int i = 0; i < lineRequests.size; i++){
|
||||||
BuildRequest req = lineRequests.get(i);
|
BuildPlan req = lineRequests.get(i);
|
||||||
if(i == lineRequests.size - 1 && req.block.rotate){
|
if(i == lineRequests.size - 1 && req.block.rotate){
|
||||||
drawArrow(block, req.x, req.y, req.rotation);
|
drawArrow(block, req.x, req.y, req.rotation);
|
||||||
}
|
}
|
||||||
@@ -425,7 +425,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Core.input.keyTap(Binding.select) && !Core.scene.hasMouse()){
|
if(Core.input.keyTap(Binding.select) && !Core.scene.hasMouse()){
|
||||||
BuildRequest req = getRequest(cursorX, cursorY);
|
BuildPlan req = getRequest(cursorX, cursorY);
|
||||||
|
|
||||||
if(Core.input.keyDown(Binding.break_block)){
|
if(Core.input.keyDown(Binding.break_block)){
|
||||||
mode = none;
|
mode = none;
|
||||||
@@ -444,7 +444,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
deleting = true;
|
deleting = true;
|
||||||
}else if(selected != null){
|
}else if(selected != null){
|
||||||
//only begin shooting if there's no cursor event
|
//only begin shooting if there's no cursor event
|
||||||
if(!tileTapped(selected.entity) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.builder().requests().size == 0 || !player.builder().isBuilding()) && !droppingItem &&
|
if(!tileTapped(selected.entity) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.builder().plans().size == 0 || !player.builder().isBuilding()) && !droppingItem &&
|
||||||
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
|
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
|
||||||
isShooting = shouldShoot;
|
isShooting = shouldShoot;
|
||||||
}
|
}
|
||||||
@@ -466,9 +466,9 @@ public class DesktopInput extends InputHandler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Core.input.keyDown(Binding.select) && mode == none && !isPlacing() && deleting){
|
if(Core.input.keyDown(Binding.select) && mode == none && !isPlacing() && deleting){
|
||||||
BuildRequest req = getRequest(cursorX, cursorY);
|
BuildPlan req = getRequest(cursorX, cursorY);
|
||||||
if(req != null && req.breaking){
|
if(req != null && req.breaking){
|
||||||
player.builder().requests().remove(req);
|
player.builder().plans().remove(req);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
deleting = false;
|
deleting = false;
|
||||||
@@ -497,7 +497,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
|
|
||||||
if(sreq != null){
|
if(sreq != null){
|
||||||
if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){
|
if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){
|
||||||
player.builder().requests().remove(sreq, true);
|
player.builder().plans().remove(sreq, true);
|
||||||
}
|
}
|
||||||
sreq = null;
|
sreq = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,10 +64,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
protected @Nullable Schematic lastSchematic;
|
protected @Nullable Schematic lastSchematic;
|
||||||
protected GestureDetector detector;
|
protected GestureDetector detector;
|
||||||
protected PlaceLine line = new PlaceLine();
|
protected PlaceLine line = new PlaceLine();
|
||||||
protected BuildRequest resultreq;
|
protected BuildPlan resultreq;
|
||||||
protected BuildRequest brequest = new BuildRequest();
|
protected BuildPlan brequest = new BuildPlan();
|
||||||
protected Seq<BuildRequest> lineRequests = new Seq<>();
|
protected Seq<BuildPlan> lineRequests = new Seq<>();
|
||||||
protected Seq<BuildRequest> selectRequests = new Seq<>();
|
protected Seq<BuildPlan> selectRequests = new Seq<>();
|
||||||
|
|
||||||
//methods to override
|
//methods to override
|
||||||
|
|
||||||
@@ -232,11 +232,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Eachable<BuildRequest> allRequests(){
|
public Eachable<BuildPlan> allRequests(){
|
||||||
return cons -> {
|
return cons -> {
|
||||||
for(BuildRequest request : player.builder().requests()) cons.get(request);
|
for(BuildPlan request : player.builder().plans()) cons.get(request);
|
||||||
for(BuildRequest request : selectRequests) cons.get(request);
|
for(BuildPlan request : selectRequests) cons.get(request);
|
||||||
for(BuildRequest request : lineRequests) cons.get(request);
|
for(BuildPlan request : lineRequests) cons.get(request);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
Drawf.selected(x, y, block, color);
|
Drawf.selected(x, y, block, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawBreaking(BuildRequest request){
|
public void drawBreaking(BuildPlan request){
|
||||||
if(request.breaking){
|
if(request.breaking){
|
||||||
drawBreaking(request.x, request.y);
|
drawBreaking(request.x, request.y);
|
||||||
}else{
|
}else{
|
||||||
@@ -325,7 +325,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requestMatches(BuildRequest request){
|
public boolean requestMatches(BuildPlan request){
|
||||||
Tile tile = world.tile(request.x, request.y);
|
Tile tile = world.tile(request.x, request.y);
|
||||||
return tile != null && tile.block() instanceof BuildBlock && tile.<BuildEntity>ent().cblock == request.block;
|
return tile != null && tile.block() instanceof BuildBlock && tile.<BuildEntity>ent().cblock == request.block;
|
||||||
}
|
}
|
||||||
@@ -362,7 +362,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rotateRequests(Seq<BuildRequest> requests, int direction){
|
public void rotateRequests(Seq<BuildPlan> requests, int direction){
|
||||||
int ox = schemOriginX(), oy = schemOriginY();
|
int ox = schemOriginX(), oy = schemOriginY();
|
||||||
|
|
||||||
requests.each(req -> {
|
requests.each(req -> {
|
||||||
@@ -396,7 +396,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flipRequests(Seq<BuildRequest> requests, boolean x){
|
public void flipRequests(Seq<BuildPlan> requests, boolean x){
|
||||||
int origin = (x ? schemOriginX() : schemOriginY()) * tilesize;
|
int origin = (x ? schemOriginX() : schemOriginY()) * tilesize;
|
||||||
|
|
||||||
requests.each(req -> {
|
requests.each(req -> {
|
||||||
@@ -436,18 +436,18 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the selection request that overlaps this position, or null. */
|
/** Returns the selection request that overlaps this position, or null. */
|
||||||
protected BuildRequest getRequest(int x, int y){
|
protected BuildPlan getRequest(int x, int y){
|
||||||
return getRequest(x, y, 1, null);
|
return getRequest(x, y, 1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the selection request that overlaps this position, or null. */
|
/** Returns the selection request that overlaps this position, or null. */
|
||||||
protected BuildRequest getRequest(int x, int y, int size, BuildRequest skip){
|
protected BuildPlan getRequest(int x, int y, int size, BuildPlan skip){
|
||||||
float offset = ((size + 1) % 2) * tilesize / 2f;
|
float offset = ((size + 1) % 2) * tilesize / 2f;
|
||||||
r2.setSize(tilesize * size);
|
r2.setSize(tilesize * size);
|
||||||
r2.setCenter(x * tilesize + offset, y * tilesize + offset);
|
r2.setCenter(x * tilesize + offset, y * tilesize + offset);
|
||||||
resultreq = null;
|
resultreq = null;
|
||||||
|
|
||||||
Boolf<BuildRequest> test = req -> {
|
Boolf<BuildPlan> test = req -> {
|
||||||
if(req == skip) return false;
|
if(req == skip) return false;
|
||||||
Tile other = req.tile();
|
Tile other = req.tile();
|
||||||
|
|
||||||
@@ -464,11 +464,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
return r2.overlaps(r1);
|
return r2.overlaps(r1);
|
||||||
};
|
};
|
||||||
|
|
||||||
for(BuildRequest req : player.builder().requests()){
|
for(BuildPlan req : player.builder().plans()){
|
||||||
if(test.get(req)) return req;
|
if(test.get(req)) return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(BuildRequest req : selectRequests){
|
for(BuildPlan req : selectRequests){
|
||||||
if(test.get(req)) return req;
|
if(test.get(req)) return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,14 +493,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
Draw.color(Pal.remove);
|
Draw.color(Pal.remove);
|
||||||
Lines.stroke(1f);
|
Lines.stroke(1f);
|
||||||
|
|
||||||
for(BuildRequest req : player.builder().requests()){
|
for(BuildPlan req : player.builder().plans()){
|
||||||
if(req.breaking) continue;
|
if(req.breaking) continue;
|
||||||
if(req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
if(req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
||||||
drawBreaking(req);
|
drawBreaking(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(BuildRequest req : selectRequests){
|
for(BuildPlan req : selectRequests){
|
||||||
if(req.breaking) continue;
|
if(req.breaking) continue;
|
||||||
if(req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
if(req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
||||||
drawBreaking(req);
|
drawBreaking(req);
|
||||||
@@ -533,10 +533,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
|
Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void flushSelectRequests(Seq<BuildRequest> requests){
|
protected void flushSelectRequests(Seq<BuildPlan> requests){
|
||||||
for(BuildRequest req : requests){
|
for(BuildPlan req : requests){
|
||||||
if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){
|
if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){
|
||||||
BuildRequest other = getRequest(req.x, req.y, req.block.size, null);
|
BuildPlan other = getRequest(req.x, req.y, req.block.size, null);
|
||||||
if(other == null){
|
if(other == null){
|
||||||
selectRequests.add(req.copy());
|
selectRequests.add(req.copy());
|
||||||
}else if(!other.breaking && other.x == req.x && other.y == req.y && other.block.size == req.block.size){
|
}else if(!other.breaking && other.x == req.x && other.y == req.y && other.block.size == req.block.size){
|
||||||
@@ -547,16 +547,16 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void flushRequests(Seq<BuildRequest> requests){
|
protected void flushRequests(Seq<BuildPlan> requests){
|
||||||
for(BuildRequest req : requests){
|
for(BuildPlan req : requests){
|
||||||
if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){
|
if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){
|
||||||
BuildRequest copy = req.copy();
|
BuildPlan copy = req.copy();
|
||||||
player.builder().addBuild(copy);
|
player.builder().addBuild(copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void drawOverRequest(BuildRequest request){
|
protected void drawOverRequest(BuildPlan request){
|
||||||
boolean valid = validPlace(request.x, request.y, request.block, request.rotation);
|
boolean valid = validPlace(request.x, request.y, request.block, request.rotation);
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
@@ -566,7 +566,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void drawRequest(BuildRequest request){
|
protected void drawRequest(BuildPlan request){
|
||||||
request.block.drawRequest(request, allRequests(), validPlace(request.x, request.y, request.block, request.rotation));
|
request.block.drawRequest(request, allRequests(), validPlace(request.x, request.y, request.block, request.rotation));
|
||||||
|
|
||||||
if(request.block.saveConfig && request.block.lastConfig != null && !request.hasConfig){
|
if(request.block.saveConfig && request.block.lastConfig != null && !request.hasConfig){
|
||||||
@@ -604,7 +604,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
if(!flush){
|
if(!flush){
|
||||||
tryBreakBlock(wx, wy);
|
tryBreakBlock(wx, wy);
|
||||||
}else if(validBreak(tile.x, tile.y) && !selectRequests.contains(r -> r.tile() != null && r.tile() == tile)){
|
}else if(validBreak(tile.x, tile.y) && !selectRequests.contains(r -> r.tile() != null && r.tile() == tile)){
|
||||||
selectRequests.add(new BuildRequest(tile.x, tile.y));
|
selectRequests.add(new BuildPlan(tile.x, tile.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -612,9 +612,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
//remove build requests
|
//remove build requests
|
||||||
Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize);
|
Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize);
|
||||||
|
|
||||||
Iterator<BuildRequest> it = player.builder().requests().iterator();
|
Iterator<BuildPlan> it = player.builder().plans().iterator();
|
||||||
while(it.hasNext()){
|
while(it.hasNext()){
|
||||||
BuildRequest req = it.next();
|
BuildPlan req = it.next();
|
||||||
if(!req.breaking && req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
if(!req.breaking && req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
@@ -622,7 +622,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
it = selectRequests.iterator();
|
it = selectRequests.iterator();
|
||||||
while(it.hasNext()){
|
while(it.hasNext()){
|
||||||
BuildRequest req = it.next();
|
BuildPlan req = it.next();
|
||||||
if(!req.breaking && req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
if(!req.breaking && req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
@@ -643,7 +643,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
lineRequests.clear();
|
lineRequests.clear();
|
||||||
iterateLine(x1, y1, x2, y2, l -> {
|
iterateLine(x1, y1, x2, y2, l -> {
|
||||||
rotation = l.rotation;
|
rotation = l.rotation;
|
||||||
BuildRequest req = new BuildRequest(l.x, l.y, l.rotation, block);
|
BuildPlan req = new BuildPlan(l.x, l.y, l.rotation, block);
|
||||||
req.animScale = 1f;
|
req.animScale = 1f;
|
||||||
lineRequests.add(req);
|
lineRequests.add(req);
|
||||||
});
|
});
|
||||||
@@ -898,8 +898,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
return validPlace(x, y, type, rotation, null);
|
return validPlace(x, y, type, rotation, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validPlace(int x, int y, Block type, int rotation, BuildRequest ignore){
|
public boolean validPlace(int x, int y, Block type, int rotation, BuildPlan ignore){
|
||||||
for(BuildRequest req : player.builder().requests()){
|
for(BuildPlan req : player.builder().plans()){
|
||||||
if(req != ignore
|
if(req != ignore
|
||||||
&& !req.breaking
|
&& !req.breaking
|
||||||
&& req.block.bounds(req.x, req.y, Tmp.r1).overlaps(type.bounds(x, y, Tmp.r2))
|
&& req.block.bounds(req.x, req.y, Tmp.r1).overlaps(type.bounds(x, y, Tmp.r2))
|
||||||
@@ -915,18 +915,18 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void placeBlock(int x, int y, Block block, int rotation){
|
public void placeBlock(int x, int y, Block block, int rotation){
|
||||||
BuildRequest req = getRequest(x, y);
|
BuildPlan req = getRequest(x, y);
|
||||||
if(req != null){
|
if(req != null){
|
||||||
player.builder().requests().remove(req);
|
player.builder().plans().remove(req);
|
||||||
}
|
}
|
||||||
player.builder().addBuild(new BuildRequest(x, y, rotation, block));
|
player.builder().addBuild(new BuildPlan(x, y, rotation, block));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void breakBlock(int x, int y){
|
public void breakBlock(int x, int y){
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.tile(x, y);
|
||||||
//TODO hacky
|
//TODO hacky
|
||||||
if(tile != null && tile.entity != null) tile = tile.entity.tile();
|
if(tile != null && tile.entity != null) tile = tile.entity.tile();
|
||||||
player.builder().addBuild(new BuildRequest(tile.x, tile.y));
|
player.builder().addBuild(new BuildPlan(tile.x, tile.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawArrow(Block block, int x, int y, int rotation){
|
public void drawArrow(Block block, int x, int y, int rotation){
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
private float shiftDeltaX, shiftDeltaY;
|
private float shiftDeltaX, shiftDeltaY;
|
||||||
|
|
||||||
/** Place requests to be removed. */
|
/** Place requests to be removed. */
|
||||||
private Seq<BuildRequest> removals = new Seq<>();
|
private Seq<BuildPlan> removals = new Seq<>();
|
||||||
/** Whether or not the player is currently shifting all placed tiles. */
|
/** Whether or not the player is currently shifting all placed tiles. */
|
||||||
private boolean selecting;
|
private boolean selecting;
|
||||||
/** Whether the player is currently in line-place mode. */
|
/** Whether the player is currently in line-place mode. */
|
||||||
@@ -58,7 +58,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
/** Whether no recipe was available when switching to break mode. */
|
/** Whether no recipe was available when switching to break mode. */
|
||||||
private Block lastBlock;
|
private Block lastBlock;
|
||||||
/** Last placed request. Used for drawing block overlay. */
|
/** Last placed request. Used for drawing block overlay. */
|
||||||
private BuildRequest lastPlaced;
|
private BuildPlan lastPlaced;
|
||||||
/** Down tracking for panning.*/
|
/** Down tracking for panning.*/
|
||||||
private boolean down = false;
|
private boolean down = false;
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
r2.setSize(block.size * tilesize);
|
r2.setSize(block.size * tilesize);
|
||||||
r2.setCenter(x * tilesize + block.offset(), y * tilesize + block.offset());
|
r2.setCenter(x * tilesize + block.offset(), y * tilesize + block.offset());
|
||||||
|
|
||||||
for(BuildRequest req : selectRequests){
|
for(BuildPlan req : selectRequests){
|
||||||
Tile other = req.tile();
|
Tile other = req.tile();
|
||||||
|
|
||||||
if(other == null || req.breaking) continue;
|
if(other == null || req.breaking) continue;
|
||||||
@@ -110,7 +110,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(BuildRequest req : player.builder().requests()){
|
for(BuildPlan req : player.builder().plans()){
|
||||||
Tile other = world.tile(req.x, req.y);
|
Tile other = world.tile(req.x, req.y);
|
||||||
|
|
||||||
if(other == null || req.breaking) continue;
|
if(other == null || req.breaking) continue;
|
||||||
@@ -126,11 +126,11 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the selection request that overlaps this tile, or null. */
|
/** Returns the selection request that overlaps this tile, or null. */
|
||||||
BuildRequest getRequest(Tile tile){
|
BuildPlan getRequest(Tile tile){
|
||||||
r2.setSize(tilesize);
|
r2.setSize(tilesize);
|
||||||
r2.setCenter(tile.worldx(), tile.worldy());
|
r2.setCenter(tile.worldx(), tile.worldy());
|
||||||
|
|
||||||
for(BuildRequest req : selectRequests){
|
for(BuildPlan req : selectRequests){
|
||||||
Tile other = req.tile();
|
Tile other = req.tile();
|
||||||
|
|
||||||
if(other == null) continue;
|
if(other == null) continue;
|
||||||
@@ -149,7 +149,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeRequest(BuildRequest request){
|
void removeRequest(BuildPlan request){
|
||||||
selectRequests.remove(request, true);
|
selectRequests.remove(request, true);
|
||||||
if(!request.breaking){
|
if(!request.breaking){
|
||||||
removals.add(request);
|
removals.add(request);
|
||||||
@@ -204,20 +204,20 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
//confirm button
|
//confirm button
|
||||||
table.button(Icon.ok, Styles.clearPartiali, () -> {
|
table.button(Icon.ok, Styles.clearPartiali, () -> {
|
||||||
for(BuildRequest request : selectRequests){
|
for(BuildPlan request : selectRequests){
|
||||||
Tile tile = request.tile();
|
Tile tile = request.tile();
|
||||||
|
|
||||||
//actually place/break all selected blocks
|
//actually place/break all selected blocks
|
||||||
if(tile != null){
|
if(tile != null){
|
||||||
if(!request.breaking){
|
if(!request.breaking){
|
||||||
if(validPlace(request.x, request.y, request.block, request.rotation)){
|
if(validPlace(request.x, request.y, request.block, request.rotation)){
|
||||||
BuildRequest other = getRequest(request.x, request.y, request.block.size, null);
|
BuildPlan other = getRequest(request.x, request.y, request.block.size, null);
|
||||||
BuildRequest copy = request.copy();
|
BuildPlan copy = request.copy();
|
||||||
|
|
||||||
if(other == null){
|
if(other == null){
|
||||||
player.builder().addBuild(copy);
|
player.builder().addBuild(copy);
|
||||||
}else if(!other.breaking && other.x == request.x && other.y == request.y && other.block.size == request.block.size){
|
}else if(!other.breaking && other.x == request.x && other.y == request.y && other.block.size == request.block.size){
|
||||||
player.builder().requests().remove(other);
|
player.builder().plans().remove(other);
|
||||||
player.builder().addBuild(copy);
|
player.builder().addBuild(copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,7 +278,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
Lines.stroke(1f);
|
Lines.stroke(1f);
|
||||||
|
|
||||||
//draw removals
|
//draw removals
|
||||||
for(BuildRequest request : removals){
|
for(BuildPlan request : removals){
|
||||||
Tile tile = request.tile();
|
Tile tile = request.tile();
|
||||||
|
|
||||||
if(tile == null) continue;
|
if(tile == null) continue;
|
||||||
@@ -293,7 +293,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//draw list of requests
|
//draw list of requests
|
||||||
for(BuildRequest request : selectRequests){
|
for(BuildPlan request : selectRequests){
|
||||||
Tile tile = request.tile();
|
Tile tile = request.tile();
|
||||||
|
|
||||||
if(tile == null) continue;
|
if(tile == null) continue;
|
||||||
@@ -333,7 +333,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
if(mode == placing && block != null){
|
if(mode == placing && block != null){
|
||||||
//draw placing
|
//draw placing
|
||||||
for(int i = 0; i < lineRequests.size; i++){
|
for(int i = 0; i < lineRequests.size; i++){
|
||||||
BuildRequest request = lineRequests.get(i);
|
BuildPlan request = lineRequests.get(i);
|
||||||
if(i == lineRequests.size - 1 && request.block.rotate){
|
if(i == lineRequests.size - 1 && request.block.rotate){
|
||||||
drawArrow(block, request.x, request.y, request.rotation);
|
drawArrow(block, request.x, request.y, request.rotation);
|
||||||
}
|
}
|
||||||
@@ -376,7 +376,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void drawRequest(BuildRequest request){
|
protected void drawRequest(BuildPlan request){
|
||||||
if(request.tile() == null) return;
|
if(request.tile() == null) return;
|
||||||
brequest.animScale = request.animScale = Mathf.lerpDelta(request.animScale, 1f, 0.1f);
|
brequest.animScale = request.animScale = Mathf.lerpDelta(request.animScale, 1f, 0.1f);
|
||||||
|
|
||||||
@@ -551,10 +551,10 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
removeRequest(getRequest(cursor));
|
removeRequest(getRequest(cursor));
|
||||||
}else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, block, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, block)){
|
}else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, block, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, block)){
|
||||||
//add to selection queue if it's a valid place position
|
//add to selection queue if it's a valid place position
|
||||||
selectRequests.add(lastPlaced = new BuildRequest(cursor.x, cursor.y, rotation, block));
|
selectRequests.add(lastPlaced = new BuildPlan(cursor.x, cursor.y, rotation, block));
|
||||||
}else if(mode == breaking && validBreak(linked.x,linked.y) && !hasRequest(linked)){
|
}else if(mode == breaking && validBreak(linked.x,linked.y) && !hasRequest(linked)){
|
||||||
//add to selection queue if it's a valid BREAK position
|
//add to selection queue if it's a valid BREAK position
|
||||||
selectRequests.add(new BuildRequest(linked.x, linked.y));
|
selectRequests.add(new BuildPlan(linked.x, linked.y));
|
||||||
}else if(!canTapPlayer(worldx, worldy) && !tileTapped(linked.entity)){
|
}else if(!canTapPlayer(worldx, worldy) && !tileTapped(linked.entity)){
|
||||||
tryBeginMine(cursor);
|
tryBeginMine(cursor);
|
||||||
}
|
}
|
||||||
@@ -659,7 +659,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
//remove place requests that have disappeared
|
//remove place requests that have disappeared
|
||||||
for(int i = removals.size - 1; i >= 0; i--){
|
for(int i = removals.size - 1; i >= 0; i--){
|
||||||
BuildRequest request = removals.get(i);
|
BuildPlan request = removals.get(i);
|
||||||
|
|
||||||
if(request.animScale <= 0.0001f){
|
if(request.animScale <= 0.0001f){
|
||||||
removals.remove(i);
|
removals.remove(i);
|
||||||
@@ -720,7 +720,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
int shiftedY = (int)(shiftDeltaY / tilesize);
|
int shiftedY = (int)(shiftDeltaY / tilesize);
|
||||||
|
|
||||||
if(Math.abs(shiftedX) > 0 || Math.abs(shiftedY) > 0){
|
if(Math.abs(shiftedX) > 0 || Math.abs(shiftedY) > 0){
|
||||||
for(BuildRequest req : selectRequests){
|
for(BuildPlan req : selectRequests){
|
||||||
if(req.breaking) continue; //don't shift removal requests
|
if(req.breaking) continue; //don't shift removal requests
|
||||||
req.x += shiftedX;
|
req.x += shiftedX;
|
||||||
req.y += shiftedY;
|
req.y += shiftedY;
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ public class TypeIO{
|
|||||||
return content.block(read.s());
|
return content.block(read.s());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeRequest(Writes write, BuildRequest request){
|
public static void writeRequest(Writes write, BuildPlan request){
|
||||||
write.b(request.breaking ? (byte)1 : 0);
|
write.b(request.breaking ? (byte)1 : 0);
|
||||||
write.i(Point2.pack(request.x, request.y));
|
write.i(Point2.pack(request.x, request.y));
|
||||||
if(!request.breaking){
|
if(!request.breaking){
|
||||||
@@ -165,8 +165,8 @@ public class TypeIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BuildRequest readRequest(Reads read){
|
public static BuildPlan readRequest(Reads read){
|
||||||
BuildRequest currentRequest;
|
BuildPlan currentRequest;
|
||||||
|
|
||||||
byte type = read.b();
|
byte type = read.b();
|
||||||
int position = read.i();
|
int position = read.i();
|
||||||
@@ -176,13 +176,13 @@ public class TypeIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(type == 1){ //remove
|
if(type == 1){ //remove
|
||||||
currentRequest = new BuildRequest(Point2.x(position), Point2.y(position));
|
currentRequest = new BuildPlan(Point2.x(position), Point2.y(position));
|
||||||
}else{ //place
|
}else{ //place
|
||||||
short block = read.s();
|
short block = read.s();
|
||||||
byte rotation = read.b();
|
byte rotation = read.b();
|
||||||
boolean hasConfig = read.b() == 1;
|
boolean hasConfig = read.b() == 1;
|
||||||
Object config = readObject(read);
|
Object config = readObject(read);
|
||||||
currentRequest = new BuildRequest(Point2.x(position), Point2.y(position), rotation, content.block(block));
|
currentRequest = new BuildPlan(Point2.x(position), Point2.y(position), rotation, content.block(block));
|
||||||
if(hasConfig){
|
if(hasConfig){
|
||||||
currentRequest.configure(config);
|
currentRequest.configure(config);
|
||||||
}
|
}
|
||||||
@@ -191,26 +191,26 @@ public class TypeIO{
|
|||||||
return currentRequest;
|
return currentRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeRequests(Writes write, BuildRequest[] requests){
|
public static void writeRequests(Writes write, BuildPlan[] requests){
|
||||||
if(requests == null){
|
if(requests == null){
|
||||||
write.s(-1);
|
write.s(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
write.s((short)requests.length);
|
write.s((short)requests.length);
|
||||||
for(BuildRequest request : requests){
|
for(BuildPlan request : requests){
|
||||||
writeRequest(write, request);
|
writeRequest(write, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BuildRequest[] readRequests(Reads read){
|
public static BuildPlan[] readRequests(Reads read){
|
||||||
short reqamount = read.s();
|
short reqamount = read.s();
|
||||||
if(reqamount == -1){
|
if(reqamount == -1){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildRequest[] reqs = new BuildRequest[reqamount];
|
BuildPlan[] reqs = new BuildPlan[reqamount];
|
||||||
for(int i = 0; i < reqamount; i++){
|
for(int i = 0; i < reqamount; i++){
|
||||||
BuildRequest request = readRequest(read);
|
BuildPlan request = readRequest(read);
|
||||||
if(request != null){
|
if(request != null){
|
||||||
reqs[i] = request;
|
reqs[i] = request;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public abstract class NetConnection{
|
|||||||
/** Timestamp of last recieved snapshot. */
|
/** Timestamp of last recieved snapshot. */
|
||||||
public long lastRecievedClientTime;
|
public long lastRecievedClientTime;
|
||||||
/** Build requests that have been recently rejected. This is cleared every snapshot. */
|
/** Build requests that have been recently rejected. This is cleared every snapshot. */
|
||||||
public Seq<BuildRequest> rejectedRequests = new Seq<>();
|
public Seq<BuildPlan> rejectedRequests = new Seq<>();
|
||||||
|
|
||||||
public boolean hasConnected, hasBegunConnecting, hasDisconnected;
|
public boolean hasConnected, hasBegunConnecting, hasDisconnected;
|
||||||
public float viewWidth, viewHeight, viewX, viewY;
|
public float viewWidth, viewHeight, viewX, viewY;
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ public class CustomRulesDialog extends BaseDialog{
|
|||||||
|
|
||||||
title("$rules.title.enemy");
|
title("$rules.title.enemy");
|
||||||
check("$rules.attack", b -> rules.attackMode = b, () -> rules.attackMode);
|
check("$rules.attack", b -> rules.attackMode = b, () -> rules.attackMode);
|
||||||
check("$rules.enemyCheat", b -> rules.enemyCheat = b, () -> rules.enemyCheat);
|
|
||||||
number("$rules.enemycorebuildradius", f -> rules.enemyCoreBuildRadius = f * tilesize, () -> Math.min(rules.enemyCoreBuildRadius / tilesize, 200));
|
number("$rules.enemycorebuildradius", f -> rules.enemyCoreBuildRadius = f * tilesize, () -> Math.min(rules.enemyCoreBuildRadius / tilesize, 200));
|
||||||
|
|
||||||
title("$rules.title.environment");
|
title("$rules.title.environment");
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ public class SchematicsDialog extends BaseDialog{
|
|||||||
for(ItemStack s : arr){
|
for(ItemStack s : arr){
|
||||||
r.image(s.item.icon(Cicon.small)).left();
|
r.image(s.item.icon(Cicon.small)).left();
|
||||||
r.label(() -> {
|
r.label(() -> {
|
||||||
Tilec core = player.closestCore();
|
Tilec core = player.core();
|
||||||
if(core == null || state.rules.infiniteResources || core.items().has(s.item, s.amount)) return "[lightgray]" + s.amount + "";
|
if(core == null || state.rules.infiniteResources || core.items().has(s.item, s.amount)) return "[lightgray]" + s.amount + "";
|
||||||
return (core.items().has(s.item, s.amount) ? "[lightgray]" : "[scarlet]") + Math.min(core.items().get(s.item), s.amount) + "[lightgray]/" + s.amount;
|
return (core.items().has(s.item, s.amount) ? "[lightgray]" : "[scarlet]") + Math.min(core.items().get(s.item), s.amount) + "[lightgray]/" + s.amount;
|
||||||
}).padLeft(2).left().padRight(4);
|
}).padLeft(2).left().padRight(4);
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class PlacementFragment extends Fragment{
|
|||||||
Block tryRecipe = tile == null ? null : tile.block();
|
Block tryRecipe = tile == null ? null : tile.block();
|
||||||
Object tryConfig = tile == null ? null : tile.config();
|
Object tryConfig = tile == null ? null : tile.config();
|
||||||
|
|
||||||
for(BuildRequest req : player.builder().requests()){
|
for(BuildPlan req : player.builder().plans()){
|
||||||
if(!req.breaking && req.block.bounds(req.x, req.y, Tmp.r1).contains(Core.input.mouseWorld())){
|
if(!req.breaking && req.block.bounds(req.x, req.y, Tmp.r1).contains(Core.input.mouseWorld())){
|
||||||
tryRecipe = req.block;
|
tryRecipe = req.block;
|
||||||
tryConfig = req.config;
|
tryConfig = req.config;
|
||||||
@@ -222,7 +222,7 @@ public class PlacementFragment extends Fragment{
|
|||||||
button.resizeImage(Cicon.medium.size);
|
button.resizeImage(Cicon.medium.size);
|
||||||
|
|
||||||
button.update(() -> { //color unplacable things gray
|
button.update(() -> { //color unplacable things gray
|
||||||
Tilec core = player.closestCore();
|
Tilec core = player.core();
|
||||||
Color color = (state.rules.infiniteResources || (core != null && (core.items().has(block.requirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources))) && player.isBuilder() ? Color.white : Color.gray;
|
Color color = (state.rules.infiniteResources || (core != null && (core.items().has(block.requirements, state.rules.buildCostMultiplier) || state.rules.infiniteResources))) && player.isBuilder() ? Color.white : Color.gray;
|
||||||
button.forEach(elem -> elem.setColor(color));
|
button.forEach(elem -> elem.setColor(color));
|
||||||
button.setChecked(control.input.block == block);
|
button.setChecked(control.input.block == block);
|
||||||
@@ -310,7 +310,7 @@ public class PlacementFragment extends Fragment{
|
|||||||
line.image(stack.item.icon(Cicon.small)).size(8 * 2);
|
line.image(stack.item.icon(Cicon.small)).size(8 * 2);
|
||||||
line.add(stack.item.localizedName).maxWidth(140f).fillX().color(Color.lightGray).padLeft(2).left().get().setEllipsis(true);
|
line.add(stack.item.localizedName).maxWidth(140f).fillX().color(Color.lightGray).padLeft(2).left().get().setEllipsis(true);
|
||||||
line.labelWrap(() -> {
|
line.labelWrap(() -> {
|
||||||
Tilec core = player.closestCore();
|
Tilec core = player.core();
|
||||||
if(core == null || state.rules.infiniteResources) return "*/*";
|
if(core == null || state.rules.infiniteResources) return "*/*";
|
||||||
|
|
||||||
int amount = core.items().get(stack.item);
|
int amount = core.items().get(stack.item);
|
||||||
|
|||||||
@@ -342,11 +342,11 @@ public class Block extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return a possible replacement for this block when placed in a line by the player. */
|
/** @return a possible replacement for this block when placed in a line by the player. */
|
||||||
public Block getReplacement(BuildRequest req, Seq<BuildRequest> requests){
|
public Block getReplacement(BuildPlan req, Seq<BuildPlan> requests){
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawRequest(BuildRequest req, Eachable<BuildRequest> list, boolean valid){
|
public void drawRequest(BuildPlan req, Eachable<BuildPlan> list, boolean valid){
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime(), 6f, 0.28f));
|
Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime(), 6f, 0.28f));
|
||||||
Draw.alpha(1f);
|
Draw.alpha(1f);
|
||||||
@@ -357,7 +357,7 @@ public class Block extends UnlockableContent{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
TextureRegion reg = getRequestRegion(req, list);
|
TextureRegion reg = getRequestRegion(req, list);
|
||||||
Draw.rect(reg, req.drawx(), req.drawy(), !rotate ? 0 : req.rotation * 90);
|
Draw.rect(reg, req.drawx(), req.drawy(), !rotate ? 0 : req.rotation * 90);
|
||||||
|
|
||||||
@@ -366,15 +366,15 @@ public class Block extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureRegion getRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public TextureRegion getRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
return icon(Cicon.full);
|
return icon(Cicon.full);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawRequestConfigCenter(BuildRequest req, Object content, String region){
|
public void drawRequestConfigCenter(BuildPlan req, Object content, String region){
|
||||||
Color color = content instanceof Item ? ((Item)content).color : content instanceof Liquid ? ((Liquid)content).color : null;
|
Color color = content instanceof Item ? ((Item)content).color : content instanceof Liquid ? ((Liquid)content).color : null;
|
||||||
if(color == null) return;
|
if(color == null) return;
|
||||||
|
|
||||||
@@ -383,7 +383,7 @@ public class Block extends UnlockableContent{
|
|||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawRequestConfigTop(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -346,10 +346,6 @@ public class Tile implements Position, QuadTreeObject{
|
|||||||
return block.destructible || block.breakable || block.update;
|
return block.destructible || block.breakable || block.update;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnemyCheat(){
|
|
||||||
return team() == state.rules.waveTeam && state.rules.enemyCheat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of all tiles linked to this multiblock, or just itself if it's not a multiblock.
|
* Returns the list of all tiles linked to this multiblock, or just itself if it's not a multiblock.
|
||||||
* This array contains all linked tiles, including this tile itself.
|
* This array contains all linked tiles, including this tile itself.
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public interface Autotiler{
|
|||||||
//holds some static temporary variables, required due to some RoboVM bugs
|
//holds some static temporary variables, required due to some RoboVM bugs
|
||||||
class AutotilerHolder{
|
class AutotilerHolder{
|
||||||
static final int[] blendresult = new int[5];
|
static final int[] blendresult = new int[5];
|
||||||
static final BuildRequest[] directionals = new BuildRequest[4];
|
static final BuildPlan[] directionals = new BuildPlan[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** slices a texture region:
|
/** slices a texture region:
|
||||||
@@ -44,9 +44,9 @@ public interface Autotiler{
|
|||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
default @Nullable int[] getTiling(BuildRequest req, Eachable<BuildRequest> list){
|
default @Nullable int[] getTiling(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
if(req.tile() == null) return null;
|
if(req.tile() == null) return null;
|
||||||
BuildRequest[] directionals = AutotilerHolder.directionals;
|
BuildPlan[] directionals = AutotilerHolder.directionals;
|
||||||
|
|
||||||
Arrays.fill(directionals, null);
|
Arrays.fill(directionals, null);
|
||||||
list.each(other -> {
|
list.each(other -> {
|
||||||
@@ -78,7 +78,7 @@ public interface Autotiler{
|
|||||||
* [3]: a 4-bit mask with bits 0-3 indicating blend state in that direction (0 being 0 degrees, 1 being 90, etc)
|
* [3]: a 4-bit mask with bits 0-3 indicating blend state in that direction (0 being 0 degrees, 1 being 90, etc)
|
||||||
* [4]: same as [3] but only blends with non-square sprites
|
* [4]: same as [3] but only blends with non-square sprites
|
||||||
* */
|
* */
|
||||||
default int[] buildBlending(Tile tile, int rotation, BuildRequest[] directional, boolean world){
|
default int[] buildBlending(Tile tile, int rotation, BuildPlan[] directional, boolean world){
|
||||||
int[] blendresult = AutotilerHolder.blendresult;
|
int[] blendresult = AutotilerHolder.blendresult;
|
||||||
blendresult[0] = 0;
|
blendresult[0] = 0;
|
||||||
blendresult[1] = blendresult[2] = 1;
|
blendresult[1] = blendresult[2] = 1;
|
||||||
@@ -134,10 +134,10 @@ public interface Autotiler{
|
|||||||
return Point2.equals(x + Geometry.d4(rotation).x,y + Geometry.d4(rotation).y, x2, y2);
|
return Point2.equals(x + Geometry.d4(rotation).x,y + Geometry.d4(rotation).y, x2, y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean blends(Tile tile, int rotation, @Nullable BuildRequest[] directional, int direction, boolean checkWorld){
|
default boolean blends(Tile tile, int rotation, @Nullable BuildPlan[] directional, int direction, boolean checkWorld){
|
||||||
int realDir = Mathf.mod(rotation - direction, 4);
|
int realDir = Mathf.mod(rotation - direction, 4);
|
||||||
if(directional != null && directional[realDir] != null){
|
if(directional != null && directional[realDir] != null){
|
||||||
BuildRequest req = directional[realDir];
|
BuildPlan req = directional[realDir];
|
||||||
if(blends(tile, rotation, req.x, req.y, req.rotation, req.block)){
|
if(blends(tile, rotation, req.x, req.y, req.rotation, req.block)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ public class BuildBlock extends Block{
|
|||||||
if(control.input.buildWasAutoPaused && !control.input.isBuilding && player.isBuilder()){
|
if(control.input.buildWasAutoPaused && !control.input.isBuilding && player.isBuilder()){
|
||||||
control.input.isBuilding = true;
|
control.input.isBuilding = true;
|
||||||
}
|
}
|
||||||
player.builder().addBuild(new BuildRequest(tile.x, tile.y, tile.rotation(), cblock), false);
|
player.builder().addBuild(new BuildPlan(tile.x, tile.y, tile.rotation(), cblock), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class Door extends Wall{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextureRegion getRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public TextureRegion getRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
return req.config == Boolean.TRUE ? openRegion : region;
|
return req.config == Boolean.TRUE ? openRegion : region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class MendProjector extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
heat = Mathf.lerpDelta(heat, consValid() || tile.isEnemyCheat() ? 1f : 0f, 0.08f);
|
heat = Mathf.lerpDelta(heat, consValid() || cheating() ? 1f : 0f, 0.08f);
|
||||||
charge += heat * delta();
|
charge += heat * delta();
|
||||||
|
|
||||||
phaseHeat = Mathf.lerpDelta(phaseHeat, Mathf.num(cons().optionalValid()), 0.1f);
|
phaseHeat = Mathf.lerpDelta(phaseHeat, Mathf.num(cons().optionalValid()), 0.1f);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class ItemTurret extends Turret{
|
|||||||
super.onProximityAdded();
|
super.onProximityAdded();
|
||||||
|
|
||||||
//add first ammo item to cheaty blocks so they can shoot properly
|
//add first ammo item to cheaty blocks so they can shoot properly
|
||||||
if(tile.isEnemyCheat() && ammo.size > 0){
|
if(cheating() && ammo.size > 0){
|
||||||
handleItem(this, ammoTypes.entries().next().key);
|
handleItem(this, ammoTypes.entries().next().key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class LaserTurret extends PowerTurret{
|
|||||||
Liquid liquid = liquids().current();
|
Liquid liquid = liquids().current();
|
||||||
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
|
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
|
||||||
|
|
||||||
float used = (tile.isEnemyCheat() ? maxUsed * Time.delta() : Math.min(liquids.get(liquid), maxUsed * Time.delta())) * liquid.heatCapacity * coolantMultiplier;
|
float used = (cheating() ? maxUsed * Time.delta() : Math.min(liquids.get(liquid), maxUsed * Time.delta())) * liquid.heatCapacity * coolantMultiplier;
|
||||||
reload -= used;
|
reload -= used;
|
||||||
liquids.remove(liquid, used);
|
liquids.remove(liquid, used);
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ public class LaserTurret extends PowerTurret{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(reload <= 0 && (consValid() || tile.isEnemyCheat())){
|
if(reload <= 0 && (consValid() || cheating())){
|
||||||
BulletType type = peekAmmo();
|
BulletType type = peekAmmo();
|
||||||
|
|
||||||
shoot(type);
|
shoot(type);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public class LiquidTurret extends Turret{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BulletType useAmmo(){
|
public BulletType useAmmo(){
|
||||||
if(tile.isEnemyCheat()) return ammoTypes.get(liquids.current());
|
if(cheating()) return ammoTypes.get(liquids.current());
|
||||||
BulletType type = ammoTypes.get(liquids.current());
|
BulletType type = ammoTypes.get(liquids.current());
|
||||||
liquids.remove(liquids.current(), type.ammoMultiplier);
|
liquids.remove(liquids.current(), type.ammoMultiplier);
|
||||||
return type;
|
return type;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class PowerTurret extends Turret{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float baseReloadSpeed(){
|
protected float baseReloadSpeed(){
|
||||||
return tile.isEnemyCheat() ? 1f : power.status;
|
return cheating() ? 1f : power.status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ public abstract class Turret extends Block{
|
|||||||
|
|
||||||
/** Consume ammo and return a type. */
|
/** Consume ammo and return a type. */
|
||||||
public BulletType useAmmo(){
|
public BulletType useAmmo(){
|
||||||
if(tile.isEnemyCheat()) return peekAmmo();
|
if(cheating()) return peekAmmo();
|
||||||
|
|
||||||
AmmoEntry entry = ammo.peek();
|
AmmoEntry entry = ammo.peek();
|
||||||
entry.amount -= ammoPerShot;
|
entry.amount -= ammoPerShot;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
int[] bits = getTiling(req, list);
|
int[] bits = getTiling(req, list);
|
||||||
|
|
||||||
if(bits == null) return;
|
if(bits == null) return;
|
||||||
@@ -81,7 +81,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Block getReplacement(BuildRequest req, Seq<BuildRequest> requests){
|
public Block getReplacement(BuildPlan req, Seq<BuildPlan> requests){
|
||||||
Boolf<Point2> cont = p -> requests.contains(o -> o.x == req.x + p.x && o.y == req.y + p.y && o.rotation == req.rotation && (req.block instanceof Conveyor || req.block instanceof Junction));
|
Boolf<Point2> cont = p -> requests.contains(o -> o.x == req.x + p.x && o.y == req.y + p.y && o.rotation == req.rotation && (req.block instanceof Conveyor || req.block instanceof Junction));
|
||||||
return cont.get(Geometry.d4(req.rotation)) &&
|
return cont.get(Geometry.d4(req.rotation)) &&
|
||||||
cont.get(Geometry.d4(req.rotation - 2)) &&
|
cont.get(Geometry.d4(req.rotation - 2)) &&
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import mindustry.world.meta.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class ItemBridge extends Block{
|
public class ItemBridge extends Block{
|
||||||
private static BuildRequest otherReq;
|
private static BuildPlan otherReq;
|
||||||
|
|
||||||
public final int timerTransport = timers++;
|
public final int timerTransport = timers++;
|
||||||
public int range;
|
public int range;
|
||||||
@@ -50,7 +50,7 @@ public class ItemBridge extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestConfigTop(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
otherReq = null;
|
otherReq = null;
|
||||||
list.each(other -> {
|
list.each(other -> {
|
||||||
if(other.block == this && req != other && req.config instanceof Point2 && ((Point2)req.config).equals(other.x - req.x, other.y - req.y)){
|
if(other.block == this && req != other && req.config instanceof Point2 && ((Point2)req.config).equals(other.x - req.x, other.y - req.y)){
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class PayloadRouter extends PayloadConveyor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
super.drawRequestRegion(req, list);
|
super.drawRequestRegion(req, list);
|
||||||
|
|
||||||
Draw.rect(overRegion, req.drawx(), req.drawy());
|
Draw.rect(overRegion, req.drawx(), req.drawy());
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class Sorter extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
drawRequestConfigCenter(req, req.config, "center");
|
drawRequestConfigCenter(req, req.config, "center");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class StackConveyor extends Block implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
int[] bits = getTiling(req, list);
|
int[] bits = getTiling(req, list);
|
||||||
|
|
||||||
if(bits == null) return;
|
if(bits == null) return;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class BlockForge extends PayloadAcceptor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
Draw.rect(region, req.drawx(), req.drawy());
|
Draw.rect(region, req.drawx(), req.drawy());
|
||||||
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class BlockLoader extends PayloadAcceptor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
Draw.rect(region, req.drawx(), req.drawy());
|
Draw.rect(region, req.drawx(), req.drawy());
|
||||||
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
||||||
Draw.rect(topRegion, req.drawx(), req.drawy());
|
Draw.rect(topRegion, req.drawx(), req.drawy());
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
int[] bits = getTiling(req, list);
|
int[] bits = getTiling(req, list);
|
||||||
|
|
||||||
if(bits == null) return;
|
if(bits == null) return;
|
||||||
@@ -53,7 +53,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Block getReplacement(BuildRequest req, Seq<BuildRequest> requests){
|
public Block getReplacement(BuildPlan req, Seq<BuildPlan> requests){
|
||||||
Boolf<Point2> cont = p -> requests.contains(o -> o.x == req.x + p.x && o.y == req.y + p.y && o.rotation == req.rotation && (req.block instanceof Conduit || req.block instanceof LiquidJunction));
|
Boolf<Point2> cont = p -> requests.contains(o -> o.x == req.x + p.x && o.y == req.y + p.y && o.rotation == req.rotation && (req.block instanceof Conduit || req.block instanceof LiquidJunction));
|
||||||
return cont.get(Geometry.d4(req.rotation)) &&
|
return cont.get(Geometry.d4(req.rotation)) &&
|
||||||
cont.get(Geometry.d4(req.rotation - 2)) &&
|
cont.get(Geometry.d4(req.rotation - 2)) &&
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class PowerDiode extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
Draw.rect(icon(Cicon.full), req.drawx(), req.drawy());
|
Draw.rect(icon(Cicon.full), req.drawx(), req.drawy());
|
||||||
Draw.rect(arrow, req.drawx(), req.drawy(), !rotate ? 0 : req.rotation * 90);
|
Draw.rect(arrow, req.drawx(), req.drawy(), !rotate ? 0 : req.rotation * 90);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ public class PowerGraph{
|
|||||||
public void update(){
|
public void update(){
|
||||||
if(Core.graphics.getFrameId() == lastFrameUpdated){
|
if(Core.graphics.getFrameId() == lastFrameUpdated){
|
||||||
return;
|
return;
|
||||||
}else if(!consumers.isEmpty() && consumers.first().tile().isEnemyCheat()){
|
}else if(!consumers.isEmpty() && consumers.first().cheating()){
|
||||||
//when cheating, just set status to 1
|
//when cheating, just set status to 1
|
||||||
for(Tilec tile : consumers){
|
for(Tilec tile : consumers){
|
||||||
tile.power().status = 1f;
|
tile.power().status = 1f;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public class PowerNode extends PowerBlock{
|
public class PowerNode extends PowerBlock{
|
||||||
protected static boolean returnValue = false;
|
protected static boolean returnValue = false;
|
||||||
protected static BuildRequest otherReq;
|
protected static BuildPlan otherReq;
|
||||||
|
|
||||||
protected final ObjectSet<PowerGraph> graphs = new ObjectSet<>();
|
protected final ObjectSet<PowerGraph> graphs = new ObjectSet<>();
|
||||||
protected final Vec2 t1 = new Vec2(), t2 = new Vec2();
|
protected final Vec2 t1 = new Vec2(), t2 = new Vec2();
|
||||||
@@ -201,7 +201,7 @@ public class PowerNode extends PowerBlock{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestConfigTop(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
if(req.config instanceof Point2[]){
|
if(req.config instanceof Point2[]){
|
||||||
for(Point2 point : (Point2[])req.config){
|
for(Point2 point : (Point2[])req.config){
|
||||||
otherReq = null;
|
otherReq = null;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class Drill extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestConfigTop(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
if(!req.worldContext) return;
|
if(!req.worldContext) return;
|
||||||
Tile tile = req.tile();
|
Tile tile = req.tile();
|
||||||
if(tile == null) return;
|
if(tile == null) return;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class ItemSource extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
drawRequestConfigCenter(req, req.config, "center");
|
drawRequestConfigCenter(req, req.config, "center");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class LiquidSource extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
drawRequestConfigCenter(req, req.config, "center");
|
drawRequestConfigCenter(req, req.config, "center");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class Unloader extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestConfig(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
drawRequestConfigCenter(req, req.config, "unloader-center");
|
drawRequestConfigCenter(req, req.config, "unloader-center");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class Reconstructor extends UnitBlock{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
Draw.rect(region, req.drawx(), req.drawy());
|
Draw.rect(region, req.drawx(), req.drawy());
|
||||||
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
||||||
Draw.rect(topRegion, req.drawx(), req.drawy());
|
Draw.rect(topRegion, req.drawx(), req.drawy());
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class UnitFactory extends UnitBlock{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||||
Draw.rect(region, req.drawx(), req.drawy());
|
Draw.rect(region, req.drawx(), req.drawy());
|
||||||
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
||||||
Draw.rect(topRegion, req.drawx(), req.drawy());
|
Draw.rect(topRegion, req.drawx(), req.drawy());
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ public class ConsumeModule extends BlockModule{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void update(){
|
public void update(){
|
||||||
//everything is valid here
|
//everything is valid when cheating
|
||||||
if(entity.tile().isEnemyCheat()){
|
if(entity.cheating()){
|
||||||
valid = optionalValid = true;
|
valid = optionalValid = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class SStats implements SteamUserStatsCallback{
|
|||||||
});
|
});
|
||||||
|
|
||||||
Events.on(Trigger.newGame, () -> Core.app.post(() -> {
|
Events.on(Trigger.newGame, () -> Core.app.post(() -> {
|
||||||
if(campaign() && player.closestCore() != null && player.closestCore().items().total() >= 10 * 1000){
|
if(campaign() && player.core() != null && player.core().items().total() >= 10 * 1000){
|
||||||
drop10kitems.complete();
|
drop10kitems.complete();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=a074a6f49cf19f417b40fede82a429dab8c91cc0
|
archash=5c3e9ec21d1b541f3b0e6ecde5f4d468b92efc25
|
||||||
|
|||||||
@@ -492,8 +492,8 @@ public class ApplicationTests{
|
|||||||
d1.set(0f, 0f);
|
d1.set(0f, 0f);
|
||||||
d2.set(20f, 20f);
|
d2.set(20f, 20f);
|
||||||
|
|
||||||
d1.addBuild(new BuildRequest(0, 0, 0, Blocks.copperWallLarge));
|
d1.addBuild(new BuildPlan(0, 0, 0, Blocks.copperWallLarge));
|
||||||
d2.addBuild(new BuildRequest(1, 1, 0, Blocks.copperWallLarge));
|
d2.addBuild(new BuildPlan(1, 1, 0, Blocks.copperWallLarge));
|
||||||
|
|
||||||
d1.update();
|
d1.update();
|
||||||
d2.update();
|
d2.update();
|
||||||
@@ -514,8 +514,8 @@ public class ApplicationTests{
|
|||||||
d1.set(10f, 20f);
|
d1.set(10f, 20f);
|
||||||
d2.set(10f, 20f);
|
d2.set(10f, 20f);
|
||||||
|
|
||||||
d1.addBuild(new BuildRequest(0, 0, 0, Blocks.copperWallLarge));
|
d1.addBuild(new BuildPlan(0, 0, 0, Blocks.copperWallLarge));
|
||||||
d2.addBuild(new BuildRequest(1, 1));
|
d2.addBuild(new BuildPlan(1, 1));
|
||||||
|
|
||||||
Time.setDeltaProvider(() -> 3f);
|
Time.setDeltaProvider(() -> 3f);
|
||||||
d1.update();
|
d1.update();
|
||||||
@@ -532,7 +532,7 @@ public class ApplicationTests{
|
|||||||
assertEquals(Blocks.copperWallLarge, world.tile(1, 1).block());
|
assertEquals(Blocks.copperWallLarge, world.tile(1, 1).block());
|
||||||
|
|
||||||
d2.clearBuilding();
|
d2.clearBuilding();
|
||||||
d2.addBuild(new BuildRequest(1, 1));
|
d2.addBuild(new BuildPlan(1, 1));
|
||||||
d2.update();
|
d2.update();
|
||||||
|
|
||||||
assertEquals(Blocks.air, world.tile(0, 0).block());
|
assertEquals(Blocks.air, world.tile(0, 0).block());
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
|
|
||||||
public class IOTests{
|
public class IOTests{
|
||||||
|
|
||||||
@Test
|
|
||||||
void writeEntities(){
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeEnglish(){
|
void writeEnglish(){
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(500);
|
ByteBuffer buffer = ByteBuffer.allocate(500);
|
||||||
|
|||||||
Reference in New Issue
Block a user