Merge branch 'master' of https://github.com/Anuken/Mindustry into new-pathfinding

This commit is contained in:
Anuken
2023-11-19 18:32:14 -05:00
29 changed files with 244 additions and 189 deletions

View File

@@ -399,6 +399,8 @@ public class CommandAI extends AIController{
@Override
public void commandPosition(Vec2 pos){
if(pos == null) return;
commandPosition(pos, false);
if(commandController != null){
commandController.commandPosition(pos);
@@ -406,8 +408,10 @@ public class CommandAI extends AIController{
}
public void commandPosition(Vec2 pos, boolean stopWhenInRange){
targetPos = pos;
lastTargetPos = pos;
if(pos == null) return;
//this is an allocation, but it's relatively rarely called anyway, and outside mutations must be prevented
targetPos = lastTargetPos = pos.cpy();
attackTarget = null;
pathId = Vars.controlPath.nextTargetId();
this.stopWhenInRange = stopWhenInRange;

View File

@@ -570,7 +570,7 @@ public class Blocks{
snowWall = new StaticWall("snow-wall");
duneWall = new StaticWall("dune-wall"){{
basalt.asFloor().wall = darksandWater.asFloor().wall = darksandTaintedWater.asFloor().wall = this;
hotrock.asFloor().wall = magmarock.asFloor().wall = basalt.asFloor().wall = darksandWater.asFloor().wall = darksandTaintedWater.asFloor().wall = this;
attributes.set(Attribute.sand, 2f);
}};
@@ -2408,7 +2408,7 @@ public class Blocks{
largeSolarPanel = new SolarGenerator("solar-panel-large"){{
requirements(Category.power, with(Items.lead, 80, Items.silicon, 110, Items.phaseFabric, 15));
size = 3;
powerProduction = 1.3f;
powerProduction = 1.6f;
}};
thoriumReactor = new NuclearReactor("thorium-reactor"){{
@@ -3968,6 +3968,7 @@ public class Blocks{
hitColor = Pal.meltdownHit;
status = StatusEffects.melting;
drawSize = 420f;
timescaleDamage = true;
incendChance = 0.4f;
incendSpread = 5f;

View File

@@ -447,11 +447,11 @@ public class ErekirTechTree{
//nodeProduce(Liquids.gallium, () -> {});
});
});
nodeProduce(Items.surgeAlloy, () -> {
nodeProduce(Items.phaseFabric, () -> {
nodeProduce(Items.surgeAlloy, () -> {
nodeProduce(Items.phaseFabric, () -> {
});
});
});
});

View File

@@ -197,7 +197,7 @@ public class UnitTypes{
singleTarget = true;
drownTimeMultiplier = 4f;
abilities.add(new ShieldRegenFieldAbility(25f, 500f, 60f * 1, 60f));
abilities.add(new ShieldRegenFieldAbility(25f, 250f, 60f * 1, 60f));
BulletType smallBullet = new BasicBulletType(3f, 10){{
width = 7f;

View File

@@ -28,6 +28,7 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
private int index;
public static int nextId(){
if(lastId >= Integer.MAX_VALUE - 2) lastId = 0;
return lastId++;
}

View File

@@ -93,7 +93,8 @@ public class ShieldArcAbility extends Ability{
paramField = this;
paramPos.set(x, y).rotate(unit.rotation - 90f).add(unit);
Groups.bullet.intersect(unit.x - radius, unit.y - radius, radius * 2f, radius * 2f, shieldConsumer);
float reach = radius + width / 2f;
Groups.bullet.intersect(paramPos.x - reach, paramPos.y - reach, reach * 2f, reach * 2f, shieldConsumer);
}else{
widthScale = Mathf.lerpDelta(widthScale, 0f, 0.11f);
}

View File

@@ -160,6 +160,8 @@ public class BulletType extends Content implements Cloneable{
/** Bullet type that is created when this bullet expires. */
public @Nullable BulletType fragBullet = null;
/** If true, frag bullets are delayed to the next frame. Fixes obscure bugs with piercing bullet types spawning frags immediately and screwing up the Damage temporary variables. */
public boolean delayFrags = false;
/** Degree spread range of fragmentation bullets. */
public float fragRandomSpread = 360f;
/** Uniform spread between each frag bullet in degrees. */
@@ -446,7 +448,11 @@ public class BulletType extends Content implements Cloneable{
Effect.shake(hitShake, hitShake, b);
if(fragOnHit){
createFrags(b, x, y);
if(delayFrags && fragBullet != null && fragBullet.delayFrags){
Core.app.post(() -> createFrags(b, x, y));
}else{
createFrags(b, x, y);
}
}
createPuddles(b, x, y);
createIncend(b, x, y);

View File

@@ -11,6 +11,8 @@ public class ContinuousBulletType extends BulletType{
public float damageInterval = 5f;
public boolean largeHit = false;
public boolean continuous = true;
/** If a building fired this, whether to multiply damage by its timescale. */
public boolean timescaleDamage = false;
{
removeAfterPierce = false;
@@ -79,7 +81,12 @@ public class ContinuousBulletType extends BulletType{
}
public void applyDamage(Bullet b){
float damage = b.damage;
if(timescaleDamage && b.owner instanceof Building build){
b.damage *= build.timeScale();
}
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), currentLength(b), largeHit, laserAbsorb, pierceCap);
b.damage = damage;
}
public float currentLength(Bullet b){

View File

@@ -38,6 +38,7 @@ public class LaserBulletType extends BulletType{
hittable = false;
absorbable = false;
removeAfterPierce = false;
delayFrags = true;
}
public LaserBulletType(){

View File

@@ -24,6 +24,7 @@ public class RailBulletType extends BulletType{
collides = false;
keepVelocity = false;
lifetime = 1f;
delayFrags = true;
}
@Override
@@ -60,7 +61,7 @@ public class RailBulletType extends BulletType{
super.init(b);
b.fdata = length;
Damage.collideLine(b, b.team, b.type.hitEffect, b.x, b.y, b.rotation(), length, false, false);
Damage.collideLine(b, b.team, b.type.hitEffect, b.x, b.y, b.rotation(), length, false, false, pierceCap);
float resultLen = b.fdata;
Vec2 nor = Tmp.v1.trns(b.rotation(), 1f).nor();

View File

@@ -1569,7 +1569,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
consumed = true;
if((!config.isShown() && build.shouldShowConfigure(player)) //if the config fragment is hidden, show
//alternatively, the current selected block can 'agree' to switch config tiles
|| (config.isShown() && config.getSelected().onConfigureBuildTapped(build))){
|| (config.isShown() && config.getSelected().onConfigureBuildTapped(build) && build.shouldShowConfigure(player))){
Sounds.click.at(build);
config.showConfig(build);
}

View File

@@ -1459,7 +1459,8 @@ public class LExecutor{
case ban -> {
Object cont = exec.obj(value);
if(cont instanceof Block b){
state.rules.bannedBlocks.add(b);
// Rebuild PlacementFragment if anything has changed
if(state.rules.bannedBlocks.add(b) && !headless) ui.hudfrag.blockfrag.rebuild();
}else if(cont instanceof UnitType u){
state.rules.bannedUnits.add(u);
}
@@ -1467,7 +1468,7 @@ public class LExecutor{
case unban -> {
Object cont = exec.obj(value);
if(cont instanceof Block b){
state.rules.bannedBlocks.remove(b);
if(state.rules.bannedBlocks.remove(b) && !headless) ui.hudfrag.blockfrag.rebuild();
}else if(cont instanceof UnitType u){
state.rules.bannedUnits.remove(u);
}

View File

@@ -335,7 +335,7 @@ public abstract class BasicGenerator implements WorldGenerator{
ore = tile.overlay();
r.get(tile.x, tile.y);
tile.setFloor(floor.asFloor());
tile.setBlock(block);
if(block != tile.block()) tile.setBlock(block);
tile.setOverlay(ore);
}
}

View File

@@ -10,7 +10,6 @@ import mindustry.game.SectorInfo.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.defense.*;
import mindustry.world.blocks.defense.Wall.*;
import mindustry.world.blocks.defense.turrets.Turret.*;
import mindustry.world.blocks.distribution.*;
@@ -111,16 +110,10 @@ public class GameService{
completeSerpulo.complete();
}
if(mods.list().size > 0){
if(mods != null && mods.list().size > 0){
installMod.complete();
}
Events.on(ClientLoadEvent.class, e -> {
if(mods.list().size > 0){
installMod.complete();
}
});
if(Core.bundle.get("yes").equals("router")){
routerLanguage.complete();
}
@@ -231,8 +224,8 @@ public class GameService{
}
}
if(e.tile.block() instanceof MendProjector || e.tile.block() instanceof RegenProjector) buildMendProjector.complete();
if(e.tile.block() instanceof OverdriveProjector) buildOverdriveProjector.complete();
if(e.tile.block() == Blocks.mendProjector) buildMendProjector.complete();
if(e.tile.block() == Blocks.overdriveProjector) buildOverdriveProjector.complete();
if(e.tile.block() == Blocks.waterExtractor){
if(e.tile.getLinkedTiles(tmpTiles).contains(t -> t.floor().liquidDrop == Liquids.water)){
@@ -459,7 +452,8 @@ public class GameService{
//check unlocked stuff on load as well
Events.on(ResearchEvent.class, e -> checkUnlocks.run());
Events.on(UnlockEvent.class, e -> checkUnlocks.run());
Events.on(ClientLoadEvent.class, e -> checkUnlocks.run());
checkUnlocks.run();
Events.on(WinEvent.class, e -> {
if(state.rules.pvp){

View File

@@ -247,29 +247,12 @@ public class JoinDialog extends BaseDialog{
void setupServer(Server server, Host host){
server.lastHost = host;
server.content.clear();
buildServer(host, server.content);
buildServer(host, server.content, false);
}
void buildServer(Host host, Table content){
void buildServer(Host host, Table content, boolean inner){
content.top().left();
String versionString;
if(host.version == -1){
versionString = Core.bundle.format("server.version", Core.bundle.get("server.custombuild"), "");
}else if(host.version == 0){
versionString = Core.bundle.get("server.outdated");
}else if(host.version < Version.build && Version.build != -1){
versionString = Core.bundle.get("server.outdated") + "\n" +
Core.bundle.format("server.version", host.version, "");
}else if(host.version > Version.build && Version.build != -1){
versionString = Core.bundle.get("server.outdated.client") + "\n" +
Core.bundle.format("server.version", host.version, "");
}else if(host.version == Version.build && Version.type.equals(host.versionType)){
//not important
versionString = "";
}else{
versionString = Core.bundle.format("server.version", host.version, host.versionType);
}
String versionString = getVersionString(host);
float twidth = targetWidth() - 40f;
@@ -277,12 +260,14 @@ public class JoinDialog extends BaseDialog{
Color color = Pal.gray;
content.table(Tex.whiteui, t -> {
t.left();
t.setColor(color);
if(inner){
content.table(Tex.whiteui, t -> {
t.left();
t.setColor(color);
t.add(host.name + " " + versionString).style(Styles.outlineLabel).padLeft(10f).width(twidth).left().ellipsis(true);
}).growX().height(36f).row();
t.add(host.name + " " + versionString).style(Styles.outlineLabel).padLeft(10f).width(twidth).left().ellipsis(true);
}).growX().height(36f).row();
}
content.table(Tex.whitePane, t -> {
t.top().left();
@@ -485,11 +470,16 @@ public class JoinDialog extends BaseDialog{
void addCommunityHost(Host host, Table container){
global.background(null);
String versionString = getVersionString(host);
float w = targetWidth();
container.left().top();
container.button(b -> buildServer(host, b), style, () -> {
Button[] button = {null};
button[0] = container.button(b -> {}, style, () -> {
if(button[0].childrenPressed()) return;
Events.fire(new ClientPreConnectEvent(host));
if(!Core.settings.getBool("server-disclaimer", false)){
ui.showCustomConfirm("@warning", "@servers.disclaimer", "@ok", "@back", () -> {
@@ -501,7 +491,28 @@ public class JoinDialog extends BaseDialog{
}else{
safeConnect(host.address, host.port, host.version);
}
}).width(w).padBottom(7).padRight(4f).top().left().growY().uniformY();
}).width(w).padBottom(7).padRight(4f).top().left().growY().uniformY().get();
Table inner = new Table(Tex.whiteui);
inner.setColor(Pal.gray);
button[0].clearChildren();
button[0].add(inner).growX();
inner.add(host.name + " " + versionString).left().padLeft(10f).wrap().style(Styles.outlineLabel).growX();
inner.button(Icon.add, Styles.emptyi, () -> {
Server server = new Server();
server.setIP(host.address + ":" + host.port);
servers.add(server);
saveServers();
setupRemote();
refreshRemote();
}).margin(3f).pad(8f).padRight(4f).top().right();
button[0].row();
buildServer(host, button[0].table(t -> {}).grow().get(), false);
if((container.getChildren().size) % columns() == 0){
container.row();
@@ -532,7 +543,7 @@ public class JoinDialog extends BaseDialog{
local.row();
}
local.button(b -> buildServer(host, b), style, () -> {
local.button(b -> buildServer(host, b, true), style, () -> {
Events.fire(new ClientPreConnectEvent(host));
safeConnect(host.address, host.port, host.version);
}).width(w).top().left().growY();
@@ -641,6 +652,25 @@ public class JoinDialog extends BaseDialog{
Core.settings.putJson("servers", Server.class, servers);
}
private String getVersionString(Host host){
if(host.version == -1){
return Core.bundle.format("server.version", Core.bundle.get("server.custombuild"), "");
}else if(host.version == 0){
return Core.bundle.get("server.outdated");
}else if(host.version < Version.build && Version.build != -1){
return Core.bundle.get("server.outdated") + "\n" +
Core.bundle.format("server.version", host.version, "");
}else if(host.version > Version.build && Version.build != -1){
return Core.bundle.get("server.outdated.client") + "\n" +
Core.bundle.format("server.version", host.version, "");
}else if(host.version == Version.build && Version.type.equals(host.versionType)){
//not important
return "";
}else{
return Core.bundle.format("server.version", host.version, host.versionType);
}
}
public static class Server{
public String ip;
public int port;

View File

@@ -113,7 +113,7 @@ public class PlacementFragment{
return hover;
}
void rebuild(){
public void rebuild(){
//category does not change on rebuild anymore, only on new world load
Group group = toggler.parent;
int index = toggler.getZIndex();

View File

@@ -78,7 +78,7 @@ public class LaserTurret extends PowerTurret{
entry.bullet.set(bulletX, bulletY);
entry.bullet.time = entry.bullet.type.lifetime * entry.bullet.type.optimalLifeFract;
entry.bullet.keepAlive = true;
entry.life -= Time.delta / Math.max(efficiency, 0.00001f);
entry.life -= Time.delta * timeScale / Math.max(efficiency, 0.00001f);
}
wasShooting = true;

View File

@@ -418,14 +418,23 @@ public class ItemBridge extends Block{
checkAccept(source, world.tile(link));
}
protected boolean checkAccept(Building source, Tile other){
protected boolean checkAccept(Building source, Tile link){
if(tile == null || linked(source)) return true;
if(linkValid(tile, other)){
int rel = relativeTo(other);
if(linkValid(tile, link)){
int rel = relativeTo(link);
var facing = Edges.getFacingEdge(source, this);
int rel2 = facing == null ? -1 : relativeTo(facing);
//this is a bug, but it is kept for compatibility, see: https://github.com/Anuken/Mindustry/issues/9257#issuecomment-1801998747
/*
for(int j = 0; j < incoming.size; j++){
int v = incoming.items[j];
if(relativeTo(Point2.x(v), Point2.y(v)) == rel2){
return false;
}
}*/
return rel != rel2;
}

View File

@@ -122,9 +122,10 @@ public class BeamNode extends PowerBlock{
@Override
public BlockStatus status(){
if(Mathf.equal(power.status, 0f, 0.001f)) return BlockStatus.noInput;
if(Mathf.equal(power.status, 1f, 0.001f)) return BlockStatus.active;
return BlockStatus.noOutput;
float balance = power.graph.getPowerBalance();
if(balance > 0f) return BlockStatus.active;
if(balance < 0f && power.graph.getLastPowerStored() > 0) return BlockStatus.noOutput;
return BlockStatus.noInput;
}
@Override

View File

@@ -5,6 +5,7 @@ import arc.struct.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.gen.*;
import mindustry.logic.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.storage.CoreBlock.*;
@@ -100,6 +101,12 @@ public class StorageBlock extends Block{
}
}
@Override
public double sense(LAccess sensor){
if(sensor == LAccess.itemCapacity && linkedCore != null) return linkedCore.sense(sensor);
return super.sense(sensor);
}
@Override
public void overwrote(Seq<Building> previous){
//only add prev items when core is not linked

View File

@@ -444,7 +444,7 @@ public class UnitAssembler extends PayloadBlock{
if(!net.client()){
var unit = plan.unit.create(team);
if(unit != null && unit.isCommandable()){
if(unit != null && unit.isCommandable() && commandPos != null){
unit.command().commandPosition(commandPos);
}
unit.set(spawn.x + Mathf.range(0.001f), spawn.y + Mathf.range(0.001f));