Merge branch 'master' of https://github.com/Anuken/Mindustry into 7.0-features
Conflicts: core/assets/logicids.dat core/src/mindustry/content/Blocks.java gradle.properties
This commit is contained in:
@@ -17,9 +17,9 @@ jobs:
|
|||||||
git tag ${BNUM}
|
git tag ${BNUM}
|
||||||
git config --global user.name "Build Uploader"
|
git config --global user.name "Build Uploader"
|
||||||
git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/Anuken/MindustryBuilds ${BNUM}
|
git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/Anuken/MindustryBuilds ${BNUM}
|
||||||
- name: Set up JDK 16
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 16
|
java-version: 17
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: ./gradlew clean cleanTest test
|
run: ./gradlew clean cleanTest test --stacktrace
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{version:6,fields:[{name:color,type:arc.graphics.Color},{name:data,type:java.lang.Object},{name:effect,type:mindustry.entities.Effect},{name:lifetime,type:float},{name:offsetPos,type:float},{name:offsetRot,type:float},{name:offsetX,type:float},{name:offsetY,type:float},{name:parent,type:mindustry.gen.Posc},{name:rotWithParent,type:boolean},{name:rotation,type:float},{name:time,type:float},{name:x,type:float},{name:y,type:float}]}
|
||||||
+3
-3
@@ -23,8 +23,8 @@ buildscript{
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins{
|
plugins{
|
||||||
id 'org.jetbrains.kotlin.jvm' version '1.5.21'
|
id 'org.jetbrains.kotlin.jvm' version '1.5.31'
|
||||||
id "org.jetbrains.kotlin.kapt" version "1.5.21"
|
id "org.jetbrains.kotlin.kapt" version "1.5.31"
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects{
|
allprojects{
|
||||||
@@ -375,7 +375,7 @@ project(":core"){
|
|||||||
if(localArc() && debugged()) api arcModule("extensions:recorder")
|
if(localArc() && debugged()) api arcModule("extensions:recorder")
|
||||||
if(localArc()) api arcModule(":extensions:packer")
|
if(localArc()) api arcModule(":extensions:packer")
|
||||||
|
|
||||||
annotationProcessor 'com.github.Anuken:jabel:34e4c172e65b3928cd9eabe1993654ea79c409cd'
|
annotationProcessor 'com.github.Anuken:jabel:0.6.0'
|
||||||
compileOnly project(":annotations")
|
compileOnly project(":annotations")
|
||||||
kapt project(":annotations")
|
kapt project(":annotations")
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 6.3 KiB |
@@ -379,6 +379,9 @@ editor.ingame = Edit In-Game
|
|||||||
editor.publish.workshop = Publish On Workshop
|
editor.publish.workshop = Publish On Workshop
|
||||||
editor.newmap = New Map
|
editor.newmap = New Map
|
||||||
editor.center = Center
|
editor.center = Center
|
||||||
|
editor.search = Search Maps...
|
||||||
|
editor.filters = Filter Maps
|
||||||
|
editor.showAll = Show Default Maps
|
||||||
workshop = Workshop
|
workshop = Workshop
|
||||||
waves.title = Waves
|
waves.title = Waves
|
||||||
waves.remove = Remove
|
waves.remove = Remove
|
||||||
@@ -1133,6 +1136,7 @@ block.sand-boulder.name = Sand Boulder
|
|||||||
block.basalt-boulder.name = Basalt Boulder
|
block.basalt-boulder.name = Basalt Boulder
|
||||||
block.grass.name = Grass
|
block.grass.name = Grass
|
||||||
block.molten-slag.name = Slag
|
block.molten-slag.name = Slag
|
||||||
|
block.pooled-cryofluid.name = Cryofluid
|
||||||
block.space.name = Space
|
block.space.name = Space
|
||||||
block.salt.name = Salt
|
block.salt.name = Salt
|
||||||
block.salt-wall.name = Salt Wall
|
block.salt-wall.name = Salt Wall
|
||||||
@@ -1613,7 +1617,7 @@ unit.omura.description = Fires a long-range piercing railgun bolt at enemies. Co
|
|||||||
unit.alpha.description = Defends the Shard core from enemies. Builds structures.
|
unit.alpha.description = Defends the Shard core from enemies. Builds structures.
|
||||||
unit.beta.description = Defends the Foundation core from enemies. Builds structures.
|
unit.beta.description = Defends the Foundation core from enemies. Builds structures.
|
||||||
unit.gamma.description = Defends the Nucleus core from enemies. Builds structures.
|
unit.gamma.description = Defends the Nucleus core from enemies. Builds structures.
|
||||||
unit.retusa.description = Places proximity mines. Repairs allied units.
|
unit.retusa.description = Fires homing torpedos at nearby enemies. Repairs allied units.
|
||||||
unit.oxynoe.description = Fires structure-repairing streams of flame at nearby enemies. Targets nearby enemy projectiles with a point defense turret.
|
unit.oxynoe.description = Fires structure-repairing streams of flame at nearby enemies. Targets nearby enemy projectiles with a point defense turret.
|
||||||
unit.cyerce.description = Fires seeking cluster-missiles at enemies. Repairs allied units.
|
unit.cyerce.description = Fires seeking cluster-missiles at enemies. Repairs allied units.
|
||||||
unit.aegires.description = Shocks all enemy units and structures that enter its energy field. Repairs all allies.
|
unit.aegires.description = Shocks all enemy units and structures that enter its energy field. Repairs all allies.
|
||||||
|
|||||||
@@ -360,3 +360,4 @@
|
|||||||
63348=molten-slag|block-molten-slag-ui
|
63348=molten-slag|block-molten-slag-ui
|
||||||
63347=crater-stone|block-crater-stone-ui
|
63347=crater-stone|block-crater-stone-ui
|
||||||
63346=deep-tainted-water|block-deep-tainted-water-ui
|
63346=deep-tainted-water|block-deep-tainted-water-ui
|
||||||
|
63345=pooled-cryofluid|block-pooled-cryofluid-ui
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,33 @@
|
|||||||
|
#define HIGHP
|
||||||
|
|
||||||
|
//shades of cryofluid
|
||||||
|
#define S1 vec3(53.0, 83.0, 93.0) / 100.0
|
||||||
|
#define S2 vec3(68.0, 90.0, 97.0) / 100.0
|
||||||
|
#define NSCALE 100.0 / 2.0
|
||||||
|
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
uniform sampler2D u_noise;
|
||||||
|
|
||||||
|
uniform vec2 u_campos;
|
||||||
|
uniform vec2 u_resolution;
|
||||||
|
uniform float u_time;
|
||||||
|
|
||||||
|
varying vec2 v_texCoords;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec2 c = v_texCoords.xy;
|
||||||
|
vec2 coords = vec2(c.x * u_resolution.x + u_campos.x, c.y * u_resolution.y + u_campos.y);
|
||||||
|
|
||||||
|
float btime = u_time / 5000.0;
|
||||||
|
float wave = abs(sin(coords.x * 1.1 + coords.y) + 0.1 * sin(2.5 * coords.x) + 0.15 * sin(3.0 * coords.y)) / 30.0;
|
||||||
|
float noise = wave + (texture2D(u_noise, (coords) / NSCALE + vec2(btime) * vec2(-0.2, 0.8)).r + texture2D(u_noise, (coords) / NSCALE + vec2(btime * 1.1) * vec2(0.8, -1.0)).r) / 2.0;
|
||||||
|
vec4 color = texture2D(u_texture, c);
|
||||||
|
|
||||||
|
if(noise > 0.54 && noise < 0.57){
|
||||||
|
color.rgb = S2;
|
||||||
|
}else if (noise > 0.49 && noise < 0.62){
|
||||||
|
color.rgb = S1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ void main(){
|
|||||||
vec2 c = v_texCoords.xy;
|
vec2 c = v_texCoords.xy;
|
||||||
vec2 coords = vec2(c.x * u_resolution.x + u_campos.x, c.y * u_resolution.y + u_campos.y);
|
vec2 coords = vec2(c.x * u_resolution.x + u_campos.x, c.y * u_resolution.y + u_campos.y);
|
||||||
|
|
||||||
float btime = u_time / 4000.0;
|
float btime = u_time / 5000.0;
|
||||||
float noise = (texture2D(u_noise, (coords) / NSCALE + vec2(btime) * vec2(-0.9, 0.8)).r + texture2D(u_noise, (coords) / NSCALE + vec2(btime * 1.1) * vec2(0.8, -1.0)).r) / 2.0;
|
float noise = (texture2D(u_noise, (coords) / NSCALE + vec2(btime) * vec2(-0.9, 0.8)).r + texture2D(u_noise, (coords) / NSCALE + vec2(btime * 1.1) * vec2(0.8, -1.0)).r) / 2.0;
|
||||||
vec4 color = texture2D(u_texture, c);
|
vec4 color = texture2D(u_texture, c);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import arc.struct.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class Astar{
|
public class Astar{
|
||||||
@@ -13,7 +15,7 @@ public class Astar{
|
|||||||
|
|
||||||
private static final Seq<Tile> out = new Seq<>();
|
private static final Seq<Tile> out = new Seq<>();
|
||||||
private static final PQueue<Tile> queue = new PQueue<>(200 * 200 / 4, (a, b) -> 0);
|
private static final PQueue<Tile> queue = new PQueue<>(200 * 200 / 4, (a, b) -> 0);
|
||||||
private static final IntFloatMap costs = new IntFloatMap();
|
private static float[] costs;
|
||||||
private static byte[][] rotations;
|
private static byte[][] rotations;
|
||||||
|
|
||||||
public static Seq<Tile> pathfind(Tile from, Tile to, TileHueristic th, Boolf<Tile> passable){
|
public static Seq<Tile> pathfind(Tile from, Tile to, TileHueristic th, Boolf<Tile> passable){
|
||||||
@@ -32,9 +34,14 @@ public class Astar{
|
|||||||
|
|
||||||
GridBits closed = new GridBits(tiles.width, tiles.height);
|
GridBits closed = new GridBits(tiles.width, tiles.height);
|
||||||
|
|
||||||
costs.clear();
|
if(costs == null || costs.length != tiles.width * tiles.height){
|
||||||
|
costs = new float[tiles.width * tiles.height];
|
||||||
|
}
|
||||||
|
|
||||||
|
Arrays.fill(costs, 0);
|
||||||
|
|
||||||
queue.clear();
|
queue.clear();
|
||||||
queue.comparator = Structs.comparingFloat(a -> costs.get(a.pos(), 0f) + dh.cost(a.x, a.y, end.x, end.y));
|
queue.comparator = Structs.comparingFloat(a -> costs[a.array()] + dh.cost(a.x, a.y, end.x, end.y));
|
||||||
queue.add(start);
|
queue.add(start);
|
||||||
if(rotations == null || rotations.length != world.width() || rotations[0].length != world.height()){
|
if(rotations == null || rotations.length != world.width() || rotations[0].length != world.height()){
|
||||||
rotations = new byte[world.width()][world.height()];
|
rotations = new byte[world.width()][world.height()];
|
||||||
@@ -43,7 +50,7 @@ public class Astar{
|
|||||||
boolean found = false;
|
boolean found = false;
|
||||||
while(!queue.empty()){
|
while(!queue.empty()){
|
||||||
Tile next = queue.poll();
|
Tile next = queue.poll();
|
||||||
float baseCost = costs.get(next.pos(), 0f);
|
float baseCost = costs[next.array()];
|
||||||
if(next == end){
|
if(next == end){
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@@ -58,7 +65,7 @@ public class Astar{
|
|||||||
if(!closed.get(child.x, child.y)){
|
if(!closed.get(child.x, child.y)){
|
||||||
closed.set(child.x, child.y);
|
closed.set(child.x, child.y);
|
||||||
rotations[child.x][child.y] = child.relativeTo(next.x, next.y);
|
rotations[child.x][child.y] = child.relativeTo(next.x, next.y);
|
||||||
costs.put(child.pos(), newCost);
|
costs[child.array()] = newCost;
|
||||||
queue.add(child);
|
queue.add(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ public class SoundControl{
|
|||||||
sound.setBus(uiBus);
|
sound.setBus(uiBus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Events.fire(new MusicRegisterEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loop(Sound sound, float volume){
|
public void loop(Sound sound, float volume){
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class Blocks implements ContentList{
|
|||||||
public static Block
|
public static Block
|
||||||
|
|
||||||
//environment
|
//environment
|
||||||
air, spawn, cliff, deepwater, water, taintedWater, deepTaintedWater, tar, slag, stone, craters, charr, sand, darksand, dirt, mud, ice, snow, darksandTaintedWater, space, empty,
|
air, spawn, cliff, deepwater, water, taintedWater, deepTaintedWater, tar, slag, cryofluid, stone, craters, charr, sand, darksand, dirt, mud, ice, snow, darksandTaintedWater, space, empty,
|
||||||
dacite, rhyolite, rhyoliteCrater, regolith, yellowStone, redIce,
|
dacite, rhyolite, rhyoliteCrater, regolith, yellowStone, redIce,
|
||||||
redmat, bluemat,
|
redmat, bluemat,
|
||||||
stoneWall, dirtWall, sporeWall, iceWall, daciteWall, sporePine, snowPine, pine, shrubs, whiteTree, whiteTreeDead, sporeCluster,
|
stoneWall, dirtWall, sporeWall, iceWall, daciteWall, sporePine, snowPine, pine, shrubs, whiteTree, whiteTreeDead, sporeCluster,
|
||||||
@@ -210,6 +210,22 @@ public class Blocks implements ContentList{
|
|||||||
cacheLayer = CacheLayer.tar;
|
cacheLayer = CacheLayer.tar;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
cryofluid = new Floor("pooled-cryofluid"){{
|
||||||
|
drownTime = 150f;
|
||||||
|
status = StatusEffects.freezing;
|
||||||
|
statusDuration = 240f;
|
||||||
|
speedMultiplier = 0.5f;
|
||||||
|
variants = 0;
|
||||||
|
liquidDrop = Liquids.cryofluid;
|
||||||
|
liquidMultiplier = 0.5f;
|
||||||
|
isLiquid = true;
|
||||||
|
cacheLayer = CacheLayer.cryofluid;
|
||||||
|
|
||||||
|
emitLight = true;
|
||||||
|
lightRadius = 25f;
|
||||||
|
lightColor = Color.cyan.cpy().a(0.19f);
|
||||||
|
}};
|
||||||
|
|
||||||
slag = new Floor("molten-slag"){{
|
slag = new Floor("molten-slag"){{
|
||||||
drownTime = 230f;
|
drownTime = 230f;
|
||||||
status = StatusEffects.melting;
|
status = StatusEffects.melting;
|
||||||
@@ -1060,6 +1076,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
thruster = new Thruster("thruster"){{
|
thruster = new Thruster("thruster"){{
|
||||||
|
requirements(Category.defense, BuildVisibility.sandboxOnly, with(Items.scrap, 96));
|
||||||
health = 55 * 16 * wallHealthMultiplier;
|
health = 55 * 16 * wallHealthMultiplier;
|
||||||
size = 4;
|
size = 4;
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -369,13 +369,13 @@ public class Fx{
|
|||||||
|
|
||||||
Fill.circle(e.x, e.y, e.fin() * 10);
|
Fill.circle(e.x, e.y, e.fin() * 10);
|
||||||
Drawf.light(e.x, e.y, e.fin() * 20f, Pal.heal, 0.7f);
|
Drawf.light(e.x, e.y, e.fin() * 20f, Pal.heal, 0.7f);
|
||||||
}).followParent(true),
|
}).followParent(true).rotWithParent(true),
|
||||||
|
|
||||||
greenLaserChargeSmall = new Effect(40f, 100f, e -> {
|
greenLaserChargeSmall = new Effect(40f, 100f, e -> {
|
||||||
color(Pal.heal);
|
color(Pal.heal);
|
||||||
stroke(e.fin() * 2f);
|
stroke(e.fin() * 2f);
|
||||||
Lines.circle(e.x, e.y, e.fout() * 50f);
|
Lines.circle(e.x, e.y, e.fout() * 50f);
|
||||||
}).followParent(true),
|
}).followParent(true).rotWithParent(true),
|
||||||
|
|
||||||
greenCloud = new Effect(80f, e -> {
|
greenCloud = new Effect(80f, e -> {
|
||||||
color(Pal.heal);
|
color(Pal.heal);
|
||||||
@@ -1975,7 +1975,7 @@ public class Fx{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Lines.endLine();
|
Lines.endLine();
|
||||||
}).followParent(false),
|
}).followParent(false).rotWithParent(false),
|
||||||
|
|
||||||
chainEmp = new Effect(30f, 300f, e -> {
|
chainEmp = new Effect(30f, 300f, e -> {
|
||||||
if(!(e.data instanceof Position p)) return;
|
if(!(e.data instanceof Position p)) return;
|
||||||
@@ -2012,5 +2012,5 @@ public class Fx{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Lines.endLine();
|
Lines.endLine();
|
||||||
}).followParent(false);
|
}).followParent(false).rotWithParent(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1787,7 +1787,6 @@ public class UnitTypes implements ContentList{
|
|||||||
//endregion
|
//endregion
|
||||||
//region naval support
|
//region naval support
|
||||||
retusa = new UnitType("retusa"){{
|
retusa = new UnitType("retusa"){{
|
||||||
defaultController = HugAI::new;
|
|
||||||
speed = 0.9f;
|
speed = 0.9f;
|
||||||
targetAir = false;
|
targetAir = false;
|
||||||
drag = 0.14f;
|
drag = 0.14f;
|
||||||
@@ -1821,15 +1820,17 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
weapons.add(new Weapon(){{
|
weapons.add(new Weapon(){{
|
||||||
mirror = false;
|
mirror = false;
|
||||||
reload = 80f;
|
rotate = true;
|
||||||
|
reload = 90f;
|
||||||
shots = 3;
|
shots = 3;
|
||||||
shotDelay = 7f;
|
shotDelay = 7f;
|
||||||
x = y = shootX = shootY = 0f;
|
x = y = shootX = shootY = 0f;
|
||||||
shootSound = Sounds.mineDeploy;
|
shootSound = Sounds.mineDeploy;
|
||||||
|
rotateSpeed = 180f;
|
||||||
|
|
||||||
bullet = new BasicBulletType(){{
|
bullet = new BasicBulletType(){{
|
||||||
sprite = "mine-bullet";
|
sprite = "mine-bullet";
|
||||||
width = height = 11f;
|
width = height = 8f;
|
||||||
layer = Layer.scorch;
|
layer = Layer.scorch;
|
||||||
shootEffect = smokeEffect = Fx.none;
|
shootEffect = smokeEffect = Fx.none;
|
||||||
|
|
||||||
@@ -1843,23 +1844,31 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
hitSound = Sounds.plasmaboom;
|
hitSound = Sounds.plasmaboom;
|
||||||
|
|
||||||
shootCone = 360f;
|
|
||||||
ejectEffect = Fx.none;
|
ejectEffect = Fx.none;
|
||||||
hitSize = 22f;
|
hitSize = 22f;
|
||||||
|
|
||||||
collidesAir = false;
|
collidesAir = false;
|
||||||
|
|
||||||
lifetime = 500f;
|
lifetime = 87f;
|
||||||
|
|
||||||
hitEffect = new MultiEffect(Fx.blastExplosion, Fx.greenCloud);
|
hitEffect = new MultiEffect(Fx.blastExplosion, Fx.greenCloud);
|
||||||
keepVelocity = false;
|
keepVelocity = false;
|
||||||
|
|
||||||
shrinkX = shrinkY = 0f;
|
shrinkX = shrinkY = 0f;
|
||||||
|
|
||||||
speed = 0f;
|
inaccuracy = 2f;
|
||||||
|
weaveMag = 5f;
|
||||||
|
weaveScale = 4f;
|
||||||
|
speed = 0.7f;
|
||||||
|
drag = -0.017f;
|
||||||
|
homingPower = 0.05f;
|
||||||
|
collideFloor = true;
|
||||||
|
trailColor = Pal.heal;
|
||||||
|
trailWidth = 3f;
|
||||||
|
trailLength = 8;
|
||||||
|
|
||||||
splashDamage = 55f;
|
splashDamage = 33f;
|
||||||
splashDamageRadius = 45f;
|
splashDamageRadius = 32f;
|
||||||
}};
|
}};
|
||||||
}});
|
}});
|
||||||
}};
|
}};
|
||||||
@@ -1934,7 +1943,7 @@ public class UnitTypes implements ContentList{
|
|||||||
shootEffect = Fx.sparkShoot;
|
shootEffect = Fx.sparkShoot;
|
||||||
hitEffect = Fx.pointHit;
|
hitEffect = Fx.pointHit;
|
||||||
maxRange = 100f;
|
maxRange = 100f;
|
||||||
damage = 15f;
|
damage = 17f;
|
||||||
}};
|
}};
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ public class GameState{
|
|||||||
public int wave = 1;
|
public int wave = 1;
|
||||||
/** Wave countdown in ticks. */
|
/** Wave countdown in ticks. */
|
||||||
public float wavetime;
|
public float wavetime;
|
||||||
|
/** Logic tick. */
|
||||||
|
public double tick;
|
||||||
/** Whether the game is in game over state. */
|
/** Whether the game is in game over state. */
|
||||||
public boolean gameOver = false, serverPaused = false;
|
public boolean gameOver = false, serverPaused = false;
|
||||||
/** Server ticks/second. Only valid in multiplayer. */
|
/** Server ticks/second. Only valid in multiplayer. */
|
||||||
|
|||||||
@@ -370,6 +370,9 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!state.isPaused()){
|
if(!state.isPaused()){
|
||||||
|
float delta = Core.graphics.getDeltaTime();
|
||||||
|
state.tick += Float.isNaN(delta) || Float.isInfinite(delta) ? 0f : delta * 60f;
|
||||||
|
|
||||||
state.teams.updateTeamStats();
|
state.teams.updateTeamStats();
|
||||||
|
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import mindustry.game.EventType.*;
|
|||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.logic.*;
|
||||||
import mindustry.net.Administration.*;
|
import mindustry.net.Administration.*;
|
||||||
import mindustry.net.*;
|
import mindustry.net.*;
|
||||||
import mindustry.net.Packets.*;
|
import mindustry.net.Packets.*;
|
||||||
@@ -452,7 +453,7 @@ public class NetClient implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
|
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
|
||||||
public static void stateSnapshot(float waveTime, int wave, int enemies, boolean paused, boolean gameOver, int timeData, byte tps, byte[] coreData){
|
public static void stateSnapshot(float waveTime, int wave, int enemies, boolean paused, boolean gameOver, int timeData, byte tps, long rand0, long rand1, byte[] coreData){
|
||||||
try{
|
try{
|
||||||
if(wave > state.wave){
|
if(wave > state.wave){
|
||||||
state.wave = wave;
|
state.wave = wave;
|
||||||
@@ -466,6 +467,11 @@ public class NetClient implements ApplicationListener{
|
|||||||
state.serverPaused = paused;
|
state.serverPaused = paused;
|
||||||
state.serverTps = tps & 0xff;
|
state.serverTps = tps & 0xff;
|
||||||
|
|
||||||
|
//note that this is far from a guarantee that random state is synced - tiny changes in delta and ping can throw everything off again.
|
||||||
|
//syncing will only make much of a difference when rand() is called infrequently
|
||||||
|
GlobalConstants.rand.seed0 = rand0;
|
||||||
|
GlobalConstants.rand.seed1 = rand1;
|
||||||
|
|
||||||
universe.updateNetSeconds(timeData);
|
universe.updateNetSeconds(timeData);
|
||||||
|
|
||||||
netClient.byteStream.setBytes(coreData);
|
netClient.byteStream.setBytes(coreData);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import mindustry.game.*;
|
|||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.logic.*;
|
||||||
import mindustry.net.*;
|
import mindustry.net.*;
|
||||||
import mindustry.net.Administration.*;
|
import mindustry.net.Administration.*;
|
||||||
import mindustry.net.Packets.*;
|
import mindustry.net.Packets.*;
|
||||||
@@ -867,7 +868,8 @@ public class NetServer implements ApplicationListener{
|
|||||||
dataStream.close();
|
dataStream.close();
|
||||||
|
|
||||||
//write basic state data.
|
//write basic state data.
|
||||||
Call.stateSnapshot(player.con, state.wavetime, state.wave, state.enemies, state.serverPaused, state.gameOver, universe.seconds(), tps, syncStream.toByteArray());
|
Call.stateSnapshot(player.con, state.wavetime, state.wave, state.enemies, state.serverPaused, state.gameOver,
|
||||||
|
universe.seconds(), tps, GlobalConstants.rand.seed0, GlobalConstants.rand.seed1, syncStream.toByteArray());
|
||||||
|
|
||||||
syncStream.reset();
|
syncStream.reset();
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,12 @@ public class Effect{
|
|||||||
public float lifetime = 50f;
|
public float lifetime = 50f;
|
||||||
/** Clip size. */
|
/** Clip size. */
|
||||||
public float clip;
|
public float clip;
|
||||||
|
/** Amount added to rotation */
|
||||||
|
public float baseRotation;
|
||||||
/** If true, parent unit is data are followed. */
|
/** If true, parent unit is data are followed. */
|
||||||
public boolean followParent;
|
public boolean followParent;
|
||||||
|
/** If this and followParent are true, the effect will offset and rotate with the parent's rotation. */
|
||||||
|
public boolean rotWithParent;
|
||||||
|
|
||||||
public float layer = Layer.effect;
|
public float layer = Layer.effect;
|
||||||
public float layerDuration;
|
public float layerDuration;
|
||||||
@@ -61,11 +65,21 @@ public class Effect{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Effect rotWithParent(boolean follow){
|
||||||
|
rotWithParent = follow;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Effect layer(float l){
|
public Effect layer(float l){
|
||||||
layer = l;
|
layer = l;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Effect baseRotation(float d){
|
||||||
|
baseRotation = d;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Effect layer(float l, float duration){
|
public Effect layer(float l, float duration){
|
||||||
layer = l;
|
layer = l;
|
||||||
this.layerDuration = duration;
|
this.layerDuration = duration;
|
||||||
@@ -156,12 +170,15 @@ public class Effect{
|
|||||||
|
|
||||||
EffectState entity = EffectState.create();
|
EffectState entity = EffectState.create();
|
||||||
entity.effect = effect;
|
entity.effect = effect;
|
||||||
entity.rotation = rotation;
|
entity.rotation = effect.baseRotation + rotation;
|
||||||
entity.data = data;
|
entity.data = data;
|
||||||
entity.lifetime = effect.lifetime;
|
entity.lifetime = effect.lifetime;
|
||||||
entity.set(x, y);
|
entity.set(x, y);
|
||||||
entity.color.set(color);
|
entity.color.set(color);
|
||||||
if(effect.followParent && data instanceof Posc p) entity.parent = p;
|
if(effect.followParent && data instanceof Posc p){
|
||||||
|
entity.parent = p;
|
||||||
|
entity.rotWithParent = effect.rotWithParent;
|
||||||
|
}
|
||||||
entity.add();
|
entity.add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.entities.abilities;
|
package mindustry.entities.abilities;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.math.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
@@ -12,6 +13,7 @@ public class StatusFieldAbility extends Ability{
|
|||||||
public float duration = 60, reload = 100, range = 20;
|
public float duration = 60, reload = 100, range = 20;
|
||||||
public Effect applyEffect = Fx.none;
|
public Effect applyEffect = Fx.none;
|
||||||
public Effect activeEffect = Fx.overdriveWave;
|
public Effect activeEffect = Fx.overdriveWave;
|
||||||
|
public float effectX, effectY;
|
||||||
public boolean parentizeEffects;
|
public boolean parentizeEffects;
|
||||||
|
|
||||||
protected float timer;
|
protected float timer;
|
||||||
@@ -40,7 +42,8 @@ public class StatusFieldAbility extends Ability{
|
|||||||
applyEffect.at(other, parentizeEffects);
|
applyEffect.at(other, parentizeEffects);
|
||||||
});
|
});
|
||||||
|
|
||||||
activeEffect.at(unit, parentizeEffects);
|
float x = unit.x + Angles.trnsx(unit.rotation, effectY, effectX), y = unit.y + Angles.trnsy(unit.rotation, effectY, effectX);
|
||||||
|
activeEffect.at(x, y, unit.rotation, parentizeEffects ? unit : null);
|
||||||
|
|
||||||
timer = 0f;
|
timer = 0f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,10 @@ public class BulletType extends Content implements Cloneable{
|
|||||||
public boolean collidesAir = true, collidesGround = true;
|
public boolean collidesAir = true, collidesGround = true;
|
||||||
/** Whether this bullet types collides with anything at all. */
|
/** Whether this bullet types collides with anything at all. */
|
||||||
public boolean collides = true;
|
public boolean collides = true;
|
||||||
|
/** If true, this projectile collides with non-surface floors. */
|
||||||
|
public boolean collideFloor = false;
|
||||||
|
/** If true, this projectile collides with static walls */
|
||||||
|
public boolean collideTerrain = false;
|
||||||
/** Whether velocity is inherited from the shooter. */
|
/** Whether velocity is inherited from the shooter. */
|
||||||
public boolean keepVelocity = true;
|
public boolean keepVelocity = true;
|
||||||
/** Whether to scale lifetime (not actually velocity!) to disappear at the target position. Used for artillery. */
|
/** Whether to scale lifetime (not actually velocity!) to disappear at the target position. Used for artillery. */
|
||||||
|
|||||||
@@ -1037,7 +1037,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
int amount = Math.min(items.get(item), explosionItemCap());
|
int amount = Math.min(items.get(item), explosionItemCap());
|
||||||
explosiveness += item.explosiveness * amount;
|
explosiveness += item.explosiveness * amount;
|
||||||
flammability += item.flammability * amount;
|
flammability += item.flammability * amount;
|
||||||
power += item.charge * amount * 100f;
|
power += item.charge * Mathf.pow(amount, 1.1f) * 150f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,15 @@ import arc.math.geom.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.content.*;
|
||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.environment.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -137,6 +140,20 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
|
|
||||||
while(x >= 0 && y >= 0 && x < ww && y < wh){
|
while(x >= 0 && y >= 0 && x < ww && y < wh){
|
||||||
Building build = world.build(x, y);
|
Building build = world.build(x, y);
|
||||||
|
|
||||||
|
if(type.collideFloor || type.collideTerrain){
|
||||||
|
Tile tile = world.tile(x, y);
|
||||||
|
if(
|
||||||
|
type.collideFloor && (tile == null || tile.floor().hasSurface() || tile.block() != Blocks.air) ||
|
||||||
|
type.collideTerrain && tile != null && tile.block() instanceof StaticWall
|
||||||
|
){
|
||||||
|
type.despawned(self());
|
||||||
|
remove();
|
||||||
|
hit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(build != null && isAdded() && build.collide(self()) && type.testCollision(self(), build)
|
if(build != null && isAdded() && build.collide(self()) && type.testCollision(self(), build)
|
||||||
&& !build.dead() && (type.collidesTeam || build.team != team) && !(type.pierceBuilding && hasCollided(build.id))){
|
&& !build.dead() && (type.collidesTeam || build.team != team) && !(type.pierceBuilding && hasCollided(build.id))){
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,41 @@
|
|||||||
package mindustry.entities.comp;
|
package mindustry.entities.comp;
|
||||||
|
|
||||||
|
import arc.math.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
abstract class ChildComp implements Posc{
|
abstract class ChildComp implements Posc, Rotc{
|
||||||
@Import float x, y;
|
@Import float x, y, rotation;
|
||||||
|
|
||||||
@Nullable Posc parent;
|
@Nullable Posc parent;
|
||||||
float offsetX, offsetY;
|
boolean rotWithParent;
|
||||||
|
float offsetX, offsetY, offsetPos, offsetRot;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(){
|
public void add(){
|
||||||
if(parent != null){
|
if(parent != null){
|
||||||
offsetX = x - parent.getX();
|
offsetX = x - parent.getX();
|
||||||
offsetY = y - parent.getY();
|
offsetY = y - parent.getY();
|
||||||
|
if(rotWithParent && parent instanceof Rotc r){
|
||||||
|
offsetPos = -r.rotation();
|
||||||
|
offsetRot = rotation - r.rotation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
if(parent != null){
|
if(parent != null){
|
||||||
x = parent.getX() + offsetX;
|
if(rotWithParent && parent instanceof Rotc r){
|
||||||
y = parent.getY() + offsetY;
|
x = parent.getX() + Angles.trnsx(r.rotation() + offsetPos, offsetX, offsetY);
|
||||||
|
y = parent.getY() + Angles.trnsy(r.rotation() + offsetPos, offsetX, offsetY);
|
||||||
|
rotation = r.rotation() + offsetRot;
|
||||||
|
}else{
|
||||||
|
x = parent.getX() + offsetX;
|
||||||
|
y = parent.getY() + offsetY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -482,7 +482,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
|
|
||||||
float explosiveness = 2f + item().explosiveness * stack().amount * 1.53f;
|
float explosiveness = 2f + item().explosiveness * stack().amount * 1.53f;
|
||||||
float flammability = item().flammability * stack().amount / 1.9f;
|
float flammability = item().flammability * stack().amount / 1.9f;
|
||||||
float power = item().charge * stack().amount * 150f;
|
float power = item().charge * Mathf.pow(stack().amount, 1.11f) * 160f;
|
||||||
|
|
||||||
if(!spawnedByCore){
|
if(!spawnedByCore){
|
||||||
Damage.dynamicExplosion(x, y, flammability, explosiveness, power, bounds() / 2f, state.rules.damageExplosions, item().flammability > 1, team, type.deathExplosionEffect);
|
Damage.dynamicExplosion(x, y, flammability, explosiveness, power, bounds() / 2f, state.rules.damageExplosions, item().flammability > 1, team, type.deathExplosionEffect);
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ public class EventType{
|
|||||||
public static class ContentInitEvent{}
|
public static class ContentInitEvent{}
|
||||||
/** Called when the client game is first loaded. */
|
/** Called when the client game is first loaded. */
|
||||||
public static class ClientLoadEvent{}
|
public static class ClientLoadEvent{}
|
||||||
|
/** Called after SoundControl registers its music. */
|
||||||
|
public static class MusicRegisterEvent{}
|
||||||
/** Called *after* all the modded files have been added into Vars.tree */
|
/** Called *after* all the modded files have been added into Vars.tree */
|
||||||
public static class FileTreeInitEvent{}
|
public static class FileTreeInitEvent{}
|
||||||
/** Called when a game begins and the world is loaded. */
|
/** Called when a game begins and the world is loaded. */
|
||||||
|
|||||||
@@ -117,10 +117,30 @@ public class BlockRenderer{
|
|||||||
lastCamY = lastCamX = -99; //invalidate camera position so blocks get updated
|
lastCamY = lastCamX = -99; //invalidate camera position so blocks get updated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalidateTile(event.tile);
|
||||||
recordIndex(event.tile);
|
recordIndex(event.tile);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void invalidateTile(Tile tile){
|
||||||
|
int avgx = (int)(camera.position.x / tilesize);
|
||||||
|
int avgy = (int)(camera.position.y / tilesize);
|
||||||
|
int rangex = (int)(camera.width / tilesize / 2) + 3;
|
||||||
|
int rangey = (int)(camera.height / tilesize / 2) + 3;
|
||||||
|
|
||||||
|
if(Math.abs(avgx - tile.x) <= rangex && Math.abs(avgy - tile.y) <= rangey){
|
||||||
|
lastCamY = lastCamX = -99; //invalidate camera position so blocks get updated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeFloorIndex(Tile tile){
|
||||||
|
if(indexFloor(tile)) floorTree.remove(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFloorIndex(Tile tile){
|
||||||
|
if(indexFloor(tile)) floorTree.insert(tile);
|
||||||
|
}
|
||||||
|
|
||||||
boolean indexBlock(Tile tile){
|
boolean indexBlock(Tile tile){
|
||||||
var block = tile.block();
|
var block = tile.block();
|
||||||
return tile.isCenter() && block != Blocks.air && block.cacheLayer == CacheLayer.normal;
|
return tile.isCenter() && block != Blocks.air && block.cacheLayer == CacheLayer.normal;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import static mindustry.Vars.*;
|
|||||||
public class CacheLayer{
|
public class CacheLayer{
|
||||||
public static CacheLayer
|
public static CacheLayer
|
||||||
|
|
||||||
water, mud, tar, slag, space, normal, walls;
|
water, mud, cryofluid, tar, slag, space, normal, walls;
|
||||||
|
|
||||||
public static CacheLayer[] all = {};
|
public static CacheLayer[] all = {};
|
||||||
|
|
||||||
@@ -37,6 +37,7 @@ public class CacheLayer{
|
|||||||
mud = new ShaderLayer(Shaders.mud),
|
mud = new ShaderLayer(Shaders.mud),
|
||||||
tar = new ShaderLayer(Shaders.tar),
|
tar = new ShaderLayer(Shaders.tar),
|
||||||
slag = new ShaderLayer(Shaders.slag),
|
slag = new ShaderLayer(Shaders.slag),
|
||||||
|
cryofluid = new ShaderLayer(Shaders.cryofluid),
|
||||||
space = new ShaderLayer(Shaders.space),
|
space = new ShaderLayer(Shaders.space),
|
||||||
normal = new CacheLayer(),
|
normal = new CacheLayer(),
|
||||||
walls = new CacheLayer()
|
walls = new CacheLayer()
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class Shaders{
|
|||||||
public static UnitBuildShader build;
|
public static UnitBuildShader build;
|
||||||
public static DarknessShader darkness;
|
public static DarknessShader darkness;
|
||||||
public static LightShader light;
|
public static LightShader light;
|
||||||
public static SurfaceShader water, mud, tar, slag, space, caustics;
|
public static SurfaceShader water, mud, tar, slag, cryofluid, space, caustics;
|
||||||
public static PlanetShader planet;
|
public static PlanetShader planet;
|
||||||
public static CloudShader clouds;
|
public static CloudShader clouds;
|
||||||
public static PlanetGridShader planetGrid;
|
public static PlanetGridShader planetGrid;
|
||||||
@@ -48,6 +48,7 @@ public class Shaders{
|
|||||||
mud = new SurfaceShader("mud");
|
mud = new SurfaceShader("mud");
|
||||||
tar = new SurfaceShader("tar");
|
tar = new SurfaceShader("tar");
|
||||||
slag = new SurfaceShader("slag");
|
slag = new SurfaceShader("slag");
|
||||||
|
cryofluid = new SurfaceShader("cryofluid");
|
||||||
space = new SpaceShader("space");
|
space = new SpaceShader("space");
|
||||||
caustics = new SurfaceShader("caustics"){
|
caustics = new SurfaceShader("caustics"){
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
"build", Version.build,
|
"build", Version.build,
|
||||||
"mapname", state.map.name(),
|
"mapname", state.map.name(),
|
||||||
"wave", state.wave,
|
"wave", state.wave,
|
||||||
|
"tick", state.tick,
|
||||||
"wavetime", state.wavetime,
|
"wavetime", state.wavetime,
|
||||||
"stats", JsonIO.write(state.stats),
|
"stats", JsonIO.write(state.stats),
|
||||||
"rules", JsonIO.write(state.rules),
|
"rules", JsonIO.write(state.rules),
|
||||||
@@ -110,6 +111,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
|
|
||||||
state.wave = map.getInt("wave");
|
state.wave = map.getInt("wave");
|
||||||
state.wavetime = map.getFloat("wavetime", state.rules.waveSpacing);
|
state.wavetime = map.getFloat("wavetime", state.rules.waveSpacing);
|
||||||
|
state.tick = map.getFloat("tick");
|
||||||
state.stats = JsonIO.read(GameStats.class, map.get("stats", "{}"));
|
state.stats = JsonIO.read(GameStats.class, map.get("stats", "{}"));
|
||||||
state.rules = JsonIO.read(Rules.class, map.get("rules", "{}"));
|
state.rules = JsonIO.read(Rules.class, map.get("rules", "{}"));
|
||||||
if(state.rules.spawns.isEmpty()) state.rules.spawns = waves.get();
|
if(state.rules.spawns.isEmpty()) state.rules.spawns = waves.get();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mindustry.logic;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.files.*;
|
import arc.files.*;
|
||||||
|
import arc.math.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
@@ -18,6 +19,8 @@ import java.io.*;
|
|||||||
public class GlobalConstants{
|
public class GlobalConstants{
|
||||||
public static final int ctrlProcessor = 1, ctrlPlayer = 2, ctrlFormation = 3;
|
public static final int ctrlProcessor = 1, ctrlPlayer = 2, ctrlFormation = 3;
|
||||||
public static final ContentType[] lookableContent = {ContentType.block, ContentType.unit, ContentType.item, ContentType.liquid};
|
public static final ContentType[] lookableContent = {ContentType.block, ContentType.unit, ContentType.item, ContentType.liquid};
|
||||||
|
/** Global random state. */
|
||||||
|
public static final Rand rand = new Rand();
|
||||||
|
|
||||||
private ObjectIntMap<String> namesToIds = new ObjectIntMap<>();
|
private ObjectIntMap<String> namesToIds = new ObjectIntMap<>();
|
||||||
private Seq<Var> vars = new Seq<>(Var.class);
|
private Seq<Var> vars = new Seq<>(Var.class);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -56,9 +57,10 @@ public class LExecutor{
|
|||||||
|
|
||||||
/** Runs a single instruction. */
|
/** Runs a single instruction. */
|
||||||
public void runOnce(){
|
public void runOnce(){
|
||||||
//set time
|
//set up time; note that @time is now only updated once every invocation and directly based off of @tick.
|
||||||
vars[varTime].numval = Time.millis();
|
//having time be based off of user system time was a very bad idea.
|
||||||
vars[varTick].numval = Time.time;
|
vars[varTime].numval = state.tick / 60.0 * 1000.0;
|
||||||
|
vars[varTick].numval = state.tick;
|
||||||
|
|
||||||
//reset to start
|
//reset to start
|
||||||
if(vars[varCounter].numval >= instructions.length || vars[varCounter].numval < 0){
|
if(vars[varCounter].numval >= instructions.length || vars[varCounter].numval < 0){
|
||||||
@@ -449,7 +451,7 @@ public class LExecutor{
|
|||||||
case build -> {
|
case build -> {
|
||||||
if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block && block.canBeBuilt()){
|
if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block && block.canBeBuilt()){
|
||||||
int x = World.toTile(x1 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize);
|
int x = World.toTile(x1 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize);
|
||||||
int rot = exec.numi(p4);
|
int rot = Mathf.mod(exec.numi(p4), 4);
|
||||||
|
|
||||||
//reset state of last request when necessary
|
//reset state of last request when necessary
|
||||||
if(ai.plan.x != x || ai.plan.y != y || ai.plan.block != block || unit.plans.isEmpty()){
|
if(ai.plan.x != x || ai.plan.y != y || ai.plan.block != block || unit.plans.isEmpty()){
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ public enum LogicOp{
|
|||||||
angle("angle", true, (x, y) -> Angles.angle((float)x, (float)y)),
|
angle("angle", true, (x, y) -> Angles.angle((float)x, (float)y)),
|
||||||
len("len", true, (x, y) -> Mathf.dst((float)x, (float)y)),
|
len("len", true, (x, y) -> Mathf.dst((float)x, (float)y)),
|
||||||
noise("noise", true, (x, y) -> Simplex.raw2d(0, x, y)),
|
noise("noise", true, (x, y) -> Simplex.raw2d(0, x, y)),
|
||||||
abs("abs", a -> Math.abs(a)),
|
abs("abs", a -> Math.abs(a)), //not a method reference because it fails to compile for some reason
|
||||||
log("log", Math::log),
|
log("log", Math::log),
|
||||||
log10("log10", Math::log10),
|
log10("log10", Math::log10),
|
||||||
floor("floor", Math::floor),
|
floor("floor", Math::floor),
|
||||||
ceil("ceil", Math::ceil),
|
ceil("ceil", Math::ceil),
|
||||||
sqrt("sqrt", Math::sqrt),
|
sqrt("sqrt", Math::sqrt),
|
||||||
rand("rand", d -> Mathf.rand.nextDouble() * d),
|
rand("rand", d -> GlobalConstants.rand.nextDouble() * d),
|
||||||
|
|
||||||
sin("sin", d -> Math.sin(d * Mathf.doubleDegRad)),
|
sin("sin", d -> Math.sin(d * Mathf.doubleDegRad)),
|
||||||
cos("cos", d -> Math.cos(d * Mathf.doubleDegRad)),
|
cos("cos", d -> Math.cos(d * Mathf.doubleDegRad)),
|
||||||
|
|||||||
@@ -262,9 +262,36 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
for(Room room : roomseq){
|
for(Room room : roomseq){
|
||||||
spawn.connect(room);
|
spawn.connect(room);
|
||||||
}
|
}
|
||||||
|
|
||||||
Room fspawn = spawn;
|
Room fspawn = spawn;
|
||||||
|
|
||||||
cells(1);
|
cells(1);
|
||||||
|
|
||||||
|
//shoreline setup
|
||||||
|
int deepRadius = 4;
|
||||||
|
|
||||||
|
pass((x, y) -> {
|
||||||
|
if(floor.asFloor().isLiquid && !floor.asFloor().isDeep()){
|
||||||
|
|
||||||
|
for(int cx = -deepRadius; cx <= deepRadius; cx++){
|
||||||
|
for(int cy = -deepRadius; cy <= deepRadius; cy++){
|
||||||
|
|
||||||
|
if((cx) * (cx) + (cy) * (cy) <= deepRadius * deepRadius){
|
||||||
|
int wx = cx + x, wy = cy + y;
|
||||||
|
|
||||||
|
Tile tile = tiles.get(wx, wy);
|
||||||
|
if(tile != null && (!tile.floor().isLiquid || tile.block() != Blocks.air)){
|
||||||
|
//found something solid, skip replacing anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
floor = floor == Blocks.darksandTaintedWater ? Blocks.taintedWater : Blocks.water;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
distort(10f, 6f);
|
distort(10f, 6f);
|
||||||
|
|
||||||
//rivers
|
//rivers
|
||||||
@@ -286,7 +313,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
floor = spore ?
|
floor = spore ?
|
||||||
(deep ? Blocks.taintedWater : Blocks.darksandTaintedWater) :
|
(deep ? Blocks.taintedWater : Blocks.darksandTaintedWater) :
|
||||||
(deep ? Blocks.water :
|
(deep ? Blocks.water :
|
||||||
(floor == Blocks.sand ? Blocks.sandWater : Blocks.darksandWater));
|
(floor == Blocks.sand || floor == Blocks.salt ? Blocks.sandWater : Blocks.darksandWater));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import mindustry.ctype.*;
|
|||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
|
import mindustry.logic.*;
|
||||||
import mindustry.maps.Map;
|
import mindustry.maps.Map;
|
||||||
import mindustry.net.Administration.*;
|
import mindustry.net.Administration.*;
|
||||||
|
|
||||||
@@ -40,6 +41,9 @@ public class NetworkIO{
|
|||||||
|
|
||||||
stream.writeInt(state.wave);
|
stream.writeInt(state.wave);
|
||||||
stream.writeFloat(state.wavetime);
|
stream.writeFloat(state.wavetime);
|
||||||
|
stream.writeDouble(state.tick);
|
||||||
|
stream.writeLong(GlobalConstants.rand.seed0);
|
||||||
|
stream.writeLong(GlobalConstants.rand.seed1);
|
||||||
|
|
||||||
stream.writeInt(player.id);
|
stream.writeInt(player.id);
|
||||||
player.write(Writes.get(stream));
|
player.write(Writes.get(stream));
|
||||||
@@ -61,6 +65,9 @@ public class NetworkIO{
|
|||||||
|
|
||||||
state.wave = stream.readInt();
|
state.wave = stream.readInt();
|
||||||
state.wavetime = stream.readFloat();
|
state.wavetime = stream.readFloat();
|
||||||
|
state.tick = stream.readDouble();
|
||||||
|
GlobalConstants.rand.seed0 = stream.readLong();
|
||||||
|
GlobalConstants.rand.seed1 = stream.readLong();
|
||||||
|
|
||||||
Groups.clear();
|
Groups.clear();
|
||||||
int id = stream.readInt();
|
int id = stream.readInt();
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ public class GameService{
|
|||||||
if(campaign()){
|
if(campaign()){
|
||||||
if(unitsBuilt.add(e.unit.type.name)){
|
if(unitsBuilt.add(e.unit.type.name)){
|
||||||
SStat.unitTypesBuilt.set(content.units().count(u -> unitsBuilt.contains(u.name) && !u.isHidden()));
|
SStat.unitTypesBuilt.set(content.units().count(u -> unitsBuilt.contains(u.name) && !u.isHidden()));
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(t5s.contains(e.unit.type)){
|
if(t5s.contains(e.unit.type)){
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public class StatusEffect extends UnlockableContent{
|
|||||||
public float damage;
|
public float damage;
|
||||||
/** Chance of effect appearing. */
|
/** Chance of effect appearing. */
|
||||||
public float effectChance = 0.15f;
|
public float effectChance = 0.15f;
|
||||||
|
/** Should the effect be given a parent */
|
||||||
|
public boolean parentizeEffect;
|
||||||
/** If true, the effect never disappears. */
|
/** If true, the effect never disappears. */
|
||||||
public boolean permanent;
|
public boolean permanent;
|
||||||
/** If true, this effect will only react with other effects and cannot be applied. */
|
/** If true, this effect will only react with other effects and cannot be applied. */
|
||||||
@@ -120,7 +122,7 @@ public class StatusEffect extends UnlockableContent{
|
|||||||
|
|
||||||
if(effect != Fx.none && Mathf.chanceDelta(effectChance)){
|
if(effect != Fx.none && Mathf.chanceDelta(effectChance)){
|
||||||
Tmp.v1.rnd(Mathf.range(unit.type.hitSize/2f));
|
Tmp.v1.rnd(Mathf.range(unit.type.hitSize/2f));
|
||||||
effect.at(unit.x + Tmp.v1.x, unit.y + Tmp.v1.y, color);
|
effect.at(unit.x + Tmp.v1.x, unit.y + Tmp.v1.y, 0, color, parentizeEffect ? unit : null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -200,6 +200,18 @@ public class Weapon implements Cloneable{
|
|||||||
boolean can = unit.canShoot();
|
boolean can = unit.canShoot();
|
||||||
mount.reload = Math.max(mount.reload - Time.delta * unit.reloadMultiplier, 0);
|
mount.reload = Math.max(mount.reload - Time.delta * unit.reloadMultiplier, 0);
|
||||||
|
|
||||||
|
//rotate if applicable
|
||||||
|
if(rotate && (mount.rotate || mount.shoot) && can){
|
||||||
|
float axisX = unit.x + Angles.trnsx(unit.rotation - 90, x, y),
|
||||||
|
axisY = unit.y + Angles.trnsy(unit.rotation - 90, x, y);
|
||||||
|
|
||||||
|
mount.targetRotation = Angles.angle(axisX, axisY, mount.aimX, mount.aimY) - unit.rotation;
|
||||||
|
mount.rotation = Angles.moveToward(mount.rotation, mount.targetRotation, rotateSpeed * Time.delta);
|
||||||
|
}else if(!rotate){
|
||||||
|
mount.rotation = 0;
|
||||||
|
mount.targetRotation = unit.angleTo(mount.aimX, mount.aimY);
|
||||||
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
weaponRotation = unit.rotation - 90 + (rotate ? mount.rotation : 0),
|
weaponRotation = unit.rotation - 90 + (rotate ? mount.rotation : 0),
|
||||||
mountX = unit.x + Angles.trnsx(unit.rotation - 90, x, y),
|
mountX = unit.x + Angles.trnsx(unit.rotation - 90, x, y),
|
||||||
@@ -256,7 +268,7 @@ public class Weapon implements Cloneable{
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
//heat decreases when not firing
|
//heat decreases when not firing
|
||||||
mount.heat = Math.max(mount.heat - Time.delta * unit.reloadMultiplier / mount.weapon.cooldownTime, 0);
|
mount.heat = Math.max(mount.heat - Time.delta * unit.reloadMultiplier / cooldownTime, 0);
|
||||||
|
|
||||||
if(mount.sound != null){
|
if(mount.sound != null){
|
||||||
mount.sound.update(bulletX, bulletY, false);
|
mount.sound.update(bulletX, bulletY, false);
|
||||||
@@ -270,26 +282,14 @@ public class Weapon implements Cloneable{
|
|||||||
mount.side = !mount.side;
|
mount.side = !mount.side;
|
||||||
}
|
}
|
||||||
|
|
||||||
//rotate if applicable
|
|
||||||
if(rotate && (mount.rotate || mount.shoot) && can){
|
|
||||||
float axisX = unit.x + Angles.trnsx(unit.rotation - 90, x, y),
|
|
||||||
axisY = unit.y + Angles.trnsy(unit.rotation - 90, x, y);
|
|
||||||
|
|
||||||
mount.targetRotation = Angles.angle(axisX, axisY, mount.aimX, mount.aimY) - unit.rotation;
|
|
||||||
mount.rotation = Angles.moveToward(mount.rotation, mount.targetRotation, rotateSpeed * Time.delta);
|
|
||||||
}else if(!rotate){
|
|
||||||
mount.rotation = 0;
|
|
||||||
mount.targetRotation = unit.angleTo(mount.aimX, mount.aimY);
|
|
||||||
}
|
|
||||||
|
|
||||||
//shoot if applicable
|
//shoot if applicable
|
||||||
if(mount.shoot && //must be shooting
|
if(mount.shoot && //must be shooting
|
||||||
can && //must be able to shoot
|
can && //must be able to shoot
|
||||||
(!useAmmo || unit.ammo > 0 || !state.rules.unitAmmo || unit.team.rules().infiniteAmmo) && //check ammo
|
(!useAmmo || unit.ammo > 0 || !state.rules.unitAmmo || unit.team.rules().infiniteAmmo) && //check ammo
|
||||||
(!alternate || mount.side == flipSprite) &&
|
(!alternate || mount.side == flipSprite) &&
|
||||||
unit.vel.len() >= mount.weapon.minShootVelocity && //check velocity requirements
|
unit.vel.len() >= minShootVelocity && //check velocity requirements
|
||||||
mount.reload <= 0.0001f && //reload has to be 0
|
mount.reload <= 0.0001f && //reload has to be 0
|
||||||
Angles.within(rotate ? mount.rotation : unit.rotation, mount.targetRotation, mount.weapon.shootCone) //has to be within the cone
|
Angles.within(rotate ? mount.rotation : unit.rotation, mount.targetRotation, shootCone) //has to be within the cone
|
||||||
){
|
){
|
||||||
shoot(unit, mount, bulletX, bulletY, mount.aimX, mount.aimY, mountX, mountY, shootAngle, Mathf.sign(x));
|
shoot(unit, mount, bulletX, bulletY, mount.aimX, mount.aimY, mountX, mountY, shootAngle, Mathf.sign(x));
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ package mindustry.ui.dialogs;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
|
import arc.scene.style.*;
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
@@ -17,6 +20,12 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public class MapsDialog extends BaseDialog{
|
public class MapsDialog extends BaseDialog{
|
||||||
private BaseDialog dialog;
|
private BaseDialog dialog;
|
||||||
|
private String searchString;
|
||||||
|
private Seq<Gamemode> modes = new Seq<>();
|
||||||
|
private Table mapTable = new Table();
|
||||||
|
private TextField searchField;
|
||||||
|
|
||||||
|
private boolean showAll = Core.settings.getBool("editorShowAllMaps", true);
|
||||||
|
|
||||||
public MapsDialog(){
|
public MapsDialog(){
|
||||||
super("@maps");
|
super("@maps");
|
||||||
@@ -37,8 +46,10 @@ public class MapsDialog extends BaseDialog{
|
|||||||
void setup(){
|
void setup(){
|
||||||
buttons.clearChildren();
|
buttons.clearChildren();
|
||||||
|
|
||||||
|
searchString = null;
|
||||||
|
|
||||||
if(Core.graphics.isPortrait()){
|
if(Core.graphics.isPortrait()){
|
||||||
buttons.button("@back", Icon.left, this::hide).size(210f*2f, 64f).colspan(2);
|
buttons.button("@back", Icon.left, this::hide).size(210f * 2f, 64f).colspan(2);
|
||||||
buttons.row();
|
buttons.row();
|
||||||
}else{
|
}else{
|
||||||
buttons.button("@back", Icon.left, this::hide).size(210f, 64f);
|
buttons.button("@back", Icon.left, this::hide).size(210f, 64f);
|
||||||
@@ -108,26 +119,58 @@ public class MapsDialog extends BaseDialog{
|
|||||||
});
|
});
|
||||||
}).size(210f, 64f);
|
}).size(210f, 64f);
|
||||||
|
|
||||||
|
|
||||||
cont.clear();
|
cont.clear();
|
||||||
|
|
||||||
Table maps = new Table();
|
rebuildMaps();
|
||||||
maps.marginRight(24);
|
|
||||||
|
|
||||||
ScrollPane pane = new ScrollPane(maps);
|
ScrollPane pane = new ScrollPane(mapTable);
|
||||||
pane.setFadeScrollBars(false);
|
pane.setFadeScrollBars(false);
|
||||||
|
|
||||||
|
Table search = new Table();
|
||||||
|
search.image(Icon.zoom);
|
||||||
|
searchField = search.field("", t -> {
|
||||||
|
searchString = t.length() > 0 ? t.toLowerCase() : null;
|
||||||
|
rebuildMaps();
|
||||||
|
}).maxTextLength(50).growX().get();
|
||||||
|
searchField.setMessageText("@editor.search");
|
||||||
|
search.button(Icon.filter, Styles.emptyi, this::showMapFilters);
|
||||||
|
|
||||||
|
cont.add(search).growX();
|
||||||
|
cont.row();
|
||||||
|
cont.add(pane).uniformX().growY();
|
||||||
|
cont.row();
|
||||||
|
cont.add(buttons).growX();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rebuildMaps(){
|
||||||
|
mapTable.clear();
|
||||||
|
|
||||||
|
mapTable.marginRight(24);
|
||||||
|
|
||||||
int maxwidth = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1);
|
int maxwidth = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1);
|
||||||
float mapsize = 200f;
|
float mapsize = 200f;
|
||||||
|
boolean noMapsShown = true;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Map map : Vars.maps.all()){
|
|
||||||
|
|
||||||
if(i % maxwidth == 0){
|
Seq<Map> mapList = showAll ? Vars.maps.all() : Vars.maps.customMaps();
|
||||||
maps.row();
|
for(Map map : mapList){
|
||||||
|
|
||||||
|
boolean invalid = false;
|
||||||
|
for(Gamemode mode : modes){
|
||||||
|
invalid |= !mode.valid(map);
|
||||||
|
}
|
||||||
|
if(invalid || (searchString != null && !Strings.stripColors(map.name()).toLowerCase().contains(searchString))){
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextButton button = maps.button("", Styles.cleart, () -> showMapInfo(map)).width(mapsize).pad(8).get();
|
noMapsShown = false;
|
||||||
|
|
||||||
|
if(i % maxwidth == 0){
|
||||||
|
mapTable.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextButton button = mapTable.button("", Styles.cleart, () -> showMapInfo(map)).width(mapsize).pad(8).get();
|
||||||
button.clearChildren();
|
button.clearChildren();
|
||||||
button.margin(9);
|
button.margin(9);
|
||||||
button.add(map.name()).width(mapsize - 18f).center().get().setEllipsis(true);
|
button.add(map.name()).width(mapsize - 18f).center().get().setEllipsis(true);
|
||||||
@@ -141,13 +184,41 @@ public class MapsDialog extends BaseDialog{
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Vars.maps.all().size == 0){
|
if(noMapsShown){
|
||||||
maps.add("@maps.none");
|
mapTable.add("@maps.none");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cont.add(buttons).growX();
|
void showMapFilters(){
|
||||||
cont.row();
|
dialog = new BaseDialog("@editor.filters");
|
||||||
cont.add(pane).uniformX();
|
dialog.addCloseButton();
|
||||||
|
dialog.setFillParent(false);
|
||||||
|
dialog.cont.table(Tex.button, t -> {
|
||||||
|
int i = 0;
|
||||||
|
for(Gamemode mode : Gamemode.all){
|
||||||
|
TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name()));
|
||||||
|
if(Core.atlas.isFound(icon.getRegion())){
|
||||||
|
t.button(mode.name(), icon, Styles.clearTogglet, () -> {
|
||||||
|
if(modes.contains(mode)){
|
||||||
|
modes.remove(mode);
|
||||||
|
}else{
|
||||||
|
modes.add(mode);
|
||||||
|
}
|
||||||
|
rebuildMaps();
|
||||||
|
}).size(150f, 60f).marginLeft(6f).checked(modes.contains(mode));
|
||||||
|
if(++i % 3 == 0) t.row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.row();
|
||||||
|
t.button("@editor.showAll", Styles.clearTogglet, () -> {
|
||||||
|
showAll = !showAll;
|
||||||
|
Core.settings.put("editorShowAllMaps", showAll);
|
||||||
|
Core.settings.forceSave();
|
||||||
|
rebuildMaps();
|
||||||
|
}).checked(b -> showAll).colspan(3).growX().height(40f);
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void showMapInfo(Map map){
|
void showMapInfo(Map map){
|
||||||
@@ -213,4 +284,15 @@ public class MapsDialog extends BaseDialog{
|
|||||||
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog show(){
|
||||||
|
super.show();
|
||||||
|
|
||||||
|
if(Core.app.isDesktop() && searchField != null){
|
||||||
|
Core.scene.setKeyboardFocus(searchField);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ public class ModsDialog extends BaseDialog{
|
|||||||
|
|
||||||
}).tooltip(c.localizedName);
|
}).tooltip(c.localizedName);
|
||||||
|
|
||||||
if(++i % Math.min(Core.graphics.getWidth() / Scl.scl(110), 14) == 0) cs.row();
|
if(++i % (int)Math.min(Core.graphics.getWidth() / Scl.scl(110), 14) == 0) cs.row();
|
||||||
}
|
}
|
||||||
}).grow();
|
}).grow();
|
||||||
d.addCloseButton();
|
d.addCloseButton();
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class SchematicsDialog extends BaseDialog{
|
|||||||
private String search = "";
|
private String search = "";
|
||||||
private TextField searchField;
|
private TextField searchField;
|
||||||
private Runnable rebuildPane = () -> {}, rebuildTags = () -> {};
|
private Runnable rebuildPane = () -> {}, rebuildTags = () -> {};
|
||||||
private Pattern ignoreSymbols = Pattern.compile("[`~!@#$%^&*()-_=+{}|;:'\",<.>/?]");
|
private Pattern ignoreSymbols = Pattern.compile("[`~!@#$%^&*()\\-_=+{}|;:'\",<.>/?]");
|
||||||
private Seq<String> tags, selectedTags = new Seq<>();
|
private Seq<String> tags, selectedTags = new Seq<>();
|
||||||
private boolean checkedTags;
|
private boolean checkedTags;
|
||||||
|
|
||||||
@@ -334,12 +334,6 @@ public class SchematicsDialog extends BaseDialog{
|
|||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void focusSearchField(){
|
|
||||||
if(searchField == null) return;
|
|
||||||
|
|
||||||
Core.scene.setKeyboardFocus(searchField);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//adds all new tags to the global list of tags
|
//adds all new tags to the global list of tags
|
||||||
//alternatively, unknown tags could be discarded on import?
|
//alternatively, unknown tags could be discarded on import?
|
||||||
@@ -635,8 +629,8 @@ public class SchematicsDialog extends BaseDialog{
|
|||||||
public Dialog show(){
|
public Dialog show(){
|
||||||
super.show();
|
super.show();
|
||||||
|
|
||||||
if(Core.app.isDesktop()){
|
if(Core.app.isDesktop() && searchField != null){
|
||||||
focusSearchField();
|
Core.scene.setKeyboardFocus(searchField);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import arc.util.*;
|
|||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.content.TechTree.*;
|
import mindustry.content.TechTree.*;
|
||||||
import mindustry.core.GameState.*;
|
|
||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
@@ -32,7 +31,7 @@ import java.util.zip.*;
|
|||||||
import static arc.Core.*;
|
import static arc.Core.*;
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class SettingsMenuDialog extends Dialog{
|
public class SettingsMenuDialog extends BaseDialog{
|
||||||
public SettingsTable graphics;
|
public SettingsTable graphics;
|
||||||
public SettingsTable game;
|
public SettingsTable game;
|
||||||
public SettingsTable sound;
|
public SettingsTable sound;
|
||||||
@@ -48,39 +47,20 @@ public class SettingsMenuDialog extends Dialog{
|
|||||||
addCloseButton();
|
addCloseButton();
|
||||||
|
|
||||||
cont.add(main = new SettingsTable());
|
cont.add(main = new SettingsTable());
|
||||||
|
shouldPause = true;
|
||||||
hidden(() -> {
|
|
||||||
Sounds.back.play();
|
|
||||||
if(state.isGame()){
|
|
||||||
if(!wasPaused || net.active())
|
|
||||||
state.set(State.playing);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
shown(() -> {
|
shown(() -> {
|
||||||
back();
|
back();
|
||||||
if(state.isGame()){
|
|
||||||
wasPaused = state.is(State.paused);
|
|
||||||
state.set(State.paused);
|
|
||||||
}
|
|
||||||
|
|
||||||
rebuildMenu();
|
rebuildMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.on(ResizeEvent.class, event -> {
|
onResize(() -> {
|
||||||
if(isShown() && Core.scene.getDialog() == this){
|
graphics.rebuild();
|
||||||
graphics.rebuild();
|
sound.rebuild();
|
||||||
sound.rebuild();
|
game.rebuild();
|
||||||
game.rebuild();
|
updateScrollFocus();
|
||||||
updateScrollFocus();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setFillParent(true);
|
|
||||||
title.setAlignment(Align.center);
|
|
||||||
titleTable.row();
|
|
||||||
titleTable.add(new Image()).growX().height(3f).pad(4f).get().setColor(Pal.accent);
|
|
||||||
|
|
||||||
cont.clearChildren();
|
cont.clearChildren();
|
||||||
cont.remove();
|
cont.remove();
|
||||||
buttons.remove();
|
buttons.remove();
|
||||||
|
|||||||
@@ -177,9 +177,7 @@ public class HintsFragment extends Fragment{
|
|||||||
&& state.rules.defaultTeam.core().items.has(Blocks.coreFoundation.requirements),
|
&& state.rules.defaultTeam.core().items.has(Blocks.coreFoundation.requirements),
|
||||||
() -> ui.hints.placedBlocks.contains(Blocks.coreFoundation)),
|
() -> ui.hints.placedBlocks.contains(Blocks.coreFoundation)),
|
||||||
presetLaunch(() -> state.isCampaign()
|
presetLaunch(() -> state.isCampaign()
|
||||||
&& state.getSector().preset == null
|
&& state.getSector().preset == null,
|
||||||
&& SectorPresets.frozenForest.unlocked()
|
|
||||||
&& SectorPresets.frozenForest.sector.save == null,
|
|
||||||
() -> state.isCampaign() && state.getSector().preset == SectorPresets.frozenForest),
|
() -> state.isCampaign() && state.getSector().preset == SectorPresets.frozenForest),
|
||||||
presetDifficulty(() -> state.isCampaign()
|
presetDifficulty(() -> state.isCampaign()
|
||||||
&& state.getSector().preset == null
|
&& state.getSector().preset == null
|
||||||
|
|||||||
@@ -205,10 +205,16 @@ public class Block extends UnlockableContent{
|
|||||||
public int outlinedIcon = -1;
|
public int outlinedIcon = -1;
|
||||||
/** Whether this block has a shadow under it. */
|
/** Whether this block has a shadow under it. */
|
||||||
public boolean hasShadow = true;
|
public boolean hasShadow = true;
|
||||||
/** Sounds made when this block is destroyed.*/
|
/** Should the sound made when this block is built change in pitch. */
|
||||||
public Sound destroySound = Sounds.boom;
|
public boolean placePitchChange = true;
|
||||||
|
/** Should the sound made when this block is deconstructed change in pitch. */
|
||||||
|
public boolean breakPitchChange = true;
|
||||||
|
/** Sound made when this block is built. */
|
||||||
|
public Sound placeSound = Sounds.place;
|
||||||
/** Sound made when this block is deconstructed. */
|
/** Sound made when this block is deconstructed. */
|
||||||
public Sound breakSound = Sounds.breaks;
|
public Sound breakSound = Sounds.breaks;
|
||||||
|
/** Sounds made when this block is destroyed.*/
|
||||||
|
public Sound destroySound = Sounds.boom;
|
||||||
/** How reflective this block is. */
|
/** How reflective this block is. */
|
||||||
public float albedo = 0f;
|
public float albedo = 0f;
|
||||||
/** Environmental passive light color. */
|
/** Environmental passive light color. */
|
||||||
|
|||||||
@@ -62,6 +62,11 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
return Point2.pack(x, y);
|
return Point2.pack(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return this tile's position, packed to the world width - for use in width*height arrays. */
|
||||||
|
public int array(){
|
||||||
|
return x + y * world.tiles.width;
|
||||||
|
}
|
||||||
|
|
||||||
public byte relativeTo(Tile tile){
|
public byte relativeTo(Tile tile){
|
||||||
return relativeTo(tile.x, tile.y);
|
return relativeTo(tile.x, tile.y);
|
||||||
}
|
}
|
||||||
@@ -269,6 +274,10 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
this.floor = type;
|
this.floor = type;
|
||||||
this.overlay = (Floor)Blocks.air;
|
this.overlay = (Floor)Blocks.air;
|
||||||
|
|
||||||
|
if(!headless && !world.isGenerating()){
|
||||||
|
renderer.blocks.removeFloorIndex(this);
|
||||||
|
}
|
||||||
|
|
||||||
recache();
|
recache();
|
||||||
if(build != null){
|
if(build != null){
|
||||||
build.onProximityUpdate();
|
build.onProximityUpdate();
|
||||||
@@ -305,6 +314,8 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
if(!headless && !world.isGenerating()){
|
if(!headless && !world.isGenerating()){
|
||||||
renderer.blocks.floor.recacheTile(this);
|
renderer.blocks.floor.recacheTile(this);
|
||||||
renderer.minimap.update(this);
|
renderer.minimap.update(this);
|
||||||
|
renderer.blocks.invalidateTile(this);
|
||||||
|
renderer.blocks.addFloorIndex(this);
|
||||||
//update neighbor tiles as well
|
//update neighbor tiles as well
|
||||||
for(int i = 0; i < 8; i++){
|
for(int i = 0; i < 8; i++){
|
||||||
Tile other = world.tile(x + Geometry.d8[i].x, y + Geometry.d8[i].y);
|
Tile other = world.tile(x + Geometry.d8[i].x, y + Geometry.d8[i].y);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class ConstructBlock extends Block{
|
|||||||
block.breakEffect.at(tile.drawx(), tile.drawy(), block.size, block.mapColor);
|
block.breakEffect.at(tile.drawx(), tile.drawy(), block.size, block.mapColor);
|
||||||
Events.fire(new BlockBuildEndEvent(tile, builder, team, true, null));
|
Events.fire(new BlockBuildEndEvent(tile, builder, team, true, null));
|
||||||
tile.remove();
|
tile.remove();
|
||||||
if(shouldPlay()) block.breakSound.at(tile, calcPitch(false));
|
if(shouldPlay()) block.breakSound.at(tile, block.breakPitchChange ? calcPitch(false) : 1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server)
|
@Remote(called = Loc.server)
|
||||||
@@ -97,7 +97,7 @@ public class ConstructBlock extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Fx.placeBlock.at(tile.drawx(), tile.drawy(), block.size);
|
Fx.placeBlock.at(tile.drawx(), tile.drawy(), block.size);
|
||||||
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
|
if(shouldPlay()) block.placeSound.at(tile, block.placePitchChange ? calcPitch(true) : 1f);
|
||||||
|
|
||||||
Events.fire(new BlockBuildEndEvent(tile, builder, team, false, config));
|
Events.fire(new BlockBuildEndEvent(tile, builder, team, false, config));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class LaserTurret extends PowerTurret{
|
|||||||
Liquid liquid = liquids.current();
|
Liquid liquid = liquids.current();
|
||||||
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
|
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
|
||||||
|
|
||||||
float used = (cheating() ? maxUsed * Time.delta : Math.min(liquids.get(liquid), maxUsed * Time.delta));
|
float used = (cheating() ? maxUsed : Math.min(liquids.get(liquid), maxUsed)) * Time.delta;
|
||||||
reload -= used * liquid.heatCapacity * coolantMultiplier;
|
reload -= used * liquid.heatCapacity * coolantMultiplier;
|
||||||
liquids.remove(liquid, used);
|
liquids.remove(liquid, used);
|
||||||
|
|
||||||
|
|||||||
@@ -127,24 +127,32 @@ public class GenericCrafter extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(progress >= 1f){
|
if(progress >= 1f){
|
||||||
consume();
|
craft();
|
||||||
|
|
||||||
if(outputItems != null){
|
|
||||||
for(ItemStack output : outputItems){
|
|
||||||
for(int i = 0; i < output.amount; i++){
|
|
||||||
offload(output.item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(outputLiquid != null){
|
|
||||||
handleLiquid(this, outputLiquid.liquid, outputLiquid.amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
craftEffect.at(x, y);
|
|
||||||
progress %= 1f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dumpOutputs();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void craft(){
|
||||||
|
consume();
|
||||||
|
|
||||||
|
if(outputItems != null){
|
||||||
|
for(ItemStack output : outputItems){
|
||||||
|
for(int i = 0; i < output.amount; i++){
|
||||||
|
offload(output.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(outputLiquid != null){
|
||||||
|
handleLiquid(this, outputLiquid.liquid, outputLiquid.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
craftEffect.at(x, y);
|
||||||
|
progress %= 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dumpOutputs(){
|
||||||
if(outputItems != null && timer(timerDump, dumpTime / timeScale)){
|
if(outputItems != null && timer(timerDump, dumpTime / timeScale)){
|
||||||
for(ItemStack output : outputItems){
|
for(ItemStack output : outputItems){
|
||||||
dump(output.item);
|
dump(output.item);
|
||||||
|
|||||||
+17
-4
@@ -1,5 +1,18 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m --illegal-access=permit
|
org.gradle.jvmargs=-Xms256m -Xmx1024m \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED \
|
||||||
|
--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
|
||||||
|
--add-opens=java.base/sun.reflect.annotation=ALL-UNNAMED
|
||||||
|
|
||||||
# Multithreaded
|
# Multithreaded
|
||||||
kapt.use.worker.api=true
|
kapt.use.worker.api=true
|
||||||
# Compilation avoidance (see https://kotlinlang.org/docs/kapt.html#compile-avoidance-for-kapt-since-1-3-20)
|
# Compilation avoidance (see https://kotlinlang.org/docs/kapt.html#compile-avoidance-for-kapt-since-1-3-20)
|
||||||
@@ -9,6 +22,6 @@ kotlin.stdlib.default.dependency=false
|
|||||||
#needed for android compilation
|
#needed for android compilation
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
#used for slow jitpack builds; TODO see if this actually works
|
#used for slow jitpack builds; TODO see if this actually works
|
||||||
http.socketTimeout=80000
|
org.gradle.internal.http.socketTimeout=100000
|
||||||
http.connectionTimeout=80000
|
org.gradle.internal.http.connectionTimeout=100000
|
||||||
archash=b631e4ed8d93513a52ebee6f7e612f7d603062c8
|
archash=57b15a1b73cf0d6f19a50d2111f43d993e57c7f1
|
||||||
|
|||||||
+5
-1
@@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DarkDustry",
|
"name": "DarkDustry",
|
||||||
"address": ["darkdustry.ml", "darkdustry.ml:3000", "darkdustry.ml:7000", "darkdustry.ml:8000"]
|
"address": ["darkdustry.ml", "darkdustry.ml:6000", "darkdustry.ml:7000", "darkdustry.ml:8000", "darkdustry.ml:9000"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Chaotic Neutral",
|
"name": "Chaotic Neutral",
|
||||||
@@ -46,5 +46,9 @@
|
|||||||
{
|
{
|
||||||
"name": "SubZero",
|
"name": "SubZero",
|
||||||
"address": ["minty-server.ddns.net"]
|
"address": ["minty-server.ddns.net"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Shiza Minigames",
|
||||||
|
"address": ["shizashizashiza.ml"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
+2
-2
@@ -17,7 +17,7 @@ def doAntialias = !project.hasProperty("disableAntialias")
|
|||||||
def colorMap = new IntMap<List<Color>>(), colorIndexMap = new IntIntMap()
|
def colorMap = new IntMap<List<Color>>(), colorIndexMap = new IntIntMap()
|
||||||
//on my machine, I have a native Nim AA implementation that is ~10x faster
|
//on my machine, I have a native Nim AA implementation that is ~10x faster
|
||||||
//it's not compiled for other platforms so they don't get it
|
//it's not compiled for other platforms so they don't get it
|
||||||
def useFastAA = System.getProperty("user.name") == "anuke"
|
def useFastAA = project.hasProperty("fastAA") || System.getProperty("user.name") == "anuke"
|
||||||
|
|
||||||
def transformColors = { List<List<String>> list ->
|
def transformColors = { List<List<String>> list ->
|
||||||
list.each{ colors ->
|
list.each{ colors ->
|
||||||
@@ -282,4 +282,4 @@ task updateScripts(dependsOn: classes, type: JavaExec){
|
|||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
standardInput = System.in
|
standardInput = System.in
|
||||||
workingDir = "../"
|
workingDir = "../"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user