Compare commits

..

7 Commits
v114 ... v114.2

Author SHA1 Message Date
Anuken
054f0b2128 Fixed server not compiling 2020-11-17 10:26:50 -05:00
Anuken
1e2b593152 Added more validaiton for sector capture events 2020-11-17 10:20:57 -05:00
Anuken
b46676014b Fixed #3431 / Fixed #3432 / Fixed #3429 / Fixed #3435 / Fixed #3434 2020-11-17 10:18:08 -05:00
Anuken
3c36749990 Implemented automatic co-op sector change sync 2020-11-17 09:39:28 -05:00
Anuken
280e345faf Cleanup 2020-11-16 19:50:15 -05:00
Anuken
f296d23cfa Bugfixes 2020-11-16 19:43:56 -05:00
Anuken
3b609f698a Fixed #3422 2020-11-16 17:41:42 -05:00
37 changed files with 2628 additions and 2492 deletions

View File

@@ -138,7 +138,7 @@ public class AndroidLauncher extends AndroidApplication{
if(open){ if(open){
new FileChooser(title, file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show(); new FileChooser(title, file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show();
}else{ }else{
super.showFileChooser(open, extension, cons); super.showFileChooser(open, "@open", extension, cons);
} }
} }
} }

View File

@@ -17,7 +17,9 @@ linkfail = Failed to open link!\nThe URL has been copied to your clipboard.
screenshot = Screenshot saved to {0} screenshot = Screenshot saved to {0}
screenshot.invalid = Map too large, potentially not enough memory for screenshot. screenshot.invalid = Map too large, potentially not enough memory for screenshot.
gameover = Game Over gameover = Game Over
gameover.disconnect = Disconnect
gameover.pvp = The[accent] {0}[] team is victorious! gameover.pvp = The[accent] {0}[] team is victorious!
gameover.waiting = [accent]Waiting for next map...
highscore = [accent]New highscore! highscore = [accent]New highscore!
copied = Copied. copied = Copied.
indev.popup = [accent]v6[] is currently in [accent]beta[].\n[lightgray]This means:[]\n[scarlet]- The campaign is unfinished[]\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[]. indev.popup = [accent]v6[] is currently in [accent]beta[].\n[lightgray]This means:[]\n[scarlet]- The campaign is unfinished[]\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[].
@@ -544,6 +546,7 @@ sectors.select = Select
sectors.nonelaunch = [lightgray]none (sun) sectors.nonelaunch = [lightgray]none (sun)
sectors.rename = Rename Sector sectors.rename = Rename Sector
sector.curcapture = Sector Captured
sector.missingresources = [scarlet]Insufficient Core Resources sector.missingresources = [scarlet]Insufficient Core Resources
sector.attacked = Sector [accent]{0}[white] under attack! sector.attacked = Sector [accent]{0}[white] under attack!
sector.lost = Sector [accent]{0}[white] lost! sector.lost = Sector [accent]{0}[white] lost!

View File

@@ -17,9 +17,9 @@ const float shinelen = 0.2;
void main(){ void main(){
vec3 norc = u_ambientColor * (diffuse + vec3(clamp((dot(a_normal, u_lightdir) + 1.0) / 2.0, 0.0, 1.0))); vec3 norc = u_ambientColor * (diffuse + vec3(clamp((dot(a_normal, u_lightdir) + 1.0) / 2.0, 0.0, 1.0)));
float shinedot = max((-dot(u_camdir, a_normal) - (1.0 - shinelen)) / shinelen, 0.0); float shinedot = max((-dot(u_camdir, a_normal) - (1.0 - shinelen)) / shinelen, 0.0);
float shinyness = (1.0 - a_color.a) * pow(shinedot, shinefalloff); float albedo = (1.0 - a_color.a) * pow(shinedot, shinefalloff);
vec4 baseCol = vec4(a_color.rgb, 1.0); vec4 baseCol = vec4(a_color.rgb, 1.0);
v_col = mix(baseCol * vec4(norc, 1.0), vec4(1.0), shinyness * norc.r); v_col = mix(baseCol * vec4(norc, 1.0), vec4(1.0), albedo * norc.r);
gl_Position = u_proj * u_trans * a_position; gl_Position = u_proj * u_trans * a_position;
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 944 KiB

After

Width:  |  Height:  |  Size: 960 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 KiB

After

Width:  |  Height:  |  Size: 575 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 185 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 MiB

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 186 KiB

View File

@@ -9,6 +9,7 @@ import mindustry.type.*;
public class Planets implements ContentList{ public class Planets implements ContentList{
public static Planet public static Planet
sun, sun,
//tantros,
serpulo; serpulo;
@Override @Override
@@ -32,10 +33,23 @@ public class Planets implements ContentList{
); );
}}; }};
/*tantros = new Planet("tantros", sun, 2, 0.8f){{
generator = new TantrosPlanetGenerator();
meshLoader = () -> new HexMesh(this, 4);
atmosphereColor = Color.valueOf("3db899");
startSector = 10;
atmosphereRadIn = -0.01f;
atmosphereRadOut = 0.3f;
accessible = false;
visible = false;
}};*/
serpulo = new Planet("serpulo", sun, 3, 1){{ serpulo = new Planet("serpulo", sun, 3, 1){{
generator = new SerpuloPlanetGenerator(); generator = new SerpuloPlanetGenerator();
meshLoader = () -> new HexMesh(this, 6); meshLoader = () -> new HexMesh(this, 6);
atmosphereColor = Color.valueOf("3c1b8f"); atmosphereColor = Color.valueOf("3c1b8f");
atmosphereRadIn = 0.02f;
atmosphereRadOut = 0.3f;
startSector = 15; startSector = 15;
}}; }};
} }

