Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
054f0b2128 | ||
|
|
1e2b593152 | ||
|
|
b46676014b | ||
|
|
3c36749990 | ||
|
|
280e345faf | ||
|
|
f296d23cfa | ||
|
|
3b609f698a |
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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!
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 944 KiB After Width: | Height: | Size: 960 KiB |
|
Before Width: | Height: | Size: 596 KiB After Width: | Height: | Size: 575 KiB |
|
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 185 KiB |
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 186 KiB |
@@ -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;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
21
core/src/mindustry/maps/planet/TantrosPlanetGenerator.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
59
core/src/mindustry/net/WorldReloader.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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){
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
fastlane/metadata/android/en-US/changelogs/29702.txt
Normal 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
|
||||||
3
fastlane/metadata/android/en-US/changelogs/29706.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- Fixed file chooser crash [Android]
|
||||||
|
- Fixed time stopping after sector capture
|
||||||
|
- Moved Ruinous Shores map to more approppriate location
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||