Replaced concept of "turns" with raw seconds
This commit is contained in:
BIN
core/assets/baseparts/000.msch
Normal file
BIN
core/assets/baseparts/000.msch
Normal file
Binary file not shown.
@@ -587,6 +587,8 @@ blocks.reload = Shots/Second
|
|||||||
blocks.ammo = Ammo
|
blocks.ammo = Ammo
|
||||||
|
|
||||||
bar.drilltierreq = Better Drill Required
|
bar.drilltierreq = Better Drill Required
|
||||||
|
bar.noresources = Missing Resources
|
||||||
|
bar.corereq = Core Base Required
|
||||||
bar.drillspeed = Drill Speed: {0}/s
|
bar.drillspeed = Drill Speed: {0}/s
|
||||||
bar.pumpspeed = Pump Speed: {0}/s
|
bar.pumpspeed = Pump Speed: {0}/s
|
||||||
bar.efficiency = Efficiency: {0}%
|
bar.efficiency = Efficiency: {0}%
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ public class Vars implements Loadable{
|
|||||||
public static final float miningRange = 70f;
|
public static final float miningRange = 70f;
|
||||||
/** range for building */
|
/** range for building */
|
||||||
public static final float buildingRange = 220f;
|
public static final float buildingRange = 220f;
|
||||||
/** duration of one turn in ticks */
|
/** duration of time between events in ticks */
|
||||||
public static final float turnDuration = 5 * Time.toMinutes;
|
public static final float eventRate = 5 * Time.toMinutes;
|
||||||
/** min armor fraction damage; e.g. 0.05 = at least 5% damage */
|
/** min armor fraction damage; e.g. 0.05 = at least 5% damage */
|
||||||
public static final float minArmorDamage = 0.05f;
|
public static final float minArmorDamage = 0.05f;
|
||||||
/** launch animation duration */
|
/** launch animation duration */
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import mindustry.game.EventType.*;
|
|||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.maps.*;
|
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.type.Weather.*;
|
import mindustry.type.Weather.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -88,13 +87,14 @@ public class Logic implements ApplicationListener{
|
|||||||
|
|
||||||
//when loading a 'damaged' sector, propagate the damage
|
//when loading a 'damaged' sector, propagate the damage
|
||||||
Events.on(WorldLoadEvent.class, e -> {
|
Events.on(WorldLoadEvent.class, e -> {
|
||||||
if(state.isCampaign() && state.rules.sector.getTurnsPassed() > 0){
|
if(state.isCampaign() && state.rules.sector.getSecondsPassed() > 0){
|
||||||
int passed = state.rules.sector.getTurnsPassed();
|
long seconds = state.rules.sector.getSecondsPassed();
|
||||||
CoreEntity core = state.rules.defaultTeam.core();
|
CoreEntity core = state.rules.defaultTeam.core();
|
||||||
|
|
||||||
if(state.rules.sector.hasWaves()){
|
//TODO figure out how to apply damage properly
|
||||||
SectorDamage.apply(passed);
|
// if(state.rules.sector.hasWaves()){
|
||||||
}
|
//SectorDamage.apply(seconds);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
//add resources based on turns passed
|
//add resources based on turns passed
|
||||||
@@ -103,7 +103,7 @@ public class Logic implements ApplicationListener{
|
|||||||
//add produced items
|
//add produced items
|
||||||
//TODO move to recieved items
|
//TODO move to recieved items
|
||||||
state.rules.sector.save.meta.secinfo.production.each((item, stat) -> {
|
state.rules.sector.save.meta.secinfo.production.each((item, stat) -> {
|
||||||
core.items.add(item, (int)(stat.mean * passed));
|
core.items.add(item, (int)(stat.mean * seconds));
|
||||||
});
|
});
|
||||||
|
|
||||||
//add recieved items
|
//add recieved items
|
||||||
@@ -121,22 +121,13 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.rules.sector.setTurnsPassed(0);
|
state.rules.sector.setLastSecond(universe.seconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
//enable infinite ammo for wave team by default
|
//enable infinite ammo for wave team by default
|
||||||
state.rules.waveTeam.rules().infiniteAmmo = true;
|
state.rules.waveTeam.rules().infiniteAmmo = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO dying takes up a turn (?)
|
|
||||||
/*
|
|
||||||
Events.on(GameOverEvent.class, e -> {
|
|
||||||
//simulate a turn on a normal non-launch gameover
|
|
||||||
if(state.isCampaign() && !state.launched){
|
|
||||||
universe.runTurn();
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds starting items, resets wave time, and sets state to playing. */
|
/** Adds starting items, resets wave time, and sets state to playing. */
|
||||||
@@ -253,16 +244,11 @@ public class Logic implements ApplicationListener{
|
|||||||
ui.hudfrag.showLaunch();
|
ui.hudfrag.showLaunch();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO core launch effect
|
//TODO better core launch effect
|
||||||
for(Building tile : state.teams.playerCores()){
|
for(Building tile : state.teams.playerCores()){
|
||||||
Fx.launch.at(tile);
|
Fx.launch.at(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.isCampaign()){
|
|
||||||
//TODO implement?
|
|
||||||
//state.getSector().setLaunched();
|
|
||||||
}
|
|
||||||
|
|
||||||
Sector sector = state.rules.sector;
|
Sector sector = state.rules.sector;
|
||||||
|
|
||||||
//TODO containers must be launched too
|
//TODO containers must be launched too
|
||||||
@@ -290,10 +276,10 @@ public class Logic implements ApplicationListener{
|
|||||||
sector.save.save();
|
sector.save.save();
|
||||||
|
|
||||||
//run a turn, since launching takes up a turn
|
//run a turn, since launching takes up a turn
|
||||||
universe.runTurn();
|
universe.runEvents();
|
||||||
|
|
||||||
//TODO ???
|
//TODO apply extra damage to sector
|
||||||
sector.setTurnsPassed(sector.getTurnsPassed() + 3);
|
//sector.setTurnsPassed(sector.getTurnsPassed() + 3);
|
||||||
|
|
||||||
//TODO load the sector that was launched from
|
//TODO load the sector that was launched from
|
||||||
Events.fire(new LaunchEvent());
|
Events.fire(new LaunchEvent());
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public class EditorTile extends Tile{
|
|||||||
if(block.hasEntity()){
|
if(block.hasEntity()){
|
||||||
build = entityprov.get().init(this, team, false);
|
build = entityprov.get().init(this, team, false);
|
||||||
build.cons(new ConsumeModule(build));
|
build.cons(new ConsumeModule(build));
|
||||||
if(block.hasItems) build.items(new ItemModule());
|
if(block.hasItems) build.items = new ItemModule();
|
||||||
if(block.hasLiquids) build.liquids(new LiquidModule());
|
if(block.hasLiquids) build.liquids(new LiquidModule());
|
||||||
if(block.hasPower) build.power(new PowerModule());
|
if(block.hasPower) build.power(new PowerModule());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ public class EventType{
|
|||||||
update
|
update
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TurnEvent{}
|
|
||||||
public static class WinEvent{}
|
public static class WinEvent{}
|
||||||
public static class LoseEvent{}
|
public static class LoseEvent{}
|
||||||
public static class LaunchEvent{}
|
public static class LaunchEvent{}
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ public class SectorInfo{
|
|||||||
public ObjectIntMap<Item> getCurrentItems(Sector sector){
|
public ObjectIntMap<Item> getCurrentItems(Sector sector){
|
||||||
ObjectIntMap<Item> map = new ObjectIntMap<>();
|
ObjectIntMap<Item> map = new ObjectIntMap<>();
|
||||||
map.putAll(coreItems);
|
map.putAll(coreItems);
|
||||||
int turns = sector.getTurnsPassed();
|
long seconds = sector.getSecondsPassed();
|
||||||
production.each((item, stat) -> map.increment(item, (int)(stat.mean * turns)));
|
production.each((item, stat) -> map.increment(item, (int)(stat.mean * seconds)));
|
||||||
//increment based on recieved items
|
//increment based on recieved items
|
||||||
sector.getRecievedItems().each(stack -> map.increment(stack.item, stack.amount));
|
sector.getRecievedItems().each(stack -> map.increment(stack.item, stack.amount));
|
||||||
return map;
|
return map;
|
||||||
@@ -155,6 +155,8 @@ public class SectorInfo{
|
|||||||
public transient float counter;
|
public transient float counter;
|
||||||
public transient WindowedMean means = new WindowedMean(valueWindow);
|
public transient WindowedMean means = new WindowedMean(valueWindow);
|
||||||
public transient boolean loaded;
|
public transient boolean loaded;
|
||||||
|
|
||||||
|
/** mean in terms of items produced per refresh rate (currently, per second) */
|
||||||
public float mean;
|
public float mean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ public class Tutorial{
|
|||||||
},
|
},
|
||||||
withdraw(() -> event("withdraw")){
|
withdraw(() -> event("withdraw")){
|
||||||
void begin(){
|
void begin(){
|
||||||
state.teams.playerCores().first().items().add(Items.copper, 10);
|
state.teams.playerCores().first().items.add(Items.copper, 10);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deposit(() -> event("deposit")),
|
deposit(() -> event("deposit")),
|
||||||
@@ -270,7 +270,7 @@ public class Tutorial{
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int item(Item item){
|
static int item(Item item){
|
||||||
return state.rules.defaultTeam.data().noCores() ? 0 : state.rules.defaultTeam.core().items().get(item);
|
return state.rules.defaultTeam.data().noCores() ? 0 : state.rules.defaultTeam.core().items.get(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean toggled(String name){
|
static boolean toggled(String name){
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ import arc.*;
|
|||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.game.EventType.*;
|
|
||||||
import mindustry.game.SectorInfo.*;
|
|
||||||
import mindustry.io.*;
|
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.blocks.storage.*;
|
import mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
@@ -18,8 +14,8 @@ import static mindustry.Vars.*;
|
|||||||
public class Universe{
|
public class Universe{
|
||||||
private long seconds;
|
private long seconds;
|
||||||
private float secondCounter;
|
private float secondCounter;
|
||||||
private int turn;
|
private int event;
|
||||||
private float turnCounter;
|
private float eventCounter;
|
||||||
|
|
||||||
private Schematic lastLoadout;
|
private Schematic lastLoadout;
|
||||||
private Seq<ItemStack> lastLaunchResources = new Seq<>();
|
private Seq<ItemStack> lastLaunchResources = new Seq<>();
|
||||||
@@ -59,11 +55,11 @@ public class Universe{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//update turn state - happens only in-game
|
//update event counter - happens only in-game
|
||||||
turnCounter += Time.delta();
|
eventCounter += Time.delta();
|
||||||
|
|
||||||
if(turnCounter >= turnDuration){
|
if(eventCounter >= eventRate){
|
||||||
runTurn();
|
runEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.hasSector()){
|
if(state.hasSector()){
|
||||||
@@ -113,70 +109,12 @@ public class Universe{
|
|||||||
return schem == null ? all.first() : schem;
|
return schem == null ? all.first() : schem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getTotalExports(){
|
/** Runs possible events. Resets event counter. */
|
||||||
int[] exports = new int[Vars.content.items().size];
|
public void runEvents(){
|
||||||
|
event++;
|
||||||
|
eventCounter = 0;
|
||||||
|
|
||||||
for(Planet planet : content.planets()){
|
//TODO events
|
||||||
for(Sector sector : planet.sectors){
|
|
||||||
|
|
||||||
//ignore the current sector if the player is in it right now
|
|
||||||
if(sector.hasBase() && !sector.isBeingPlayed()){
|
|
||||||
SaveMeta meta = sector.save.meta;
|
|
||||||
|
|
||||||
for(ObjectMap.Entry<Item, ExportStat> entry : meta.secinfo.export){
|
|
||||||
//total is calculated by items/sec (value) * turn duration in seconds
|
|
||||||
int total = (int)(entry.value.mean * turnDuration / 60f);
|
|
||||||
|
|
||||||
exports[entry.key.id] += total;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return exports;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runTurns(int amount){
|
|
||||||
for(int i = 0; i < amount; i++){
|
|
||||||
runTurn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Runs a turn once. Resets turn counter. */
|
|
||||||
public void runTurn(){
|
|
||||||
turn ++;
|
|
||||||
turnCounter = 0;
|
|
||||||
|
|
||||||
//TODO EVENTS + a notification
|
|
||||||
|
|
||||||
//increment turns passed for sectors with waves
|
|
||||||
//TODO a turn passing may break the core; detect this, send an event and mark the sector as having no base!
|
|
||||||
for(Planet planet : content.planets()){
|
|
||||||
for(Sector sector : planet.sectors){
|
|
||||||
//update turns passed for all sectors
|
|
||||||
if(!sector.isBeingPlayed() && sector.hasSave()){
|
|
||||||
sector.setTurnsPassed(sector.getTurnsPassed() + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate passive item generation
|
|
||||||
//TODO make exports only update for sector with items
|
|
||||||
//TODO items should be added directly to cores!
|
|
||||||
|
|
||||||
Events.fire(new TurnEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTurn(){
|
|
||||||
return turn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSectorsAttacked(){
|
|
||||||
int count = 0;
|
|
||||||
for(Planet planet : content.planets()){
|
|
||||||
count += planet.sectors.count(s -> !s.isBeingPlayed() && s.hasSave() && s.hasWaves());
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float secondsMod(float mod, float scale){
|
public float secondsMod(float mod, float scale){
|
||||||
@@ -193,14 +131,14 @@ public class Universe{
|
|||||||
|
|
||||||
private void save(){
|
private void save(){
|
||||||
Core.settings.put("utime", seconds);
|
Core.settings.put("utime", seconds);
|
||||||
Core.settings.put("turn", turn);
|
Core.settings.put("event", event);
|
||||||
Core.settings.put("turntime", turnCounter);
|
Core.settings.put("eventtime", eventCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(){
|
private void load(){
|
||||||
seconds = Core.settings.getLong("utime");
|
seconds = Core.settings.getLong("utime");
|
||||||
turn = Core.settings.getInt("turn");
|
event = Core.settings.getInt("event");
|
||||||
turnCounter = Core.settings.getFloat("turntime");
|
eventCounter = Core.settings.getFloat("eventtime");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
//prepare campaign data for writing
|
//prepare campaign data for writing
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
state.secinfo.prepare();
|
state.secinfo.prepare();
|
||||||
|
state.getSector().setLastSecond(universe.seconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
//flush tech node progress
|
//flush tech node progress
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import mindustry.game.Saves.*;
|
|||||||
import mindustry.graphics.g3d.PlanetGrid.*;
|
import mindustry.graphics.g3d.PlanetGrid.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.world;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
/** A small section of a planet. */
|
/** A small section of a planet. */
|
||||||
public class Sector{
|
public class Sector{
|
||||||
@@ -131,12 +131,12 @@ public class Sector{
|
|||||||
return Core.settings.getInt(key("spawn-position"), Point2.pack(world.width() / 2, world.height() / 2));
|
return Core.settings.getInt(key("spawn-position"), Point2.pack(world.width() / 2, world.height() / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTurnsPassed(int number){
|
public void setLastSecond(long number){
|
||||||
put("turns-passed", number);
|
put("last-second", number);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTurnsPassed(){
|
public long getSecondsPassed(){
|
||||||
return Core.settings.getInt(key("turns-passed"));
|
return universe.seconds() - Core.settings.getLong(key("last-second"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String key(String key){
|
private String key(String key){
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
t.left();
|
t.left();
|
||||||
|
|
||||||
sector.save.meta.secinfo.exportRates().each(entry -> {
|
sector.save.meta.secinfo.exportRates().each(entry -> {
|
||||||
int total = (int)(entry.value * turnDuration / 60f);
|
int total = (int)(entry.value * eventRate / 60f);
|
||||||
if(total > 1){
|
if(total > 1){
|
||||||
t.image(entry.key.icon(Cicon.small)).padRight(3);
|
t.image(entry.key.icon(Cicon.small)).padRight(3);
|
||||||
t.add(ui.formatAmount(total) + " /turn").color(Color.lightGray);
|
t.add(ui.formatAmount(total) + " /turn").color(Color.lightGray);
|
||||||
@@ -330,11 +330,13 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//display how many turns this sector has been attacked
|
//display how many turns this sector has been attacked
|
||||||
|
//TODO implement properly
|
||||||
|
/*
|
||||||
if(sector.getTurnsPassed() > 0 && sector.hasBase()){
|
if(sector.getTurnsPassed() > 0 && sector.hasBase()){
|
||||||
stable.row();
|
stable.row();
|
||||||
|
|
||||||
stable.add("[scarlet]" + Iconc.warning + " " + sector.getTurnsPassed() + "x attacks");
|
stable.add("[scarlet]" + Iconc.warning + " " + sector.getTurnsPassed() + "x attacks");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
stable.row();
|
stable.row();
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,6 @@ public class HudFragment extends Fragment{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(Group parent){
|
public void build(Group parent){
|
||||||
Events.on(TurnEvent.class, e -> {
|
|
||||||
//TODO localize, clean up, etc
|
|
||||||
int attacked = universe.getSectorsAttacked();
|
|
||||||
showToast("New turn: [accent]" + universe.getTurn() + "[]" + (attacked > 0 ? "\n[scarlet]" + Iconc.warning + " " + attacked + " sectors attacked!": ""));
|
|
||||||
});
|
|
||||||
|
|
||||||
//TODO details and stuff
|
//TODO details and stuff
|
||||||
Events.on(SectorCaptureEvent.class, e ->{
|
Events.on(SectorCaptureEvent.class, e ->{
|
||||||
|
|||||||
@@ -484,6 +484,11 @@ public class Block extends UnlockableContent{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called right before building of this block begins. */
|
||||||
|
public void beforePlaceBegan(Tile tile, Block previous){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** @return a message detailing why this block can't be placed. */
|
/** @return a message detailing why this block can't be placed. */
|
||||||
public String unplaceableMessage(){
|
public String unplaceableMessage(){
|
||||||
return state.rules.bannedBlocks.contains(this) ? Core.bundle.get("banned") : buildPlaceability.message();
|
return state.rules.bannedBlocks.contains(this) ? Core.bundle.get("banned") : buildPlaceability.message();
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ public class Build{
|
|||||||
Block previous = tile.block();
|
Block previous = tile.block();
|
||||||
Block sub = BuildBlock.get(result.size);
|
Block sub = BuildBlock.get(result.size);
|
||||||
|
|
||||||
|
result.beforePlaceBegan(tile, previous);
|
||||||
|
|
||||||
tile.setBlock(sub, team, rotation);
|
tile.setBlock(sub, team, rotation);
|
||||||
tile.<BuildEntity>bc().setConstruct(previous, result);
|
tile.<BuildEntity>bc().setConstruct(previous, result);
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class CachedTile extends Tile{
|
|||||||
n.cons(new ConsumeModule(build));
|
n.cons(new ConsumeModule(build));
|
||||||
n.tile(this);
|
n.tile(this);
|
||||||
n.block(block);
|
n.block(block);
|
||||||
if(block.hasItems) n.items(new ItemModule());
|
if(block.hasItems) n.items = new ItemModule();
|
||||||
if(block.hasLiquids) n.liquids(new LiquidModule());
|
if(block.hasLiquids) n.liquids(new LiquidModule());
|
||||||
if(block.hasPower) n.power(new PowerModule());
|
if(block.hasPower) n.power(new PowerModule());
|
||||||
build = n;
|
build = n;
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public class MassDriver extends Block{
|
|||||||
|
|
||||||
if(
|
if(
|
||||||
items.total() >= minDistribute && //must shoot minimum amount of items
|
items.total() >= minDistribute && //must shoot minimum amount of items
|
||||||
link.block().itemCapacity - link.items().total() >= minDistribute //must have minimum amount of space
|
link.block().itemCapacity - link.items.total() >= minDistribute //must have minimum amount of space
|
||||||
){
|
){
|
||||||
MassDriverEntity other = (MassDriverEntity)link;
|
MassDriverEntity other = (MassDriverEntity)link;
|
||||||
other.waitingShooters.add(tile);
|
other.waitingShooters.add(tile);
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import arc.util.ArcAnnotate.*;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.game.*;
|
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
@@ -25,6 +25,9 @@ import mindustry.world.modules.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class CoreBlock extends StorageBlock{
|
public class CoreBlock extends StorageBlock{
|
||||||
|
//hacky way to pass item modules between methods
|
||||||
|
private static ItemModule nextItems;
|
||||||
|
|
||||||
public UnitType unitType = UnitTypes.alpha;
|
public UnitType unitType = UnitTypes.alpha;
|
||||||
|
|
||||||
public final int timerResupply = timers++;
|
public final int timerResupply = timers++;
|
||||||
@@ -76,7 +79,7 @@ public class CoreBlock extends StorageBlock{
|
|||||||
new Bar(
|
new Bar(
|
||||||
() -> Core.bundle.format("bar.capacity", ui.formatAmount(e.storageCapacity)),
|
() -> Core.bundle.format("bar.capacity", ui.formatAmount(e.storageCapacity)),
|
||||||
() -> Pal.items,
|
() -> Pal.items,
|
||||||
() -> e.items().total() / ((float)e.storageCapacity * content.items().count(i -> i.unlockedNow()))
|
() -> e.items.total() / ((float)e.storageCapacity * content.items().count(i -> i.unlockedNow()))
|
||||||
));
|
));
|
||||||
|
|
||||||
bars.add("units", e ->
|
bars.add("units", e ->
|
||||||
@@ -100,6 +103,9 @@ public class CoreBlock extends StorageBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlaceOn(Tile tile, Team team){
|
public boolean canPlaceOn(Tile tile, Team team){
|
||||||
|
CoreEntity core = team.core();
|
||||||
|
//must have all requirements
|
||||||
|
if(core == null || (!state.rules.infiniteResources && !core.items.has(requirements))) return false;
|
||||||
return canReplace(tile.block());
|
return canReplace(tile.block());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +116,41 @@ public class CoreBlock extends StorageBlock{
|
|||||||
tile.setBlock(this, tile.team());
|
tile.setBlock(this, tile.team());
|
||||||
Fx.placeBlock.at(tile, tile.block().size);
|
Fx.placeBlock.at(tile, tile.block().size);
|
||||||
Fx.upgradeCore.at(tile, tile.block().size);
|
Fx.upgradeCore.at(tile, tile.block().size);
|
||||||
|
|
||||||
|
//set up the correct items
|
||||||
|
if(nextItems != null){
|
||||||
|
//force-set the total items
|
||||||
|
if(tile.team().core() != null){
|
||||||
|
tile.team().core().items.set(nextItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
nextItems = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforePlaceBegan(Tile tile, Block previous){
|
||||||
|
if(tile.build instanceof CoreEntity){
|
||||||
|
//right before placing, create a "destination" item array which is all the previous items minus core requirements
|
||||||
|
ItemModule items = tile.build.items.copy();
|
||||||
|
if(!state.rules.infiniteResources){
|
||||||
|
items.remove(requirements);
|
||||||
|
}
|
||||||
|
|
||||||
|
nextItems = items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
|
if(!canPlaceOn(world.tile(x, y),player.team())){
|
||||||
|
|
||||||
|
drawPlaceText(Core.bundle.get((player.team().core() != null && player.team().core().items.has(requirements) && !state.rules.infiniteResources) ?
|
||||||
|
"bar.corereq" :
|
||||||
|
"bar.noresources"
|
||||||
|
), x, y, valid);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,14 +202,14 @@ public class CoreBlock extends StorageBlock{
|
|||||||
public void onProximityUpdate(){
|
public void onProximityUpdate(){
|
||||||
for(Building other : state.teams.cores(team)){
|
for(Building other : state.teams.cores(team)){
|
||||||
if(other.tile() != tile){
|
if(other.tile() != tile){
|
||||||
items(other.items());
|
this.items = other.items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.teams.registerCore(this);
|
state.teams.registerCore(this);
|
||||||
|
|
||||||
storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) && owns(e) ? e.block().itemCapacity : 0);
|
storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) && owns(e) ? e.block().itemCapacity : 0);
|
||||||
proximity.each(e -> isContainer(e) && owns(e), t -> {
|
proximity.each(e -> isContainer(e) && owns(e), t -> {
|
||||||
t.items(items);
|
t.items = items;
|
||||||
((StorageBlockEntity)t).linkedCore = this;
|
((StorageBlockEntity)t).linkedCore = this;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -198,10 +239,10 @@ public class CoreBlock extends StorageBlock{
|
|||||||
Draw.rect("block-select", t.x() + offset * p.x, t.y() + offset * p.y, i * 90);
|
Draw.rect("block-select", t.x() + offset * p.x, t.y() + offset * p.y, i * 90);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if(proximity.contains(e -> isContainer(e) && e.items() == items)){
|
if(proximity.contains(e -> isContainer(e) && e.items == items)){
|
||||||
outline.get(this);
|
outline.get(this);
|
||||||
}
|
}
|
||||||
proximity.each(e -> isContainer(e) && e.items() == items, outline);
|
proximity.each(e -> isContainer(e) && e.items == items, outline);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,15 +269,15 @@ public class CoreBlock extends StorageBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRemoved(){
|
public void onRemoved(){
|
||||||
int total = proximity.count(e -> e.items() != null && e.items() == items);
|
int total = proximity.count(e -> e.items != null && e.items == items);
|
||||||
float fract = 1f / total / state.teams.cores(team).size;
|
float fract = 1f / total / state.teams.cores(team).size;
|
||||||
|
|
||||||
proximity.each(e -> isContainer(e) && e.items() == items && owns(e), t -> {
|
proximity.each(e -> isContainer(e) && e.items == items && owns(e), t -> {
|
||||||
StorageBlockEntity ent = (StorageBlockEntity)t;
|
StorageBlockEntity ent = (StorageBlockEntity)t;
|
||||||
ent.linkedCore = null;
|
ent.linkedCore = null;
|
||||||
ent.items(new ItemModule());
|
ent.items = new ItemModule();
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
ent.items().set(item, (int)(fract * items.get(item)));
|
ent.items.set(item, (int)(fract * items.get(item)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -51,19 +51,19 @@ public class Unloader extends Block{
|
|||||||
if(timer(timerUnload, speed / timeScale())){
|
if(timer(timerUnload, speed / timeScale())){
|
||||||
for(Building other : proximity){
|
for(Building other : proximity){
|
||||||
if(other.interactable(team) && other.block().unloadable && other.block().hasItems
|
if(other.interactable(team) && other.block().unloadable && other.block().hasItems
|
||||||
&& ((sortItem == null && other.items().total() > 0) || (sortItem != null && other.items().has(sortItem)))){
|
&& ((sortItem == null && other.items.total() > 0) || (sortItem != null && other.items.has(sortItem)))){
|
||||||
//make sure the item can't be dumped back into this block
|
//make sure the item can't be dumped back into this block
|
||||||
dumpingTo = other;
|
dumpingTo = other;
|
||||||
|
|
||||||
//get item to be taken
|
//get item to be taken
|
||||||
Item item = sortItem == null ? other.items().beginTake() : sortItem;
|
Item item = sortItem == null ? other.items.beginTake() : sortItem;
|
||||||
|
|
||||||
//remove item if it's dumped correctly
|
//remove item if it's dumped correctly
|
||||||
if(put(item)){
|
if(put(item)){
|
||||||
if(sortItem == null){
|
if(sortItem == null){
|
||||||
other.items().endTake(item);
|
other.items.endTake(item);
|
||||||
}else{
|
}else{
|
||||||
other.items().remove(item, 1);
|
other.items.remove(item, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,18 @@ public class ItemModule extends BlockModule{
|
|||||||
|
|
||||||
private @Nullable WindowedMean[] flow;
|
private @Nullable WindowedMean[] flow;
|
||||||
|
|
||||||
|
public ItemModule copy(){
|
||||||
|
ItemModule out = new ItemModule();
|
||||||
|
out.set(this);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(ItemModule other){
|
||||||
|
total = other.total;
|
||||||
|
takeRotation = other.takeRotation;
|
||||||
|
System.arraycopy(other.items, 0, items, 0, items.length);
|
||||||
|
}
|
||||||
|
|
||||||
public void update(boolean showFlow){
|
public void update(boolean showFlow){
|
||||||
if(showFlow){
|
if(showFlow){
|
||||||
if(flow == null){
|
if(flow == null){
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class SStats implements SteamUserStatsCallback{
|
|||||||
});
|
});
|
||||||
|
|
||||||
Events.on(Trigger.newGame, () -> Core.app.post(() -> {
|
Events.on(Trigger.newGame, () -> Core.app.post(() -> {
|
||||||
if(campaign() && player.core() != null && player.core().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=6a8eb57007ff1b0ae465fbfe9983edb585964823
|
archash=0582cfd3b405d534c948383578c7a3f0c0d9dd6b
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ public class ServerControl implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
state.teams.cores(team).first().items().set(item, state.teams.cores(team).first().block().itemCapacity);
|
state.teams.cores(team).first().items.set(item, state.teams.cores(team).first().block().itemCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
info("Core filled.");
|
info("Core filled.");
|
||||||
|
|||||||
@@ -2,19 +2,18 @@ package mindustry.tools;
|
|||||||
|
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.graphics.Color;
|
import arc.graphics.Color;
|
||||||
import arc.graphics.g2d.TextureRegion;
|
import arc.graphics.g2d.*;
|
||||||
import arc.util.Structs;
|
import arc.struct.*;
|
||||||
import mindustry.tools.ImagePacker.GenRegion;
|
import arc.util.*;
|
||||||
|
import mindustry.tools.ImagePacker.*;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.*;
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
class Image{
|
class Image{
|
||||||
private static ArrayList<Image> toDispose = new ArrayList<>();
|
private static Seq<Image> toDispose = new Seq<>();
|
||||||
|
|
||||||
private BufferedImage image;
|
private BufferedImage image;
|
||||||
private Graphics2D graphics;
|
private Graphics2D graphics;
|
||||||
@@ -135,7 +134,7 @@ class Image{
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int total(){
|
static int total(){
|
||||||
return toDispose.size();
|
return toDispose.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispose(){
|
static void dispose(){
|
||||||
|
|||||||
Reference in New Issue
Block a user