View File

@@ -41,7 +41,7 @@ public class SectorPresets implements ContentList{
difficulty = 2; difficulty = 2;
}}; }};
ruinousShores = new SectorPreset("ruinousShores", serpulo, 19){{ ruinousShores = new SectorPreset("ruinousShores", serpulo, 213){{
captureWave = 30; captureWave = 30;
difficulty = 3; difficulty = 3;
}}; }};

View File

@@ -53,7 +53,7 @@ public class Weathers implements ContentList{
baseSpeed = 5.4f; baseSpeed = 5.4f;
attrs.set(Attribute.light, -0.1f); attrs.set(Attribute.light, -0.1f);
attrs.set(Attribute.water, -0.1f); attrs.set(Attribute.water, -0.1f);
opacityMultiplier = 0.8f; opacityMultiplier = 0.5f;
force = 0.1f; force = 0.1f;
sound = Sounds.wind; sound = Sounds.wind;
soundVol = 0.3f; soundVol = 0.3f;
@@ -74,7 +74,7 @@ public class Weathers implements ContentList{
attrs.set(Attribute.spores, 1f); attrs.set(Attribute.spores, 1f);
attrs.set(Attribute.light, -0.15f); attrs.set(Attribute.light, -0.15f);
status = StatusEffects.sporeSlowed; status = StatusEffects.sporeSlowed;
opacityMultiplier = 0.85f; opacityMultiplier = 0.75f;
force = 0.1f; force = 0.1f;
sound = Sounds.wind; sound = Sounds.wind;
soundVol = 0.3f; soundVol = 0.3f;

View File

@@ -22,6 +22,7 @@ import mindustry.input.*;
import mindustry.io.*; import mindustry.io.*;
import mindustry.io.SaveIO.*; import mindustry.io.SaveIO.*;
import mindustry.maps.Map; import mindustry.maps.Map;
import mindustry.net.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.ui.dialogs.*; import mindustry.ui.dialogs.*;
import mindustry.world.*; import mindustry.world.*;
@@ -162,7 +163,7 @@ public class Control implements ApplicationListener, Loadable{
Events.on(GameOverEvent.class, e -> { Events.on(GameOverEvent.class, e -> {
if(state.isCampaign() && !net.client() && !headless){ if(state.isCampaign() && !net.client() && !headless){
//delete the save, it is gone. //save gameover sate immediately
if(saves.getCurrent() != null && !state.rules.tutorial){ if(saves.getCurrent() != null && !state.rules.tutorial){
saves.getCurrent().save(); saves.getCurrent().save();
} }
@@ -279,6 +280,10 @@ public class Control implements ApplicationListener, Loadable{
} }
public void playSector(@Nullable Sector origin, Sector sector){ public void playSector(@Nullable Sector origin, Sector sector){
playSector(origin, sector, new WorldReloader());
}
void playSector(@Nullable Sector origin, Sector sector, WorldReloader reloader){
ui.loadAnd(() -> { ui.loadAnd(() -> {
if(saves.getCurrent() != null && state.isGame()){ if(saves.getCurrent() != null && state.isGame()){
control.saves.getCurrent().save(); control.saves.getCurrent().save();
@@ -291,7 +296,7 @@ public class Control implements ApplicationListener, Loadable{
if(slot != null && !clearSectors){ if(slot != null && !clearSectors){
try{ try{
net.reset(); reloader.begin();
slot.load(); slot.load();
slot.setAutosave(true); slot.setAutosave(true);
state.rules.sector = sector; state.rules.sector = sector;
@@ -305,7 +310,7 @@ public class Control implements ApplicationListener, Loadable{
sector.save = null; sector.save = null;
slot.delete(); slot.delete();
//play again //play again
playSector(origin, sector); playSector(origin, sector, reloader);
return; return;
} }
@@ -331,6 +336,7 @@ public class Control implements ApplicationListener, Loadable{
} }
state.set(State.playing); state.set(State.playing);
reloader.end();
}catch(SaveException e){ }catch(SaveException e){
Log.err(e); Log.err(e);
@@ -341,8 +347,7 @@ public class Control implements ApplicationListener, Loadable{
} }
ui.planet.hide(); ui.planet.hide();
}else{ }else{
net.reset(); reloader.begin();
logic.reset();
world.loadSector(sector); world.loadSector(sector);
state.rules.sector = sector; state.rules.sector = sector;
//assign origin when launching //assign origin when launching
@@ -352,6 +357,7 @@ public class Control implements ApplicationListener, Loadable{
control.saves.saveSector(sector); control.saves.saveSector(sector);
Events.fire(new SectorLaunchEvent(sector)); Events.fire(new SectorLaunchEvent(sector));
Events.fire(Trigger.newGame); Events.fire(Trigger.newGame);
reloader.end();
} }
}); });
} }
@@ -484,7 +490,7 @@ public class Control implements ApplicationListener, Loadable{
//unlock core items //unlock core items
var core = state.rules.defaultTeam.core(); var core = state.rules.defaultTeam.core();
if(!net.client() && core != null){ if(!net.client() && core != null && state.isCampaign()){
core.items.each((i, a) -> i.unlock()); core.items.each((i, a) -> i.unlock());
} }

View File

@@ -123,7 +123,7 @@ public class Logic implements ApplicationListener{
}); });
Events.on(SectorCaptureEvent.class, e -> { Events.on(SectorCaptureEvent.class, e -> {
if(!net.client()){ if(!net.client() && e.sector == state.getSector() && e.sector.isBeingPlayed()){
for(Tile tile : world.tiles){ for(Tile tile : world.tiles){
//convert all blocks to neutral, randomly killing them //convert all blocks to neutral, randomly killing them
if(tile.isCenter() && tile.build != null && tile.build.team == state.rules.waveTeam){ if(tile.isCenter() && tile.build != null && tile.build.team == state.rules.waveTeam){

View File

@@ -519,7 +519,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
public void dumpLiquid(Liquid liquid){ public void dumpLiquid(Liquid liquid){
int dump = this.cdump; int dump = this.cdump;
if(!net.client()) liquid.unlock(); if(!net.client() && state.isCampaign()) liquid.unlock();
for(int i = 0; i < proximity.size; i++){ for(int i = 0; i < proximity.size; i++){
incrementDump(proximity.size); incrementDump(proximity.size);
@@ -620,7 +620,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
*/ */
public void offload(Item item){ public void offload(Item item){
int dump = this.cdump; int dump = this.cdump;
if(!net.client()) item.unlock(); if(!net.client() && state.isCampaign()) item.unlock();
for(int i = 0; i < proximity.size; i++){ for(int i = 0; i < proximity.size; i++){
incrementDump(proximity.size); incrementDump(proximity.size);
@@ -1358,6 +1358,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
@Final @Final
@Override @Override
public void update(){ public void update(){
if(state.isEditor()) return;
timeScaleDuration -= Time.delta; timeScaleDuration -= Time.delta;
if(timeScaleDuration <= 0f || !block.canOverdrive){ if(timeScaleDuration <= 0f || !block.canOverdrive){
timeScale = 1f; timeScale = 1f;

View File

@@ -24,8 +24,8 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
/** weapon mount array, never null */ /** weapon mount array, never null */
@SyncLocal WeaponMount[] mounts = {}; @SyncLocal WeaponMount[] mounts = {};
@ReadOnly transient float aimX, aimY;
@ReadOnly transient boolean isRotate; @ReadOnly transient boolean isRotate;
transient float aimX, aimY;
boolean isShooting; boolean isShooting;
float ammo; float ammo;

View File

@@ -142,6 +142,10 @@ public class AIController implements UnitController{
mount.rotate = shoot; mount.rotate = shoot;
unit.isShooting |= shoot; unit.isShooting |= shoot;
if(shoot){
unit.aimX = mount.aimX;
unit.aimY = mount.aimY;
}
} }
} }

View File

@@ -71,8 +71,8 @@ public class Shaders{
setUniformf("u_rcampos", Tmp.v31.set(camera.position).sub(planet.position)); setUniformf("u_rcampos", Tmp.v31.set(camera.position).sub(planet.position));
setUniformf("u_light", planet.getLightNormal()); setUniformf("u_light", planet.getLightNormal());
setUniformf("u_color", planet.atmosphereColor.r, planet.atmosphereColor.g, planet.atmosphereColor.b); setUniformf("u_color", planet.atmosphereColor.r, planet.atmosphereColor.g, planet.atmosphereColor.b);
setUniformf("u_innerRadius", planet.radius + 0.02f); setUniformf("u_innerRadius", planet.radius + planet.atmosphereRadIn);
setUniformf("u_outerRadius", planet.radius * 1.3f); setUniformf("u_outerRadius", planet.radius + planet.atmosphereRadOut);
setUniformMatrix4("u_model", planet.getTransform(mat).val); setUniformMatrix4("u_model", planet.getTransform(mat).val);
setUniformMatrix4("u_projection", camera.combined.val); setUniformMatrix4("u_projection", camera.combined.val);

View File

@@ -77,8 +77,6 @@ public class MeshBuilder{
if(c.length > 5){ if(c.length > 5){
verts(c[0].v, c[4].v, c[5].v, nor, color); verts(c[0].v, c[4].v, c[5].v, nor, color);
}else{
verts(c[0].v, c[3].v, c[4].v, nor, color);
} }
} }

View File

@@ -57,6 +57,7 @@ public class PlanetRenderer implements Disposable{
camPos.set(0, 0f, camLength); camPos.set(0, 0f, camLength);
projector.setScaling(1f / 150f); projector.setScaling(1f / 150f);
cam.fov = 60f; cam.fov = 60f;
cam.far = 150f;
} }
/** Render the entire planet scene to the screen. */ /** Render the entire planet scene to the screen. */
@@ -93,6 +94,8 @@ public class PlanetRenderer implements Disposable{
renderPlanet(solarSystem); renderPlanet(solarSystem);
renderTransparent(solarSystem);
endBloom(); endBloom();
Events.fire(Trigger.universeDrawEnd); Events.fire(Trigger.universeDrawEnd);
@@ -125,11 +128,21 @@ public class PlanetRenderer implements Disposable{
renderOrbit(planet); renderOrbit(planet);
for(Planet child : planet.children){
renderPlanet(child);
}
}
public void renderTransparent(Planet planet){
if(!planet.visible()) return;
if(planet.isLandable() && planet == this.planet){ if(planet.isLandable() && planet == this.planet){
renderSectors(planet); renderSectors(planet);
} }
if(planet.parent != null && planet.hasAtmosphere && Core.settings.getBool("atmosphere")){ if(planet.parent != null && planet.hasAtmosphere && Core.settings.getBool("atmosphere")){
Gl.depthMask(false);
Blending.additive.apply(); Blending.additive.apply();
Shaders.atmosphere.camera = cam; Shaders.atmosphere.camera = cam;
@@ -140,10 +153,12 @@ public class PlanetRenderer implements Disposable{
atmosphere.render(Shaders.atmosphere, Gl.triangles); atmosphere.render(Shaders.atmosphere, Gl.triangles);
Blending.normal.apply(); Blending.normal.apply();
Gl.depthMask(true);
} }
for(Planet child : planet.children){ for(Planet child : planet.children){
renderPlanet(child); renderTransparent(child);
} }
} }
@@ -152,7 +167,7 @@ public class PlanetRenderer implements Disposable{
Vec3 center = planet.parent.position; Vec3 center = planet.parent.position;
float radius = planet.orbitRadius; float radius = planet.orbitRadius;
int points = (int)(radius * 50); int points = (int)(radius * 10);
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray)); Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray));
batch.flush(Gl.lineLoop); batch.flush(Gl.lineLoop);
} }

View File

@@ -11,6 +11,7 @@ import mindustry.world.*;
public abstract class PlanetGenerator extends BasicGenerator implements HexMesher{ public abstract class PlanetGenerator extends BasicGenerator implements HexMesher{
protected IntSeq ints = new IntSeq(); protected IntSeq ints = new IntSeq();
protected Sector sector; protected Sector sector;
protected Simplex noise = new Simplex();
/** Should generate sector bases for a planet. */ /** Should generate sector bases for a planet. */
public void generateSector(Sector sector){ public void generateSector(Sector sector){
@@ -46,6 +47,12 @@ public abstract class PlanetGenerator extends BasicGenerator implements HexMeshe
} }
@Override
protected float noise(float x, float y, double octaves, double falloff, double scl, double mag){
Vec3 v = sector.rect.project(x, y);
return (float)noise.octaveNoise3D(octaves, falloff, 1f / scl, v.x, v.y, v.z) * (float)mag;
}
public void generate(Tiles tiles, Sector sec){ public void generate(Tiles tiles, Sector sec){
this.tiles = tiles; this.tiles = tiles;
this.sector = sec; this.sector = sec;

View File

@@ -16,7 +16,6 @@ import mindustry.world.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class SerpuloPlanetGenerator extends PlanetGenerator{ public class SerpuloPlanetGenerator extends PlanetGenerator{
Simplex noise = new Simplex();
RidgedPerlin rid = new RidgedPerlin(1, 2); RidgedPerlin rid = new RidgedPerlin(1, 2);
BaseGenerator basegen = new BaseGenerator(); BaseGenerator basegen = new BaseGenerator();
float scl = 5f; float scl = 5f;

View File

@@ -0,0 +1,21 @@
package mindustry.maps.planet;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
import mindustry.maps.generators.*;
public class TantrosPlanetGenerator extends PlanetGenerator{
Color c1 = Color.valueOf("5057a6"), c2 = Color.valueOf("272766"), out = new Color();
@Override
public float getHeight(Vec3 position){
return 0;
}
@Override
public Color getColor(Vec3 position){
float depth = (float)noise.octaveNoise3D(2, 0.56, 1.7f, position.x, position.y, position.z) / 1.7f;
return c1.write(out).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(0.6f);
}
}

View File

@@ -0,0 +1,59 @@
package mindustry.net;
import arc.struct.*;
import arc.struct.Seq.*;
import mindustry.gen.*;
import static mindustry.Vars.*;
/** Handles player state for sending to every connected player*/
public class WorldReloader{
Seq<Player> players = new Seq<>();
boolean wasServer = false;
boolean began = false;
/** Begins reloading the world. Sends world begin packets to each user and stores player state.
* If the current client is not a server, this resets state and disconnects. */
public void begin(){
//don't begin twice
if(began) return;
if(wasServer = net.server()){
players.clear();
for(Player p : Groups.player){
if(p.isLocal()) continue;
players.add(p);
p.clearUnit();
}
logic.reset();
Call.worldDataBegin();
}else{
net.reset();
logic.reset();
}
began = true;
}
/** Ends reloading the world. Sends world data to each player.
* If the current client was not a server, does nothing.*/
public void end(){
if(wasServer){
for(Player p : players){
if(p.con == null) continue;
boolean wasAdmin = p.admin;
p.reset();
p.admin = wasAdmin;
if(state.rules.pvp){
p.team(netServer.assignTeam(p, new SeqIterable<>(players)));
}
netServer.sendWorldData(p);
}
}
}
}

View File

@@ -18,7 +18,7 @@ import static mindustry.Vars.*;
public class Planet extends UnlockableContent{ public class Planet extends UnlockableContent{
/** Default spacing between planet orbits in world units. */ /** Default spacing between planet orbits in world units. */
private static final float orbitSpacing = 10f; private static final float orbitSpacing = 9f;
/** intersect() temp var. */ /** intersect() temp var. */
private static final Vec3 intersectResult = new Vec3(); private static final Vec3 intersectResult = new Vec3();
/** Mesh used for rendering. Created on load() - will be null on the server! */ /** Mesh used for rendering. Created on load() - will be null on the server! */
@@ -33,6 +33,8 @@ public class Planet extends UnlockableContent{
public Seq<Sector> sectors; public Seq<Sector> sectors;
/** Radius of this planet's sphere. Does not take into account sattelites. */ /** Radius of this planet's sphere. Does not take into account sattelites. */
public float radius; public float radius;
/** Atmosphere radius adjustment parameters. */
public float atmosphereRadIn = 0, atmosphereRadOut = 0.3f;
/** Orbital radius around the sun. Do not change unless you know exactly what you are doing.*/ /** Orbital radius around the sun. Do not change unless you know exactly what you are doing.*/
public float orbitRadius; public float orbitRadius;
/** Total radius of this planet and all its children. */ /** Total radius of this planet and all its children. */
@@ -51,6 +53,8 @@ public class Planet extends UnlockableContent{
public int startSector = 0; public int startSector = 0;
/** Whether the bloom render effect is enabled. */ /** Whether the bloom render effect is enabled. */
public boolean bloom = false; public boolean bloom = false;
/** Whether this planet is displayed. */
public boolean visible = true;
/** For suns, this is the color that shines on other planets. Does nothing for children. */ /** For suns, this is the color that shines on other planets. Does nothing for children. */
public Color lightColor = Color.white.cpy(); public Color lightColor = Color.white.cpy();
/** Atmosphere tint for landable planets. */ /** Atmosphere tint for landable planets. */
@@ -264,7 +268,7 @@ public class Planet extends UnlockableContent{
} }
public boolean visible(){ public boolean visible(){
return true; return visible;
} }
public void draw(Mat3D projection, Mat3D transform){ public void draw(Mat3D projection, Mat3D transform){

View File

@@ -103,7 +103,7 @@ public class Sector{
/** @return whether the enemy has a generated base here. */ /** @return whether the enemy has a generated base here. */
public boolean hasEnemyBase(){ public boolean hasEnemyBase(){
return generateEnemyBase && (save == null || info.attack); return ((generateEnemyBase && preset == null) || (preset != null && preset.captureWave == 0)) && (save == null || info.attack);
} }
public boolean isBeingPlayed(){ public boolean isBeingPlayed(){
@@ -198,7 +198,7 @@ public class Sector{
} }
public String toString(){ public String toString(){
return planet.name + "#" + id; return planet.name + "#" + id + " (" + name() + ")";
} }
/** Projects this sector onto a 4-corner square for use in map gen. /** Projects this sector onto a 4-corner square for use in map gen.

View File

@@ -1,6 +1,7 @@
package mindustry.ui.dialogs; package mindustry.ui.dialogs;
import arc.*; import arc.*;
import mindustry.core.GameState.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.type.*; import mindustry.type.*;
@@ -15,6 +16,8 @@ public class GameOverDialog extends BaseDialog{
super("@gameover"); super("@gameover");
setFillParent(true); setFillParent(true);
shown(this::rebuild); shown(this::rebuild);
Events.on(ResetEvent.class, e -> hide());
} }
public void show(Team winner){ public void show(Team winner){
@@ -49,47 +52,51 @@ public class GameOverDialog extends BaseDialog{
cont.pane(t -> { cont.pane(t -> {
t.margin(13f); t.margin(13f);
t.left().defaults().left(); t.left().defaults().left();
t.add(Core.bundle.format("stat.wave", state.stats.wavesLasted)); t.add(Core.bundle.format("stat.wave", state.stats.wavesLasted)).row();
t.row(); t.add(Core.bundle.format("stat.enemiesDestroyed", state.stats.enemyUnitsDestroyed)).row();
t.add(Core.bundle.format("stat.enemiesDestroyed", state.stats.enemyUnitsDestroyed)); t.add(Core.bundle.format("stat.built", state.stats.buildingsBuilt)).row();
t.row(); t.add(Core.bundle.format("stat.destroyed", state.stats.buildingsDestroyed)).row();
t.add(Core.bundle.format("stat.built", state.stats.buildingsBuilt)); t.add(Core.bundle.format("stat.deconstructed", state.stats.buildingsDeconstructed)).row();
t.row();
t.add(Core.bundle.format("stat.destroyed", state.stats.buildingsDestroyed));
t.row();
t.add(Core.bundle.format("stat.deconstructed", state.stats.buildingsDeconstructed));
t.row();
if(control.saves.getCurrent() != null){ if(control.saves.getCurrent() != null){
t.add(Core.bundle.format("stat.playtime", control.saves.getCurrent().getPlayTime())); t.add(Core.bundle.format("stat.playtime", control.saves.getCurrent().getPlayTime())).row();
t.row();
} }
if(state.isCampaign() && !state.stats.itemsDelivered.isEmpty()){ if(state.isCampaign() && !state.stats.itemsDelivered.isEmpty()){
t.add("@stat.delivered"); t.add("@stat.delivered").row();
t.row();
for(Item item : content.items()){ for(Item item : content.items()){
if(state.stats.itemsDelivered.get(item, 0) > 0){ if(state.stats.itemsDelivered.get(item, 0) > 0){
t.table(items -> { t.table(items -> {
items.add(" [lightgray]" + state.stats.itemsDelivered.get(item, 0)); items.add(" [lightgray]" + state.stats.itemsDelivered.get(item, 0));
items.image(item.icon(Cicon.small)).size(8 * 3).pad(4); items.image(item.icon(Cicon.small)).size(8 * 3).pad(4);
}).left(); }).left().row();
t.row();
} }
} }
} }
if(state.isCampaign() && net.client()){
t.add("@gameover.waiting").padTop(20f).row();
}
}).pad(12); }).pad(12);
if(state.isCampaign()){ if(state.isCampaign()){
buttons.button("@continue", () -> { if(net.client()){
hide(); buttons.button("@gameover.disconnect", () -> {
logic.reset(); logic.reset();
ui.planet.show(); net.reset();
}).size(130f, 60f); hide();
state.set(State.menu);
}).size(170f, 60f);
}else{
buttons.button("@continue", () -> {
hide();
ui.planet.show();
}).size(170f, 60f);
}
}else{ }else{
buttons.button("@menu", () -> { buttons.button("@menu", () -> {
hide(); hide();
logic.reset(); logic.reset();
}).size(130f, 60f); }).size(140f, 60f);
} }
} }
} }

View File

@@ -283,7 +283,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
} }
} }
Sector current = state.getSector() != null && state.getSector().isBeingPlayed() ? state.getSector() : null; Sector current = state.getSector() != null && state.getSector().isBeingPlayed() && state.getSector().planet == planets.planet ? state.getSector() : null;
if(current != null){ if(current != null){
planets.fill(current, hoverColor, -0.001f); planets.fill(current, hoverColor, -0.001f);
@@ -418,6 +418,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
Planet planet = content.planets().get(i); Planet planet = content.planets().get(i);
if(planet.accessible){ if(planet.accessible){
pt.button(planet.localizedName, Styles.clearTogglet, () -> { pt.button(planet.localizedName, Styles.clearTogglet, () -> {
selected = null;
launchSector = null;
renderer.planets.planet = planet; renderer.planets.planet = planet;
}).width(200).height(40).growX().update(bb -> bb.setChecked(renderer.planets.planet == planet)); }).width(200).height(40).growX().update(bb -> bb.setChecked(renderer.planets.planet == planet));
pt.row(); pt.row();
@@ -485,6 +487,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
hoverLabel.remove(); hoverLabel.remove();
} }
if(launching && selected != null){
lookAt(selected, 0.1f);
}
if(showing()){ if(showing()){
Sector to = newPresets.peek(); Sector to = newPresets.peek();

View File

@@ -61,6 +61,7 @@ public class ResearchDialog extends BaseDialog{
for(Sector sector : planet.sectors){ for(Sector sector : planet.sectors){
if(sector.hasSave() && sector.hasBase()){ if(sector.hasSave() && sector.hasBase()){
ItemSeq cached = sector.items(); ItemSeq cached = sector.items();
cache.put(sector, cached);
cached.each((item, amount) -> { cached.each((item, amount) -> {
values[item.id] += amount; values[item.id] += amount;
total += amount; total += amount;

View File

@@ -749,6 +749,14 @@ public class HudFragment extends Fragment{
return builder; return builder;
} }
if(!state.rules.waves && state.isCampaign()){
builder.append("[lightgray]").append(Core.bundle.get("sector.curcapture"));
}
if(!state.rules.waves){
return builder;
}
if(state.rules.winWave > 1 && state.rules.winWave >= state.wave && state.isCampaign()){ if(state.rules.winWave > 1 && state.rules.winWave >= state.wave && state.isCampaign()){
builder.append(wavefc.get(state.wave, state.rules.winWave)); builder.append(wavefc.get(state.wave, state.rules.winWave));
}else{ }else{
@@ -774,9 +782,6 @@ public class HudFragment extends Fragment{
return builder; return builder;
}).growX().pad(8f); }).growX().pad(8f);
table.update(() -> {
//table.background(state.rules.waves ? Tex.wavepane : null);
});
table.touchable(() -> state.rules.waves ? Touchable.enabled : Touchable.disabled); table.touchable(() -> state.rules.waves ? Touchable.enabled : Touchable.disabled);
return table; return table;

View File

@@ -101,7 +101,7 @@ public abstract class Turret extends ReloadTurret{
super.setStats(); super.setStats();
stats.add(Stat.inaccuracy, (int)inaccuracy, StatUnit.degrees); stats.add(Stat.inaccuracy, (int)inaccuracy, StatUnit.degrees);
stats.add(Stat.reload, 60f / reloadTime * shots, StatUnit.none); stats.add(Stat.reload, 60f / reloadTime * (alternate ? 1 : shots), StatUnit.none);
stats.add(Stat.targetsAir, targetAir); stats.add(Stat.targetsAir, targetAir);
stats.add(Stat.targetsGround, targetGround); stats.add(Stat.targetsGround, targetGround);
} }

View File

@@ -174,7 +174,7 @@ public class UnitFactory extends UnitBlock{
i.setScaling(Scaling.fit); i.setScaling(Scaling.fit);
i.setColor(currentPlan == -1 ? Color.lightGray : Color.white); i.setColor(currentPlan == -1 ? Color.lightGray : Color.white);
}).size(32).padBottom(-4).padRight(2); }).size(32).padBottom(-4).padRight(2);
t.label(() -> currentPlan == -1 ? "@none" : plans.get(currentPlan).unit.localizedName).color(Color.lightGray); t.label(() -> currentPlan == -1 ? "@none" : plans.get(currentPlan).unit.localizedName).wrap().width(230f).color(Color.lightGray);
}).left(); }).left();
} }

View File

@@ -0,0 +1,10 @@
- Sound fixes for various platforms
- Added a few new sound effects
- Added stats for unit weapons (Contributed by @genNAowl)
- Logic: Added logical AND operation
- Disabled automatic targeting of derelict structures
- Campaign: Many various bugfixes
- Campaign: Added random water pool generation
- Campaign: Added more preset sectors
- Campaign: Removed item/liquid research costs, items are now discovered upon production
- Campaign: More scrap generation

View File

@@ -0,0 +1,3 @@
- Fixed file chooser crash [Android]
- Fixed time stopping after sector capture
- Moved Ruinous Shores map to more approppriate location

View File

@@ -1,3 +1,3 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=079640f8ea3e46c1aff497f5f8a5e5f9c5197282 archash=f1feed86eb643c2e5dbcee013b1b186644b5cf98

View File

@@ -3,7 +3,6 @@ package mindustry.server;
import arc.*; import arc.*;
import arc.files.*; import arc.files.*;
import arc.struct.*; import arc.struct.*;
import arc.struct.Seq.*;
import arc.util.*; import arc.util.*;
import arc.util.Timer; import arc.util.Timer;
import arc.util.CommandHandler.*; import arc.util.CommandHandler.*;
@@ -22,6 +21,7 @@ import mindustry.maps.Maps.*;
import mindustry.mod.Mods.*; import mindustry.mod.Mods.*;
import mindustry.net.Administration.*; import mindustry.net.Administration.*;
import mindustry.net.Packets.*; import mindustry.net.Packets.*;
import mindustry.net.*;
import mindustry.type.*; import mindustry.type.*;
import java.io.*; import java.io.*;
@@ -964,30 +964,16 @@ public class ServerControl implements ApplicationListener{
private void play(boolean wait, Runnable run){ private void play(boolean wait, Runnable run){
inExtraRound = true; inExtraRound = true;
Runnable r = () -> { Runnable r = () -> {
Seq<Player> players = new Seq<>(); WorldReloader reloader = new WorldReloader();
for(Player p : Groups.player){
players.add(p);
p.clearUnit();
}
logic.reset(); reloader.begin();
Call.worldDataBegin();
run.run(); run.run();
state.rules = state.map.applyRules(lastMode); state.rules = state.map.applyRules(lastMode);
logic.play(); logic.play();
for(Player p : players){ reloader.end();
if(p.con == null) continue;
boolean wasAdmin = p.admin;
p.reset();
p.admin = wasAdmin;
if(state.rules.pvp){
p.team(netServer.assignTeam(p, new SeqIterable<>(players)));
}
netServer.sendWorldData(p);
}
inExtraRound = false; inExtraRound = false;
}; };