Merge branch 'master' of https://github.com/Anuken/Mindustry into 7.0-features
Conflicts: core/assets/icons/icons.properties core/assets/logicids.dat core/src/mindustry/ui/dialogs/PlanetDialog.java core/src/mindustry/world/blocks/distribution/ItemBridge.java core/src/mindustry/world/blocks/liquid/LiquidExtendingBridge.java core/src/mindustry/world/blocks/storage/StorageBlock.java gradle.properties
This commit is contained in:
@@ -284,6 +284,21 @@ public class EventType{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after a building's team changes.
|
||||
* Event object is reused, do not nest!
|
||||
* */
|
||||
public static class BuildTeamChangeEvent{
|
||||
public Team previous;
|
||||
public Building build;
|
||||
|
||||
public BuildTeamChangeEvent set(Team previous, Building build){
|
||||
this.build = build;
|
||||
this.previous = previous;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/** Called when a core block is placed/removed or its team is changed. */
|
||||
public static class CoreChangeEvent{
|
||||
public CoreBuild core;
|
||||
|
||||
@@ -23,7 +23,7 @@ public enum Gamemode{
|
||||
rules.waves = true;
|
||||
rules.waveTimer = true;
|
||||
|
||||
rules.waveSpacing = 60f * Time.toMinutes;
|
||||
rules.waveSpacing = 2f * Time.toMinutes;
|
||||
rules.teams.get(rules.waveTeam).infiniteResources = true;
|
||||
}, map -> map.teams.contains(state.rules.waveTeam.id)),
|
||||
pvp(rules -> {
|
||||
|
||||
@@ -50,7 +50,7 @@ public class Rules{
|
||||
public boolean unitAmmo = false;
|
||||
/** Whether cores add to unit limit */
|
||||
public boolean unitCapVariable = true;
|
||||
/** How fast unit pads build units. */
|
||||
/** How fast unit factories build units. */
|
||||
public float unitBuildSpeedMultiplier = 1f;
|
||||
/** How much damage any other units deal. */
|
||||
public float unitDamageMultiplier = 1f;
|
||||
@@ -94,6 +94,8 @@ public class Rules{
|
||||
public Seq<WeatherEntry> weather = new Seq<>(1);
|
||||
/** Blocks that cannot be placed. */
|
||||
public ObjectSet<Block> bannedBlocks = new ObjectSet<>();
|
||||
/** Units that cannot be built. */
|
||||
public ObjectSet<UnitType> bannedUnits = new ObjectSet<>();
|
||||
/** Reveals blocks normally hidden by build visibility. */
|
||||
public ObjectSet<Block> revealedBlocks = new ObjectSet<>();
|
||||
/** Unlocked content names. Only used in multiplayer when the campaign is enabled. */
|
||||
@@ -109,6 +111,8 @@ public class Rules{
|
||||
public Team defaultTeam = Team.sharded;
|
||||
/** team of the enemy in waves/sectors. */
|
||||
public Team waveTeam = Team.crux;
|
||||
/** color of clouds that is displayed when the player is landing */
|
||||
public Color cloudColor = new Color(0f, 0f, 0f, 0f);
|
||||
/** name of the custom mode that this ruleset describes, or null. */
|
||||
public @Nullable String modeName;
|
||||
/** Whether cores incinerate items when full, just like in the campaign. */
|
||||
|
||||
@@ -114,6 +114,7 @@ public class Schematics implements Loadable{
|
||||
target.tiles.addAll(newSchematic.tiles);
|
||||
target.width = newSchematic.width;
|
||||
target.height = newSchematic.height;
|
||||
newSchematic.labels = target.labels;
|
||||
newSchematic.tags.putAll(target.tags);
|
||||
newSchematic.file = target.file;
|
||||
|
||||
@@ -432,6 +433,11 @@ public class Schematics implements Loadable{
|
||||
if(seq.contains(t -> !t.block().alwaysReplace && !t.synthetic())){
|
||||
return;
|
||||
}
|
||||
for(var t : seq){
|
||||
if(t.block() != Blocks.air){
|
||||
t.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tile.setBlock(st.block, team, st.rotation);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package mindustry.game;
|
||||
|
||||
import arc.func.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
@@ -21,6 +22,7 @@ public class SectorInfo{
|
||||
private static final int valueWindow = 60;
|
||||
/** refresh period of export in ticks */
|
||||
private static final float refreshPeriod = 60;
|
||||
private static float returnf;
|
||||
|
||||
/** Core input statistics. */
|
||||
public ObjectMap<Item, ExportStat> production = new ObjectMap<>();
|
||||
@@ -76,6 +78,8 @@ public class SectorInfo{
|
||||
public int waveVersion = -1;
|
||||
/** Whether this sector was indicated to the player or not. */
|
||||
public boolean shown = false;
|
||||
/** Temporary seq for last imported items. Do not use. */
|
||||
public transient ItemSeq lastImported = new ItemSeq();
|
||||
|
||||
/** Special variables for simulation. */
|
||||
public float sumHealth, sumRps, sumDps, waveHealthBase, waveHealthSlope, waveDpsBase, waveDpsSlope, bossHealth, bossDps, curEnemyHealth, curEnemyDps;
|
||||
@@ -265,23 +269,29 @@ public class SectorInfo{
|
||||
return map;
|
||||
}
|
||||
|
||||
public boolean anyExports(){
|
||||
if(export.size == 0) return false;
|
||||
returnf = 0f;
|
||||
export.each((i, e) -> returnf += e.mean);
|
||||
return returnf >= 0.01f;
|
||||
}
|
||||
|
||||
/** @return a newly allocated map with import statistics. Use sparingly. */
|
||||
//TODO this can be a float map
|
||||
public ObjectMap<Item, ExportStat> importStats(){
|
||||
public ObjectMap<Item, ExportStat> importStats(Planet planet){
|
||||
ObjectMap<Item, ExportStat> imports = new ObjectMap<>();
|
||||
//for all sectors on all planets that have bases and export to this sector
|
||||
for(Planet planet : content.planets()){
|
||||
for(Sector sector : planet.sectors){
|
||||
Sector dest = sector.info.getRealDestination();
|
||||
if(sector.hasBase() && sector.info != this && dest != null && dest.info == this){
|
||||
//add their exports to our imports
|
||||
sector.info.export.each((item, stat) -> {
|
||||
imports.get(item, ExportStat::new).mean += stat.mean;
|
||||
});
|
||||
}
|
||||
eachImport(planet, sector -> sector.info.export.each((item, stat) -> imports.get(item, ExportStat::new).mean += stat.mean));
|
||||
return imports;
|
||||
}
|
||||
|
||||
/** Iterates through every sector this one imports from. */
|
||||
public void eachImport(Planet planet, Cons<Sector> cons){
|
||||
for(Sector sector : planet.sectors){
|
||||
Sector dest = sector.info.getRealDestination();
|
||||
if(sector.hasBase() && sector.info != this && dest != null && dest.info == this){
|
||||
cons.get(sector);
|
||||
}
|
||||
}
|
||||
return imports;
|
||||
}
|
||||
|
||||
public static class ExportStat{
|
||||
|
||||
@@ -17,6 +17,8 @@ public class Team implements Comparable<Team>{
|
||||
public final int id;
|
||||
public final Color color;
|
||||
public final Color[] palette;
|
||||
public final int[] palettei = new int[3];
|
||||
public String emoji = "";
|
||||
public boolean hasPalette;
|
||||
public String name;
|
||||
|
||||
@@ -31,9 +33,9 @@ public class Team implements Comparable<Team>{
|
||||
Color.valueOf("ffd37f"), Color.valueOf("eab678"), Color.valueOf("d4816b")),
|
||||
crux = new Team(2, "crux", Color.valueOf("f25555"),
|
||||
Color.valueOf("fc8e6c"), Color.valueOf("f25555"), Color.valueOf("a04553")),
|
||||
green = new Team(3, "green", Color.valueOf("54d67d")),
|
||||
purple = new Team(4, "purple", Color.valueOf("995bb0")),
|
||||
blue = new Team(5, "blue", Color.valueOf("5a4deb"));
|
||||
green = new Team(3, "green", Color.valueOf("54d67d"), Color.valueOf("96f58c"), Color.valueOf("54d67d"), Color.valueOf("28785c")),
|
||||
purple = new Team(4, "purple", Color.valueOf("995bb0"), Color.valueOf("f08dd5"), Color.valueOf("995bb0"), Color.valueOf("312c63")),
|
||||
blue = new Team(5, "blue", Color.valueOf("554deb"), Color.valueOf("80aaff"), Color.valueOf("554deb"), Color.valueOf("3f207d"));
|
||||
|
||||
static{
|
||||
Mathf.rand.setSeed(8);
|
||||
@@ -60,6 +62,10 @@ public class Team implements Comparable<Team>{
|
||||
palette[0] = color;
|
||||
palette[1] = color.cpy().mul(0.75f);
|
||||
palette[2] = color.cpy().mul(0.5f);
|
||||
|
||||
for(int i = 0; i < 3; i++){
|
||||
palettei[i] = palette[i].rgba();
|
||||
}
|
||||
}
|
||||
|
||||
/** Specifies a 3-color team palette. */
|
||||
@@ -69,6 +75,9 @@ public class Team implements Comparable<Team>{
|
||||
palette[0] = pal1;
|
||||
palette[1] = pal2;
|
||||
palette[2] = pal3;
|
||||
for(int i = 0; i < 3; i++){
|
||||
palettei[i] = palette[i].rgba();
|
||||
}
|
||||
hasPalette = true;
|
||||
}
|
||||
|
||||
@@ -96,6 +105,11 @@ public class Team implements Comparable<Team>{
|
||||
return state.teams.isActive(this);
|
||||
}
|
||||
|
||||
/** @return whether this team is solely comprised of AI, with no players. */
|
||||
public boolean isAI(){
|
||||
return state.rules.waves && this == state.rules.waveTeam;
|
||||
}
|
||||
|
||||
public boolean isEnemy(Team other){
|
||||
return this != other;
|
||||
}
|
||||
|
||||
@@ -148,8 +148,35 @@ public class Universe{
|
||||
|
||||
//update relevant sectors
|
||||
for(Planet planet : content.planets()){
|
||||
|
||||
//first pass: clear import stats
|
||||
for(Sector sector : planet.sectors){
|
||||
if(sector.hasSave() && sector.hasBase()){
|
||||
if(sector.hasBase() && !sector.isBeingPlayed()){
|
||||
sector.info.lastImported.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//second pass: update export & import statistics
|
||||
for(Sector sector : planet.sectors){
|
||||
if(sector.hasBase() && !sector.isBeingPlayed()){
|
||||
|
||||
//export to another sector
|
||||
if(sector.info.destination != null){
|
||||
Sector to = sector.info.destination;
|
||||
if(to.hasBase()){
|
||||
ItemSeq items = new ItemSeq();
|
||||
//calculated exported items to this sector
|
||||
sector.info.export.each((item, stat) -> items.add(item, (int)(stat.mean * newSecondsPassed * sector.getProductionScale())));
|
||||
to.addItems(items);
|
||||
to.info.lastImported.add(items);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//third pass: everything else
|
||||
for(Sector sector : planet.sectors){
|
||||
if(sector.hasBase()){
|
||||
|
||||
//if it is being attacked, capture time is 0; otherwise, increment the timer
|
||||
if(sector.isAttacked()){
|
||||
@@ -199,26 +226,16 @@ public class Universe{
|
||||
|
||||
float scl = sector.getProductionScale();
|
||||
|
||||
//export to another sector
|
||||
if(sector.info.destination != null){
|
||||
Sector to = sector.info.destination;
|
||||
if(to.hasBase()){
|
||||
ItemSeq items = new ItemSeq();
|
||||
//calculated exported items to this sector
|
||||
sector.info.export.each((item, stat) -> items.add(item, (int)(stat.mean * newSecondsPassed * scl)));
|
||||
to.addItems(items);
|
||||
}
|
||||
}
|
||||
//add production, making sure that it's capped
|
||||
sector.info.production.each((item, stat) -> sector.info.items.add(item, Math.min((int)(stat.mean * newSecondsPassed * scl), sector.info.storageCapacity - sector.info.items.get(item))));
|
||||
|
||||
sector.info.export.each((item, amount) -> {
|
||||
if(sector.info.items.get(item) <= 0 && sector.info.production.get(item, ExportStat::new).mean < 0){
|
||||
//disable export when production is negative.
|
||||
sector.info.export.get(item).mean = 0f;
|
||||
sector.info.export.each((item, stat) -> {
|
||||
if(sector.info.items.get(item) <= 0 && sector.info.production.get(item, ExportStat::new).mean < 0 && stat.mean > 0){
|
||||
//cap export by import when production is negative.
|
||||
stat.mean = Math.min(sector.info.lastImported.get(item) / (float)newSecondsPassed, stat.mean);
|
||||
}
|
||||
});
|
||||
|
||||
//add production, making sure that it's capped
|
||||
sector.info.production.each((item, stat) -> sector.info.items.add(item, Math.min((int)(stat.mean * newSecondsPassed * scl), sector.info.storageCapacity - sector.info.items.get(item))));
|
||||
//prevent negative values with unloaders
|
||||
sector.info.items.checkNegative();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user