Merge remote-tracking branch 'origin/master'

This commit is contained in:
Joshua Fan
2020-12-05 22:56:34 -08:00
24 changed files with 208 additions and 120 deletions

View File

@@ -47,8 +47,6 @@ public class Vars implements Loadable{
public static final int bufferSize = 8192;
/** global charset, since Android doesn't support the Charsets class */
public static final Charset charset = Charset.forName("UTF-8");
/** mods suggested for import */
public static final String[] suggestedMods = {""};
/** main application name, capitalized */
public static final String appName = "Mindustry";
/** URL for itch.io donations. */

View File

@@ -341,7 +341,7 @@ public class Control implements ApplicationListener, Loadable{
state.rules.waves = true;
//reset win wave??
state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : state.rules.winWave > state.wave ? state.rules.winWave : 40;
state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null && sector.preset.captureWave > 0 ? sector.preset.captureWave : state.rules.winWave > state.wave ? state.rules.winWave : 40;
//if there's still an enemy base left, fix it
if(state.rules.attackMode){

View File

@@ -153,6 +153,18 @@ public class Logic implements ApplicationListener{
}
});
//send out items to each client
Events.on(TurnEvent.class, e -> {
if(net.server() && state.isCampaign()){
int[] out = new int[content.items().size];
state.getSector().info.production.each((item, stat) -> {
out[item.id] = Math.max(0, (int)(stat.mean * turnDuration / 60));
});
Call.sectorProduced(out);
}
});
}
/** Adds starting items, resets wave time, and sets state to playing. */
@@ -243,8 +255,10 @@ public class Logic implements ApplicationListener{
}
private void updateWeather(){
state.rules.weather.removeAll(w -> w.weather == null);
for(WeatherEntry entry : state.rules.weather){
if(entry.weather == null) continue;
//update cooldown
entry.cooldown -= Time.delta;
@@ -295,8 +309,46 @@ public class Logic implements ApplicationListener{
public static void researched(Content content){
if(!(content instanceof UnlockableContent u)) return;
var node = u.node();
//unlock all direct dependencies on client, permanently
while(node != null){
node.content.unlock();
node = node.parent;
}
state.rules.researched.add(u.name);
Events.fire(new UnlockEvent(u));
}
//called when the remote server runs a turn and produces something
@Remote
public static void sectorProduced(int[] amounts){
if(!state.isCampaign()) return;
Planet planet = state.rules.sector.planet;
boolean any = false;
for(Item item : content.items()){
int am = amounts[item.id];
if(am > 0){
int sumMissing = planet.sectors.sum(s -> s.hasBase() ? s.info.storageCapacity - s.info.items.get(item) : 0);
if(sumMissing == 0) continue;
//how much % to add
double percent = Math.min((double)am / sumMissing, 1);
for(Sector sec : planet.sectors){
if(sec.hasBase()){
int added = (int)Math.ceil(((sec.info.storageCapacity - sec.info.items.get(item)) * percent));
sec.info.items.add(item, added);
any = true;
}
}
}
}
if(any){
for(Sector sec : planet.sectors){
sec.saveInfo();
}
}
}
@Override

View File

@@ -615,6 +615,7 @@ public class World{
GenerateInput input = new GenerateInput();
for(GenerateFilter filter : filters){
filter.randomize();
input.begin(filter, width(), height(), (x, y) -> tiles.getn(x, y));
filter.apply(tiles, input);
}

View File

@@ -117,7 +117,7 @@ public abstract class UnlockableContent extends MappableContent{
/** Makes this piece of content unlocked; if it already unlocked, nothing happens. */
public void unlock(){
if(!net.client() && !unlocked()){
if(!unlocked && !alwaysUnlocked){
unlocked = true;
Core.settings.put(name + "-unlocked", true);
@@ -135,7 +135,7 @@ public abstract class UnlockableContent extends MappableContent{
}
public boolean unlocked(){
if(net != null && net.client()) return alwaysUnlocked || state.rules.researched.contains(name);
if(net != null && net.client()) return unlocked || alwaysUnlocked || state.rules.researched.contains(name);
return unlocked || alwaysUnlocked;
}

View File

@@ -130,7 +130,7 @@ public class SectorInfo{
}
//if there are infinite waves and no win wave, add a win wave.
if(waves && winWave <= 0 && !attack){
if(winWave <= 0 && !attack){
winWave = 30;
}

View File

@@ -547,6 +547,22 @@ public class TypeIO{
return read.b(new byte[length]);
}
public static void writeInts(Writes write, int[] ints){
write.s((short)ints.length);
for(int i : ints){
write.i(i);
}
}
public static int[] readInts(Reads read){
short length = read.s();
int[] out = new int[length];
for(int i = 0; i < length; i++){
out[i] = read.i();
}
return out;
}
public static void writeTraceInfo(Writes write, TraceInfo trace){
writeString(write, trace.ip);
writeString(write, trace.uuid);

View File

@@ -114,6 +114,7 @@ public abstract class LStatement{
t.actions(Actions.alpha(0), Actions.fadeIn(0.3f, Interp.fade));
t.top().pane(inner -> {
inner.marginRight(24f);
inner.top();
hideCons.get(inner, hide);
}).top();

View File

@@ -528,7 +528,9 @@ public class LStatements{
stack.clearChildren();
stack.addChild(tables[selected]);
t.pack();
t.parent.parent.pack();
t.parent.parent.invalidateHierarchy();
}).size(80f, 50f).growX().checked(selected == fi).group(group);
}
t.row();

View File

@@ -23,24 +23,27 @@ public abstract class GenerateFilter{
//buffer of tiles used, each tile packed into a long struct
long[] buffer = new long[tiles.width * tiles.height];
//save to buffer
for(int i = 0; i < tiles.width * tiles.height; i++){
Tile tile = tiles.geti(i);
buffer[i] = PackTile.get(tile.blockID(), tile.floorID(), tile.overlayID());
in.apply(tile.x, tile.y, tile.block(), tile.floor(), tile.overlay());
apply();
buffer[i] = PackTile.get(in.block.id, in.floor.id, in.overlay.id);
}
//write to buffer
for(int i = 0; i < tiles.width * tiles.height; i++){
Tile tile = tiles.geti(i);
long b = buffer[i];
in.apply(tile.x, tile.y, Vars.content.block(PackTile.block(b)), Vars.content.block(PackTile.floor(b)), Vars.content.block(PackTile.overlay(b)));
apply();
Block block = Vars.content.block(PackTile.block(b)), floor = Vars.content.block(PackTile.floor(b)), overlay = Vars.content.block(PackTile.overlay(b));
tile.setFloor(in.floor.asFloor());
tile.setOverlay(!in.floor.asFloor().hasSurface() && in.overlay.asFloor().needsSurface ? Blocks.air : in.overlay);
tile.setFloor(floor.asFloor());
tile.setOverlay(!floor.asFloor().hasSurface() && overlay.asFloor().needsSurface ? Blocks.air : overlay);
if(!tile.block().synthetic() && !in.block.synthetic()){
tile.setBlock(in.block);
if(!tile.block().synthetic() && !block.synthetic()){
tile.setBlock(block);
}
}
}else{

View File

@@ -68,7 +68,7 @@ public class ArcNetProvider implements NetProvider{
}
});
server = new Server(8192, 8192, new PacketSerializer());
server = new Server(32768, 8192, new PacketSerializer());
server.setMulticast(multicastGroup, multicastPort);
server.setDiscoveryHandler((address, handler) -> {
ByteBuffer buffer = NetworkIO.writeServerData();

View File

@@ -67,7 +67,7 @@ public class Fonts{
}
public static int cursorScale(){
return Math.max(1, Mathf.round(Scl.scl(1f)));
return 1;
}
public static void loadFonts(){

View File

@@ -105,13 +105,9 @@ public class ModsDialog extends BaseDialog{
t.button("@mod.import.github", Icon.github, bstyle, () -> {
dialog.hide();
var modString = Core.settings.getString("lastmod", "");
var suggested = Structs.random(suggestedMods);
ui.showTextInput("@mod.import.github", "", 64, modString.isEmpty() ? suggested : modString, text -> {
if(!modString.isEmpty() || !Structs.eq(suggested, text)){
Core.settings.put("lastmod", text);
}
ui.showTextInput("@mod.import.github", "", 64, Core.settings.getString("lastmod", ""), text -> {
Core.settings.put("lastmod", text);
ui.loadfrag.show();
//Try to download the 6.0 branch first, but if it doesn't exist, try master.

View File

@@ -254,6 +254,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
boolean canSelect(Sector sector){
if(mode == select) return sector.hasBase();
if(sector.hasBase()) return true;
//preset sectors can only be selected once unlocked
if(sector.preset != null){
TechNode node = sector.preset.node();
@@ -709,7 +710,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
stable.image().color(Pal.accent).fillX().height(3f).pad(3f).row();
boolean locked = sector.preset != null && sector.preset.locked() && sector.preset.node() != null;
boolean locked = sector.preset != null && sector.preset.locked() && !sector.hasBase() && sector.preset.node() != null;
if(locked){
stable.table(r -> {
@@ -805,7 +806,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
return;
}
if(sector.preset != null && sector.preset.locked()){
if(sector.preset != null && sector.preset.locked() && !sector.hasBase()){
return;
}

View File

@@ -172,16 +172,6 @@ public class ResearchDialog extends BaseDialog{
});
}
@Override
public Dialog show(){
if(net.client()){
ui.showInfo("@research.multiplayer");
return this;
}
return super.show();
}
void treeLayout(){
float spacing = 20f;
LayoutNode node = new LayoutNode(root, null);
@@ -439,6 +429,14 @@ public class ResearchDialog extends BaseDialog{
void unlock(TechNode node){
node.content.unlock();
//unlock parent nodes in multiplayer.
TechNode parent = node.parent;
while(parent != null){
parent.content.unlock();
parent = parent.parent;
}
checkNodes(root);
hoverNode = null;
treeLayout();

View File

@@ -173,6 +173,7 @@ public class HintsFragment extends Fragment{
&& SectorPresets.frozenForest.sector.save == null,
() -> state.isCampaign() && state.getSector().preset == SectorPresets.frozenForest),
coreIncinerate(() -> state.isCampaign() && state.rules.defaultTeam.core() != null && state.rules.defaultTeam.core().items.get(Items.copper) >= state.rules.defaultTeam.core().storageCapacity - 10, () -> false),
coopCampaign(() -> net.client() && state.isCampaign() && SectorPresets.groundZero.sector.hasBase(), () -> false),
;
@Nullable

View File

@@ -318,9 +318,10 @@ public class LogicBlock extends Block{
//store any older variables
for(Var var : executor.vars){
if(!var.constant){
boolean unit = var.name.equals("@unit");
if(!var.constant || unit){
BVar dest = asm.getVar(var.name);
if(dest != null && !dest.constant){
if(dest != null && (!dest.constant || unit)){
dest.value = var.isobj ? var.objval : var.numval;
}
}

View File

@@ -6,6 +6,7 @@ import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
@@ -246,17 +247,18 @@ public class CoreBlock extends StorageBlock{
}
state.teams.registerCore(this);
storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) && owns(e) ? e.block.itemCapacity : 0);
proximity.each(e -> isContainer(e) && owns(e), t -> {
storageCapacity = itemCapacity + proximity().sum(e -> owns(e) ? e.block.itemCapacity : 0);
proximity.each(e -> owns(e), t -> {
t.items = items;
((StorageBuild)t).linkedCore = this;
});
for(Building other : state.teams.cores(team)){
if(other.tile() == tile) continue;
storageCapacity += other.block.itemCapacity + other.proximity().sum(e -> isContainer(e) && owns(other, e) ? e.block.itemCapacity : 0);
storageCapacity += other.block.itemCapacity + other.proximity().sum(e -> owns(e) && owns(other, e) ? e.block.itemCapacity : 0);
}
//Team.sharded.core().items.set(Items.surgeAlloy, 12000)
if(!world.isGenerating()){
for(Item item : content.items()){
items.set(item, Math.min(items.get(item), storageCapacity));
@@ -303,24 +305,19 @@ public class CoreBlock extends StorageBlock{
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 -> owns(e) && e.items == items)){
outline.get(this);
}
proximity.each(e -> isContainer(e) && e.items == items, outline);
proximity.each(e -> owns(e) && e.items == items, outline);
Draw.reset();
}
public boolean isContainer(Building tile){
return tile instanceof StorageBuild && (((StorageBuild)tile).linkedCore == this || ((StorageBuild)tile).linkedCore == null);
}
public boolean owns(Building tile){
return tile instanceof StorageBuild && (((StorageBuild)tile).linkedCore == this || ((StorageBuild)tile).linkedCore == null);
return owns(this, tile);
}
public boolean owns(Building core, Building tile){
return tile instanceof StorageBuild && (((StorageBuild)tile).linkedCore == core || ((StorageBuild)tile).linkedCore == null);
return tile instanceof StorageBuild b && (b.linkedCore == core || b.linkedCore == null);
}
public boolean incinerate(){
@@ -340,7 +337,7 @@ public class CoreBlock extends StorageBlock{
int total = proximity.count(e -> e.items != null && e.items == items);
float fract = 1f / total / state.teams.cores(team).size;
proximity.each(e -> isContainer(e) && e.items == items && owns(e), t -> {
proximity.each(e -> owns(e) && e.items == items && owns(e), t -> {
StorageBuild ent = (StorageBuild)t;
ent.linkedCore = null;
ent.items = new ItemModule();

View File

@@ -91,14 +91,16 @@ public class StorageBlock extends Block{
@Override
public void overwrote(Seq<Building> previous){
for(Building other : previous){
if(other.items != null){
items.add(other.items);
//only add prev items when core is not linked
if(linkedCore == null){
for(Building other : previous){
if(other.items != null && other.items != items){
items.add(other.items);
}
}
}
//ensure item counts are not too high
items.each((i, a) -> items.set(i, Math.min(a, itemCapacity)));
items.each((i, a) -> items.set(i, Math.min(a, itemCapacity)));
}
}
@Override