Bugfixes / Removed tile unit multi-mining
This commit is contained in:
@@ -312,6 +312,28 @@ public class BlockIndexer{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Find the closest ore block relative to a position. */
|
||||||
|
public Tile findClosestOre(Unit unit, Item item){
|
||||||
|
if(!(unit instanceof Minerc miner)) return null;
|
||||||
|
|
||||||
|
TileArray arr = getOrePositions(item);
|
||||||
|
|
||||||
|
arr.tiles.sort(t -> t.dst2(unit.x, unit.y));
|
||||||
|
|
||||||
|
for(Tile tile : arr.tiles){
|
||||||
|
for(int x = Math.max(0, tile.x - quadrantSize / 2); x < tile.x + quadrantSize / 2 && x < world.width(); x++){
|
||||||
|
for(int y = Math.max(0, tile.y - quadrantSize / 2); y < tile.y + quadrantSize / 2 && y < world.height(); y++){
|
||||||
|
Tile res = world.tile(x, y);
|
||||||
|
if(res.drop() == item && miner.validMine(res, false)){
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return extra unit cap of a team. This is added onto the base value. */
|
/** @return extra unit cap of a team. This is added onto the base value. */
|
||||||
public int getExtraUnits(Team team){
|
public int getExtraUnits(Team team){
|
||||||
return unitCaps[team.id];
|
return unitCaps[team.id];
|
||||||
@@ -457,8 +479,8 @@ public class BlockIndexer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class TileArray implements Iterable<Tile>{
|
public static class TileArray implements Iterable<Tile>{
|
||||||
private Seq<Tile> tiles = new Seq<>(false, 16);
|
Seq<Tile> tiles = new Seq<>(false, 16);
|
||||||
private IntSet contained = new IntSet();
|
IntSet contained = new IntSet();
|
||||||
|
|
||||||
public void add(Tile tile){
|
public void add(Tile tile){
|
||||||
if(contained.add(tile.pos())){
|
if(contained.add(tile.pos())){
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ public class LogicAI extends AIController{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateMovement(){
|
protected void updateMovement(){
|
||||||
if(itemTimer > 0) itemTimer -= Time.delta;
|
if(itemTimer >= 0) itemTimer -= Time.delta;
|
||||||
if(payTimer > 0) payTimer -= Time.delta;
|
if(payTimer >= 0) payTimer -= Time.delta;
|
||||||
|
|
||||||
if(targetTimer > 0f){
|
if(targetTimer > 0f){
|
||||||
targetTimer -= Time.delta;
|
targetTimer -= Time.delta;
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ public class MinerAI extends AIController{
|
|||||||
if(unit.stack.amount >= unit.type.itemCapacity || (targetItem != null && !unit.acceptsItem(targetItem))){
|
if(unit.stack.amount >= unit.type.itemCapacity || (targetItem != null && !unit.acceptsItem(targetItem))){
|
||||||
mining = false;
|
mining = false;
|
||||||
}else{
|
}else{
|
||||||
if(retarget() && targetItem != null){
|
if(timer.get(timerTarget, 60) && targetItem != null){
|
||||||
ore = indexer.findClosestOre(unit.x, unit.y, targetItem);
|
ore = indexer.findClosestOre(unit, targetItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ore != null){
|
if(ore != null){
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ public class SectorPresets implements ContentList{
|
|||||||
|
|
||||||
groundZero = new SectorPreset("groundZero", serpulo, 15){{
|
groundZero = new SectorPreset("groundZero", serpulo, 15){{
|
||||||
alwaysUnlocked = true;
|
alwaysUnlocked = true;
|
||||||
|
addStartingItems = true;
|
||||||
captureWave = 10;
|
captureWave = 10;
|
||||||
difficulty = 1;
|
difficulty = 1;
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -264,7 +264,6 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
slot.load();
|
slot.load();
|
||||||
slot.setAutosave(true);
|
slot.setAutosave(true);
|
||||||
state.rules.sector = sector;
|
state.rules.sector = sector;
|
||||||
state.secinfo = state.rules.sector.info;
|
|
||||||
|
|
||||||
//if there is no base, simulate a new game and place the right loadout at the spawn position
|
//if there is no base, simulate a new game and place the right loadout at the spawn position
|
||||||
if(state.rules.defaultTeam.cores().isEmpty()){
|
if(state.rules.defaultTeam.cores().isEmpty()){
|
||||||
@@ -282,6 +281,9 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
//reset wave so things are more fair
|
//reset wave so things are more fair
|
||||||
state.wave = 1;
|
state.wave = 1;
|
||||||
|
|
||||||
|
//reset win wave??
|
||||||
|
state.rules.winWave = sector.preset != null ? sector.preset.captureWave : 40;
|
||||||
|
|
||||||
//kill all units, since they should be dead anwyay
|
//kill all units, since they should be dead anwyay
|
||||||
Groups.unit.clear();
|
Groups.unit.clear();
|
||||||
Groups.fire.clear();
|
Groups.fire.clear();
|
||||||
@@ -312,8 +314,8 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
world.loadSector(sector);
|
world.loadSector(sector);
|
||||||
state.rules.sector = sector;
|
state.rules.sector = sector;
|
||||||
//assign origin when launching
|
//assign origin when launching
|
||||||
state.secinfo.origin = origin;
|
sector.info.origin = origin;
|
||||||
state.secinfo.destination = origin;
|
sector.info.destination = origin;
|
||||||
logic.play();
|
logic.play();
|
||||||
control.saves.saveSector(sector);
|
control.saves.saveSector(sector);
|
||||||
Events.fire(Trigger.newGame);
|
Events.fire(Trigger.newGame);
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ public class GameState{
|
|||||||
public GameStats stats = new GameStats();
|
public GameStats stats = new GameStats();
|
||||||
/** Global attributes of the environment, calculated by weather. */
|
/** Global attributes of the environment, calculated by weather. */
|
||||||
public Attributes envAttrs = new Attributes();
|
public Attributes envAttrs = new Attributes();
|
||||||
/** Sector information. Only valid in the campaign. */
|
|
||||||
public SectorInfo secinfo = new SectorInfo();
|
|
||||||
/** Team data. Gets reset every new game. */
|
/** Team data. Gets reset every new game. */
|
||||||
public Teams teams = new Teams();
|
public Teams teams = new Teams();
|
||||||
/** Number of enemies in the game; only used clientside in servers. */
|
/** Number of enemies in the game; only used clientside in servers. */
|
||||||
|
|||||||
@@ -55,15 +55,14 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.on(LaunchItemEvent.class, e -> state.secinfo.handleItemExport(e.stack));
|
|
||||||
|
|
||||||
//when loading a 'damaged' sector, propagate the damage
|
//when loading a 'damaged' sector, propagate the damage
|
||||||
Events.on(SaveLoadEvent.class, e -> {
|
Events.on(SaveLoadEvent.class, e -> {
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
state.secinfo.write();
|
SectorInfo info = state.rules.sector.info;
|
||||||
|
info.write();
|
||||||
|
|
||||||
//how much wave time has passed
|
//how much wave time has passed
|
||||||
int wavesPassed = state.secinfo.wavesPassed;
|
int wavesPassed = info.wavesPassed;
|
||||||
|
|
||||||
//wave has passed, remove all enemies, they are assumed to be dead
|
//wave has passed, remove all enemies, they are assumed to be dead
|
||||||
if(wavesPassed > 0){
|
if(wavesPassed > 0){
|
||||||
@@ -84,10 +83,10 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//reset values
|
//reset values
|
||||||
state.secinfo.damage = 0f;
|
info.damage = 0f;
|
||||||
state.secinfo.wavesPassed = 0;
|
info.wavesPassed = 0;
|
||||||
state.secinfo.hasCore = true;
|
info.hasCore = true;
|
||||||
state.secinfo.secondsPassed = 0;
|
info.secondsPassed = 0;
|
||||||
|
|
||||||
state.rules.sector.saveInfo();
|
state.rules.sector.saveInfo();
|
||||||
}
|
}
|
||||||
@@ -273,7 +272,7 @@ public class Logic implements ApplicationListener{
|
|||||||
state.teams.updateTeamStats();
|
state.teams.updateTeamStats();
|
||||||
|
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
state.secinfo.update();
|
state.rules.sector.info.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
|
|||||||
@@ -331,6 +331,7 @@ public class World{
|
|||||||
state.rules.weather.add(new WeatherEntry(Weathers.sporestorm));
|
state.rules.weather.add(new WeatherEntry(Weathers.sporestorm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.info("saving resources as @ -> @ / @", sector.info.resources, content.asArray(), sector.info.hashCode());
|
||||||
sector.info.resources = content.asArray();
|
sector.info.resources = content.asArray();
|
||||||
sector.info.resources.sort(Structs.comps(Structs.comparing(Content::getContentType), Structs.comparingInt(c -> c.id)));
|
sector.info.resources.sort(Structs.comps(Structs.comparing(Content::getContentType), Structs.comparingInt(c -> c.id)));
|
||||||
sector.saveInfo();
|
sector.saveInfo();
|
||||||
|
|||||||
@@ -32,12 +32,16 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean mining(){
|
boolean mining(){
|
||||||
return mineTile != null && !(((Object)this) instanceof Builderc && ((Builderc)(Object)this).activelyBuilding());
|
return mineTile != null && !(((Object)this) instanceof Builderc b && b.activelyBuilding());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validMine(Tile tile, boolean checkDst){
|
||||||
|
return !(tile == null || tile.block() != Blocks.air || (!within(tile.worldx(), tile.worldy(), miningRange) && checkDst)
|
||||||
|
|| tile.drop() == null || !canMine(tile.drop())) && state.teams.canMine(self(), tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validMine(Tile tile){
|
public boolean validMine(Tile tile){
|
||||||
return !(tile == null || tile.block() != Blocks.air || !within(tile.worldx(), tile.worldy(), miningRange)
|
return validMine(tile, true);
|
||||||
|| tile.drop() == null || !canMine(tile.drop()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,6 +62,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
mineTile = null;
|
mineTile = null;
|
||||||
mineTimer = 0f;
|
mineTimer = 0f;
|
||||||
}else if(mining()){
|
}else if(mining()){
|
||||||
|
state.teams.registerMined(mineTile, self());
|
||||||
Item item = mineTile.drop();
|
Item item = mineTile.drop();
|
||||||
lookAt(angleTo(mineTile.worldx(), mineTile.worldy()));
|
lookAt(angleTo(mineTile.worldx(), mineTile.worldy()));
|
||||||
mineTimer += Time.delta *type.mineSpeed;
|
mineTimer += Time.delta *type.mineSpeed;
|
||||||
@@ -84,8 +89,6 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
mineTimer = 0f;
|
mineTimer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ public class AIController implements UnitController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean retarget(){
|
protected boolean retarget(){
|
||||||
return timer.get(timerTarget, 30);
|
return timer.get(timerTarget, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){
|
protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){
|
||||||
|
|||||||
@@ -156,7 +156,6 @@ public class SectorInfo{
|
|||||||
damage = 0;
|
damage = 0;
|
||||||
|
|
||||||
if(state.rules.sector != null){
|
if(state.rules.sector != null){
|
||||||
state.rules.sector.info = this;
|
|
||||||
state.rules.sector.saveInfo();
|
state.rules.sector.saveInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import mindustry.content.*;
|
|||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.payloads.*;
|
import mindustry.world.blocks.payloads.*;
|
||||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
import mindustry.world.blocks.storage.CoreBlock.*;
|
||||||
|
|
||||||
@@ -26,6 +27,8 @@ public class Teams{
|
|||||||
public Seq<TeamData> active = new Seq<>();
|
public Seq<TeamData> active = new Seq<>();
|
||||||
/** Teams with block or unit presence. */
|
/** Teams with block or unit presence. */
|
||||||
public Seq<TeamData> present = new Seq<>(TeamData.class);
|
public Seq<TeamData> present = new Seq<>(TeamData.class);
|
||||||
|
/** Ores currently being mined. */
|
||||||
|
private IntMap<Unit> mined = new IntMap<>();
|
||||||
|
|
||||||
public Teams(){
|
public Teams(){
|
||||||
active.add(get(Team.crux));
|
active.add(get(Team.crux));
|
||||||
@@ -142,7 +145,20 @@ public class Teams{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return whether this ore is taken. */
|
||||||
|
public boolean canMine(Unit unit, Tile tile){
|
||||||
|
if(tile == null) return false;
|
||||||
|
Unit u = mined.get(tile.pos());
|
||||||
|
return u == unit || u == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerMined(Tile tile, Unit unit){
|
||||||
|
if(tile == null || unit == null) return;
|
||||||
|
mined.put(tile.pos(), unit);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateTeamStats(){
|
public void updateTeamStats(){
|
||||||
|
mined.clear();
|
||||||
present.clear();
|
present.clear();
|
||||||
|
|
||||||
for(Team team : Team.all){
|
for(Team team : Team.all){
|
||||||
|
|||||||
@@ -945,10 +945,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
boolean canMine(Tile tile){
|
boolean canMine(Tile tile){
|
||||||
return !Core.scene.hasMouse()
|
return !Core.scene.hasMouse()
|
||||||
&& tile.drop() != null && player.miner().canMine(tile.drop())
|
&& tile.drop() != null
|
||||||
|
&& player.miner().validMine(tile)
|
||||||
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
|
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
|
||||||
&& player.unit().acceptsItem(tile.drop())
|
&& player.unit().acceptsItem(tile.drop())
|
||||||
&& tile.block() == Blocks.air && player.dst(tile.worldx(), tile.worldy()) <= miningRange;
|
&& tile.block() == Blocks.air;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the tile at the specified MOUSE coordinates. */
|
/** Returns the tile at the specified MOUSE coordinates. */
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
public void writeMeta(DataOutput stream, StringMap tags) throws IOException{
|
public void writeMeta(DataOutput stream, StringMap tags) throws IOException{
|
||||||
//prepare campaign data for writing
|
//prepare campaign data for writing
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
state.secinfo.prepare();
|
state.rules.sector.info.prepare();
|
||||||
state.rules.sector.saveInfo();
|
state.rules.sector.saveInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,11 +110,6 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get();
|
if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get();
|
||||||
lastReadBuild = map.getInt("build", -1);
|
lastReadBuild = map.getInt("build", -1);
|
||||||
|
|
||||||
//load in sector info
|
|
||||||
if(state.rules.sector != null){
|
|
||||||
state.secinfo = state.rules.sector.info;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!headless){
|
if(!headless){
|
||||||
Tmp.v1.tryFromString(map.get("viewpos"));
|
Tmp.v1.tryFromString(map.get("viewpos"));
|
||||||
Core.camera.position.set(Tmp.v1);
|
Core.camera.position.set(Tmp.v1);
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ public class LExecutor{
|
|||||||
switch(locate){
|
switch(locate){
|
||||||
case ore -> {
|
case ore -> {
|
||||||
if(exec.obj(ore) instanceof Item item){
|
if(exec.obj(ore) instanceof Item item){
|
||||||
res = indexer.findClosestOre(unit.x, unit.y, item);
|
res = indexer.findClosestOre(unit, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case building -> {
|
case building -> {
|
||||||
@@ -466,9 +466,8 @@ public class LExecutor{
|
|||||||
if(ai.itemTimer > 0) return;
|
if(ai.itemTimer > 0) return;
|
||||||
|
|
||||||
Building build = exec.building(p1);
|
Building build = exec.building(p1);
|
||||||
int amount = exec.numi(p2);
|
int dropped = Math.min(unit.stack.amount, exec.numi(p2));
|
||||||
int dropped = Math.min(unit.stack.amount, amount);
|
if(build != null && dropped > 0 && unit.within(build, logicItemTransferRange + build.block.size * tilesize/2f)){
|
||||||
if(build != null && dropped > 0 && unit.within(build, logicItemTransferRange)){
|
|
||||||
int accepted = build.acceptStack(unit.item(), dropped, unit);
|
int accepted = build.acceptStack(unit.item(), dropped, unit);
|
||||||
if(accepted > 0){
|
if(accepted > 0){
|
||||||
Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build);
|
Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build);
|
||||||
@@ -482,7 +481,7 @@ public class LExecutor{
|
|||||||
Building build = exec.building(p1);
|
Building build = exec.building(p1);
|
||||||
int amount = exec.numi(p3);
|
int amount = exec.numi(p3);
|
||||||
|
|
||||||
if(build != null && build.items != null && exec.obj(p2) instanceof Item item && unit.within(build, logicItemTransferRange)){
|
if(build != null && build.items != null && exec.obj(p2) instanceof Item item && unit.within(build, logicItemTransferRange + build.block.size * tilesize/2f)){
|
||||||
int taken = Math.min(build.items.get(item), Math.min(amount, unit.maxAccepted(item)));
|
int taken = Math.min(build.items.get(item), Math.min(amount, unit.maxAccepted(item)));
|
||||||
|
|
||||||
if(taken > 0){
|
if(taken > 0){
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ public class SectorDamage{
|
|||||||
/** Applies wave damage based on sector parameters. */
|
/** Applies wave damage based on sector parameters. */
|
||||||
public static void applyCalculatedDamage(){
|
public static void applyCalculatedDamage(){
|
||||||
//calculate base damage fraction
|
//calculate base damage fraction
|
||||||
float damage = getDamage(state.secinfo);
|
float damage = getDamage(state.rules.sector.info);
|
||||||
|
|
||||||
//scaled damage has a power component to make it seem a little more realistic (as systems fail, enemy capturing gets easier and easier)
|
//scaled damage has a power component to make it seem a little more realistic (as systems fail, enemy capturing gets easier and easier)
|
||||||
float scaled = Mathf.pow(damage, 1.5f);
|
float scaled = Mathf.pow(damage, 1.5f);
|
||||||
|
|
||||||
//apply damage to units
|
//apply damage to units
|
||||||
float unitDamage = damage * state.secinfo.sumHealth;
|
float unitDamage = damage * state.rules.sector.info.sumHealth;
|
||||||
Tile spawn = spawner.getFirstSpawn();
|
Tile spawn = spawner.getFirstSpawn();
|
||||||
|
|
||||||
//damage only units near the spawn point
|
//damage only units near the spawn point
|
||||||
@@ -114,7 +114,7 @@ public class SectorDamage{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.secinfo.wavesPassed > 0){
|
if(state.rules.sector.info.wavesPassed > 0){
|
||||||
//simply remove each block in the spawner range if a wave passed
|
//simply remove each block in the spawner range if a wave passed
|
||||||
for(Tile spawner : spawner.getSpawns()){
|
for(Tile spawner : spawner.getSpawns()){
|
||||||
spawner.circle((int)(state.rules.dropZoneRadius / tilesize), tile -> {
|
spawner.circle((int)(state.rules.dropZoneRadius / tilesize), tile -> {
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public class FileMapGenerator implements WorldGenerator{
|
public class FileMapGenerator implements WorldGenerator{
|
||||||
public final Map map;
|
public final Map map;
|
||||||
|
public final SectorPreset preset;
|
||||||
|
|
||||||
public FileMapGenerator(String mapName){
|
public FileMapGenerator(String mapName, SectorPreset preset){
|
||||||
this.map = maps != null ? maps.loadInternalMap(mapName) : null;
|
this.map = maps != null ? maps.loadInternalMap(mapName) : null;
|
||||||
|
this.preset = preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -56,6 +58,10 @@ public class FileMapGenerator implements WorldGenerator{
|
|||||||
if(tile.isCenter() && tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam && !anyCores){
|
if(tile.isCenter() && tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam && !anyCores){
|
||||||
Schematics.placeLaunchLoadout(tile.x, tile.y);
|
Schematics.placeLaunchLoadout(tile.x, tile.y);
|
||||||
anyCores = true;
|
anyCores = true;
|
||||||
|
|
||||||
|
if(preset.addStartingItems){
|
||||||
|
tile.build.items.add(state.rules.loadout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,10 +17,11 @@ public class SectorPreset extends UnlockableContent{
|
|||||||
public Cons<Rules> rules = rules -> rules.winWave = captureWave;
|
public Cons<Rules> rules = rules -> rules.winWave = captureWave;
|
||||||
/** Difficulty, 0-10. */
|
/** Difficulty, 0-10. */
|
||||||
public float difficulty;
|
public float difficulty;
|
||||||
|
public boolean addStartingItems = false;
|
||||||
|
|
||||||
public SectorPreset(String name, Planet planet, int sector){
|
public SectorPreset(String name, Planet planet, int sector){
|
||||||
super(name);
|
super(name);
|
||||||
this.generator = new FileMapGenerator(name);
|
this.generator = new FileMapGenerator(name, this);
|
||||||
this.planet = planet;
|
this.planet = planet;
|
||||||
sector %= planet.sectors.size;
|
sector %= planet.sectors.size;
|
||||||
this.sector = planet.sectors.get(sector);
|
this.sector = planet.sectors.get(sector);
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
|
|
||||||
shouldPause = true;
|
shouldPause = true;
|
||||||
|
|
||||||
|
addCloseListener();
|
||||||
|
|
||||||
buttons.defaults().size(200f, 56f).pad(2);
|
buttons.defaults().size(200f, 56f).pad(2);
|
||||||
buttons.button("@back", Icon.left, this::hide);
|
buttons.button("@back", Icon.left, this::hide);
|
||||||
buttons.button("@techtree", Icon.tree, () -> ui.research.show());
|
buttons.button("@techtree", Icon.tree, () -> ui.research.show());
|
||||||
@@ -380,6 +382,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
stable.row();
|
stable.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.info("sector resources = @ / @", sector.info.resources, sector.info.hashCode());
|
||||||
|
|
||||||
if(sector.save != null && sector.info.resources.any()){
|
if(sector.save != null && sector.info.resources.any()){
|
||||||
stable.add("@sectors.resources").row();
|
stable.add("@sectors.resources").row();
|
||||||
stable.table(t -> {
|
stable.table(t -> {
|
||||||
|
|||||||
@@ -368,9 +368,9 @@ public class HudFragment extends Fragment{
|
|||||||
c.clearChildren();
|
c.clearChildren();
|
||||||
|
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
if(state.secinfo.getExport(item) >= 1){
|
if(state.rules.sector != null && state.rules.sector.info.getExport(item) >= 1){
|
||||||
c.image(item.icon(Cicon.small));
|
c.image(item.icon(Cicon.small));
|
||||||
c.label(() -> (int)state.secinfo.getExport(item) + " /s").color(Color.lightGray);
|
c.label(() -> (int)state.rules.sector.info.getExport(item) + " /s").color(Color.lightGray);
|
||||||
c.row();
|
c.row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,7 @@ public class HudFragment extends Fragment{
|
|||||||
c.update(() -> {
|
c.update(() -> {
|
||||||
boolean wrong = false;
|
boolean wrong = false;
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
boolean has = state.secinfo.getExport(item) >= 1;
|
boolean has = state.rules.sector != null && state.rules.sector.info.getExport(item) >= 1;
|
||||||
if(used.get(item.id) != has){
|
if(used.get(item.id) != has){
|
||||||
used.set(item.id, has);
|
used.set(item.id, has);
|
||||||
wrong = true;
|
wrong = true;
|
||||||
@@ -389,7 +389,7 @@ public class HudFragment extends Fragment{
|
|||||||
rebuild.run();
|
rebuild.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).visible(() -> state.isCampaign() && content.items().contains(i -> state.secinfo.getExport(i) > 0));
|
}).visible(() -> state.isCampaign() && content.items().contains(i -> state.rules.sector != null && state.rules.sector.info.getExport(i) > 0));
|
||||||
});
|
});
|
||||||
|
|
||||||
blockfrag.build(parent);
|
blockfrag.build(parent);
|
||||||
|
|||||||
@@ -126,7 +126,6 @@ public class Build{
|
|||||||
for(int dy = 0; dy < type.size; dy++){
|
for(int dy = 0; dy < type.size; dy++){
|
||||||
int wx = dx + offsetx + tile.x, wy = dy + offsety + tile.y;
|
int wx = dx + offsetx + tile.x, wy = dy + offsety + tile.y;
|
||||||
|
|
||||||
|
|
||||||
Tile check = world.tile(wx, wy);
|
Tile check = world.tile(wx, wy);
|
||||||
|
|
||||||
if(
|
if(
|
||||||
@@ -136,6 +135,10 @@ public class Build{
|
|||||||
!check.interactable(team) || //cannot interact
|
!check.interactable(team) || //cannot interact
|
||||||
!check.floor().placeableOn || //solid wall
|
!check.floor().placeableOn || //solid wall
|
||||||
!((type.canReplace(check.block()) || //can replace type
|
!((type.canReplace(check.block()) || //can replace type
|
||||||
|
//controversial change: allow rebuilding damaged blocks
|
||||||
|
//this could be buggy and abusable, so I'm not enabling it yet
|
||||||
|
//note that this requires a change in BuilderComp as well
|
||||||
|
//(type == check.block() && check.centerX() == x && check.centerY() == y && check.build != null && check.build.health < check.build.maxHealth - 0.0001f) ||
|
||||||
(check.block instanceof ConstructBlock && check.<ConstructBuild>bc().cblock == type && check.centerX() == tile.x && check.centerY() == tile.y)) && //same type in construction
|
(check.block instanceof ConstructBlock && check.<ConstructBuild>bc().cblock == type && check.centerX() == tile.x && check.centerY() == tile.y)) && //same type in construction
|
||||||
type.bounds(tile.x, tile.y, Tmp.r1).grow(0.01f).contains(check.block.bounds(check.centerX(), check.centerY(), Tmp.r2))) || //no replacement
|
type.bounds(tile.x, tile.y, Tmp.r1).grow(0.01f).contains(check.block.bounds(check.centerX(), check.centerY(), Tmp.r2))) || //no replacement
|
||||||
(type.requiresWater && check.floor().liquidDrop != Liquids.water) //requires water but none found
|
(type.requiresWater && check.floor().liquidDrop != Liquids.water) //requires water but none found
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class LaunchPad extends Block{
|
|||||||
|
|
||||||
table.row();
|
table.row();
|
||||||
table.label(() -> {
|
table.label(() -> {
|
||||||
Sector dest = state.secinfo.getRealDestination();
|
Sector dest = state.rules.sector == null ? null : state.rules.sector.info.getRealDestination();
|
||||||
|
|
||||||
return Core.bundle.format("launch.destination",
|
return Core.bundle.format("launch.destination",
|
||||||
dest == null ? Core.bundle.get("sectors.nonelaunch") :
|
dest == null ? Core.bundle.get("sectors.nonelaunch") :
|
||||||
@@ -135,7 +135,11 @@ public class LaunchPad extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
table.button(Icon.upOpen, Styles.clearTransi, () -> {
|
table.button(Icon.upOpen, Styles.clearTransi, () -> {
|
||||||
ui.planet.showSelect(state.rules.sector, other -> state.secinfo.destination = other);
|
ui.planet.showSelect(state.rules.sector, other -> {
|
||||||
|
if(state.isCampaign()){
|
||||||
|
state.rules.sector.info.destination = other;
|
||||||
|
}
|
||||||
|
});
|
||||||
deselect();
|
deselect();
|
||||||
}).size(40f);
|
}).size(40f);
|
||||||
}
|
}
|
||||||
@@ -208,7 +212,7 @@ public class LaunchPad extends Block{
|
|||||||
public void remove(){
|
public void remove(){
|
||||||
if(!state.isCampaign()) return;
|
if(!state.isCampaign()) return;
|
||||||
|
|
||||||
Sector destsec = state.secinfo.getRealDestination();
|
Sector destsec = state.rules.sector.info.getRealDestination();
|
||||||
|
|
||||||
//actually launch the items upon removal
|
//actually launch the items upon removal
|
||||||
if(team() == state.rules.defaultTeam){
|
if(team() == state.rules.defaultTeam){
|
||||||
@@ -219,7 +223,7 @@ public class LaunchPad extends Block{
|
|||||||
dest.add(stack);
|
dest.add(stack);
|
||||||
|
|
||||||
//update export
|
//update export
|
||||||
state.secinfo.handleItemExport(stack);
|
state.rules.sector.info.handleItemExport(stack);
|
||||||
Events.fire(new LaunchItemEvent(stack));
|
Events.fire(new LaunchItemEvent(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -339,15 +339,15 @@ public class CoreBlock extends StorageBlock{
|
|||||||
public void itemTaken(Item item){
|
public void itemTaken(Item item){
|
||||||
if(state.isCampaign() && team == state.rules.defaultTeam){
|
if(state.isCampaign() && team == state.rules.defaultTeam){
|
||||||
//update item taken amount
|
//update item taken amount
|
||||||
state.secinfo.handleCoreItem(item, -1);
|
state.rules.sector.info.handleCoreItem(item, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleItem(Building source, Item item){
|
public void handleItem(Building source, Item item){
|
||||||
if(net.server() || !net.active()){
|
if(net.server() || !net.active()){
|
||||||
if(team == state.rules.defaultTeam){
|
if(team == state.rules.defaultTeam && state.isCampaign()){
|
||||||
state.secinfo.handleCoreItem(item, 1);
|
state.rules.sector.info.handleCoreItem(item, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(items.get(item) >= getMaximumAccepted(item)){
|
if(items.get(item) >= getMaximumAccepted(item)){
|
||||||
|
|||||||
Reference in New Issue
Block a user