Merge branch 'master' into do-you-hear-the-voices-too
This commit is contained in:
@@ -47,6 +47,8 @@ public class BuilderAI extends AIController{
|
||||
|
||||
if(target != null && shouldShoot()){
|
||||
unit.lookAt(target);
|
||||
}else if(!unit.type.flying){
|
||||
unit.lookAt(unit.prefRotation());
|
||||
}
|
||||
|
||||
unit.updateBuilding = true;
|
||||
@@ -55,6 +57,8 @@ public class BuilderAI extends AIController{
|
||||
following = assistFollowing;
|
||||
}
|
||||
|
||||
boolean moving = false;
|
||||
|
||||
if(following != null){
|
||||
retreatTimer = 0f;
|
||||
//try to follow and mimic someone
|
||||
@@ -83,6 +87,7 @@ public class BuilderAI extends AIController{
|
||||
var core = unit.closestCore();
|
||||
if(core != null && !unit.within(core, retreatDst)){
|
||||
moveTo(core, retreatDst);
|
||||
moving = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,7 +119,8 @@ public class BuilderAI extends AIController{
|
||||
|
||||
if(valid){
|
||||
//move toward the plan
|
||||
moveTo(req.tile(), unit.type.buildRange - 20f);
|
||||
moveTo(req.tile(), unit.type.buildRange - 20f, 20f);
|
||||
moving = !unit.within(req.tile(), unit.type.buildRange - 10f);
|
||||
}else{
|
||||
//discard invalid plan
|
||||
unit.plans.removeFirst();
|
||||
@@ -124,6 +130,7 @@ public class BuilderAI extends AIController{
|
||||
|
||||
if(assistFollowing != null){
|
||||
moveTo(assistFollowing, assistFollowing.type.hitSize + unit.type.hitSize/2f + 60f);
|
||||
moving = !unit.within(assistFollowing, assistFollowing.type.hitSize + unit.type.hitSize/2f + 65f);
|
||||
}
|
||||
|
||||
//follow someone and help them build
|
||||
@@ -186,6 +193,10 @@ public class BuilderAI extends AIController{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!unit.type.flying){
|
||||
unit.updateBoosting(moving || unit.floorOn().isDuct || unit.floorOn().damageTaken > 0f);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean nearEnemy(int x, int y){
|
||||
|
||||
@@ -164,8 +164,11 @@ public class SoundControl{
|
||||
//this just fades out the last track to make way for ingame music
|
||||
silence();
|
||||
|
||||
//play music at intervals
|
||||
if(Time.timeSinceMillis(lastPlayed) > 1000 * musicInterval / 60f){
|
||||
if(Core.settings.getBool("alwaysmusic")){
|
||||
if(current == null){
|
||||
playRandom();
|
||||
}
|
||||
}else if(Time.timeSinceMillis(lastPlayed) > 1000 * musicInterval / 60f){
|
||||
//chance to play it per interval
|
||||
if(Mathf.chance(musicChance)){
|
||||
lastPlayed = Time.millis();
|
||||
@@ -213,7 +216,9 @@ public class SoundControl{
|
||||
|
||||
/** Plays a random track.*/
|
||||
public void playRandom(){
|
||||
if(isDark()){
|
||||
if(state.boss() != null){
|
||||
playOnce(bossMusic.random(lastRandomPlayed));
|
||||
}else if(isDark()){
|
||||
playOnce(darkMusic.random(lastRandomPlayed));
|
||||
}else{
|
||||
playOnce(ambientMusic.random(lastRandomPlayed));
|
||||
|
||||
@@ -322,7 +322,7 @@ public class UnitTypes{
|
||||
speed = 0.55f;
|
||||
hitSize = 8f;
|
||||
health = 120f;
|
||||
buildSpeed = 0.8f;
|
||||
buildSpeed = 0.35f;
|
||||
armor = 1f;
|
||||
|
||||
abilities.add(new RepairFieldAbility(10f, 60f * 4, 60f));
|
||||
@@ -354,7 +354,7 @@ public class UnitTypes{
|
||||
speed = 0.7f;
|
||||
hitSize = 11f;
|
||||
health = 320f;
|
||||
buildSpeed = 0.9f;
|
||||
buildSpeed = 0.5f;
|
||||
armor = 4f;
|
||||
riseSpeed = 0.07f;
|
||||
|
||||
@@ -408,7 +408,7 @@ public class UnitTypes{
|
||||
mineTier = 3;
|
||||
boostMultiplier = 2f;
|
||||
health = 640f;
|
||||
buildSpeed = 1.7f;
|
||||
buildSpeed = 1.1f;
|
||||
canBoost = true;
|
||||
armor = 9f;
|
||||
mechLandShake = 2f;
|
||||
|
||||
@@ -82,7 +82,7 @@ public class ForceFieldAbility extends Ability{
|
||||
if(unit.shield <= 0f && !wasBroken){
|
||||
unit.shield -= cooldown * regen;
|
||||
|
||||
Fx.shieldBreak.at(unit.x, unit.y, radius, unit.team.color, this);
|
||||
Fx.shieldBreak.at(unit.x, unit.y, radius, unit.type.shieldColor(unit), this);
|
||||
}
|
||||
|
||||
wasBroken = unit.shield <= 0f;
|
||||
@@ -110,7 +110,7 @@ public class ForceFieldAbility extends Ability{
|
||||
checkRadius(unit);
|
||||
|
||||
if(unit.shield > 0){
|
||||
Draw.color(unit.team.color, Color.white, Mathf.clamp(alpha));
|
||||
Draw.color(unit.type.shieldColor(unit), Color.white, Mathf.clamp(alpha));
|
||||
|
||||
if(Vars.renderer.animateShields){
|
||||
Draw.z(Layer.shields + 0.001f * alpha);
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ShieldArcAbility extends Ability{
|
||||
if(paramField.data <= b.damage()){
|
||||
paramField.data -= paramField.cooldown * paramField.regen;
|
||||
|
||||
Fx.arcShieldBreak.at(paramPos.x, paramPos.y, 0, paramUnit.team.color, paramUnit);
|
||||
Fx.arcShieldBreak.at(paramPos.x, paramPos.y, 0, paramField.color == null ? paramUnit.type.shieldColor(paramUnit) : paramField.color, paramUnit);
|
||||
}
|
||||
|
||||
paramField.data -= b.damage();
|
||||
@@ -60,6 +60,8 @@ public class ShieldArcAbility extends Ability{
|
||||
public boolean drawArc = true;
|
||||
/** If not null, will be drawn on top. */
|
||||
public @Nullable String region;
|
||||
/** Color override of the shield. Uses unit shield colour by default. */
|
||||
public @Nullable Color color;
|
||||
/** If true, sprite position will be influenced by x/y. */
|
||||
public boolean offsetRegion = false;
|
||||
|
||||
@@ -109,7 +111,7 @@ public class ShieldArcAbility extends Ability{
|
||||
if(widthScale > 0.001f){
|
||||
Draw.z(Layer.shields);
|
||||
|
||||
Draw.color(unit.team.color, Color.white, Mathf.clamp(alpha));
|
||||
Draw.color(color == null ? unit.type.shieldColor(unit) : color, Color.white, Mathf.clamp(alpha));
|
||||
var pos = paramPos.set(x, y).rotate(unit.rotation - 90f).add(unit);
|
||||
|
||||
if(!Vars.renderer.animateShields){
|
||||
|
||||
@@ -48,13 +48,13 @@ public class ShieldRegenFieldAbility extends Ability{
|
||||
if(other.shield < max){
|
||||
other.shield = Math.min(other.shield + amount, max);
|
||||
other.shieldAlpha = 1f; //TODO may not be necessary
|
||||
applyEffect.at(unit.x, unit.y, 0f, unit.team.color, parentizeEffects ? other : null);
|
||||
applyEffect.at(other.x, other.y, 0f, other.type.shieldColor(other), parentizeEffects ? other : null);
|
||||
applied = true;
|
||||
}
|
||||
});
|
||||
|
||||
if(applied){
|
||||
activeEffect.at(unit.x, unit.y, unit.team.color);
|
||||
activeEffect.at(unit.x, unit.y, unit.type.shieldColor(unit));
|
||||
}
|
||||
|
||||
timer = 0f;
|
||||
|
||||
@@ -87,6 +87,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
transient float optionalEfficiency;
|
||||
/** The efficiency this block *would* have if shouldConsume() returned true. */
|
||||
transient float potentialEfficiency;
|
||||
/** Whether there are any consumers (aside from power) that have efficiency > 0. */
|
||||
transient boolean shouldConsumePower;
|
||||
|
||||
transient float healSuppressionTime = -1f;
|
||||
transient float lastHealTime = -120f * 10f;
|
||||
@@ -1773,6 +1775,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
if(!block.hasConsumers || cheating()){
|
||||
potentialEfficiency = enabled && productionValid() ? 1f : 0f;
|
||||
efficiency = optionalEfficiency = shouldConsume() ? potentialEfficiency : 0f;
|
||||
shouldConsumePower = true;
|
||||
updateEfficiencyMultiplier();
|
||||
return;
|
||||
}
|
||||
@@ -1780,6 +1783,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
//disabled -> nothing works
|
||||
if(!enabled){
|
||||
potentialEfficiency = efficiency = optionalEfficiency = 0f;
|
||||
shouldConsumePower = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1789,10 +1793,17 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
//assume efficiency is 1 for the calculations below
|
||||
efficiency = optionalEfficiency = 1f;
|
||||
shouldConsumePower = true;
|
||||
|
||||
//first pass: get the minimum efficiency of any consumer
|
||||
for(var cons : block.nonOptionalConsumers){
|
||||
minEfficiency = Math.min(minEfficiency, cons.efficiency(self()));
|
||||
float result = cons.efficiency(self());
|
||||
|
||||
if(cons != block.consPower && result <= 0.0000001f){
|
||||
shouldConsumePower = false;
|
||||
}
|
||||
|
||||
minEfficiency = Math.min(minEfficiency, result);
|
||||
}
|
||||
|
||||
//same for optionals
|
||||
|
||||
@@ -47,6 +47,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
transient float deathTimer;
|
||||
transient String lastText = "";
|
||||
transient float textFadeTime;
|
||||
transient Ratekeeper itemDepositRate = new Ratekeeper();
|
||||
|
||||
transient private Unit lastReadUnit = Nulls.unit;
|
||||
transient private int wrongReadUnits;
|
||||
|
||||
@@ -61,7 +61,7 @@ abstract class ShieldComp implements Healthc, Posc{
|
||||
}
|
||||
|
||||
if(hadShields && shield <= 0.0001f){
|
||||
Fx.unitShieldBreak.at(x, y, 0, team.color, this);
|
||||
Fx.unitShieldBreak.at(x, y, 0, type.shieldColor(self()), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public enum Gamemode{
|
||||
}, map -> map.spawns > 0),
|
||||
sandbox(rules -> {
|
||||
rules.infiniteResources = true;
|
||||
rules.allowEditRules = true;
|
||||
rules.waves = true;
|
||||
rules.waveTimer = false;
|
||||
}),
|
||||
|
||||
@@ -19,6 +19,8 @@ import mindustry.world.blocks.*;
|
||||
* Does not store game state, just configuration.
|
||||
*/
|
||||
public class Rules{
|
||||
/** Allows editing the rules in-game. Essentially a cheat mode toggle. */
|
||||
public boolean allowEditRules = false;
|
||||
/** Sandbox mode: Enables infinite resources, build range and build speed. */
|
||||
public boolean infiniteResources;
|
||||
/** Team-specific rules. */
|
||||
@@ -105,6 +107,8 @@ public class Rules{
|
||||
public boolean cleanupDeadTeams = true;
|
||||
/** If true, items can only be deposited in the core. */
|
||||
public boolean onlyDepositCore = false;
|
||||
/** Cooldown, in seconds, of item depositing for players. */
|
||||
public float itemDepositCooldown = 0.5f;
|
||||
/** If true, every enemy block in the radius of the (enemy) core is destroyed upon death. Used for campaign maps. */
|
||||
public boolean coreDestroyClear = false;
|
||||
/** If true, banned blocks are hidden from the build menu. */
|
||||
|
||||
@@ -241,7 +241,9 @@ public class OverlayRenderer{
|
||||
Draw.reset();
|
||||
|
||||
Building build = world.buildWorld(v.x, v.y);
|
||||
if(input.canDropItem() && build != null && build.interactable(player.team()) && build.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(build, itemTransferRange)){
|
||||
if(input.canDropItem() && build != null && build.interactable(player.team()) && build.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(build, itemTransferRange) &&
|
||||
input.itemDepositCooldown <= 0f){
|
||||
|
||||
boolean invalid = (state.rules.onlyDepositCore && !(build instanceof CoreBuild));
|
||||
|
||||
Lines.stroke(3f, Pal.gray);
|
||||
|
||||
@@ -114,12 +114,12 @@ public class DesktopInput extends InputHandler{
|
||||
|
||||
//draw break selection
|
||||
if(mode == breaking){
|
||||
drawBreakSelection(selectX, selectY, cursorX, cursorY, !Core.input.keyDown(Binding.schematic_select) ? maxLength : Vars.maxSchematicSize, false);
|
||||
drawBreakSelection(selectX, selectY, cursorX, cursorY, !(Core.input.keyDown(Binding.schematic_select) && schemX != -1 && schemY != -1) ? maxLength : Vars.maxSchematicSize, false);
|
||||
}
|
||||
|
||||
if(!Core.scene.hasKeyboard() && mode != breaking){
|
||||
|
||||
if(Core.input.keyDown(Binding.schematic_select)){
|
||||
if(Core.input.keyDown(Binding.schematic_select) && schemX != -1 && schemY != -1){
|
||||
drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize);
|
||||
}else if(Core.input.keyDown(Binding.rebuild_select)){
|
||||
drawRebuildSelection(schemX, schemY, cursorX, cursorY);
|
||||
@@ -594,7 +594,7 @@ public class DesktopInput extends InputHandler{
|
||||
selectPlans.clear();
|
||||
}
|
||||
|
||||
if( !Core.scene.hasKeyboard() && selectX == -1 && selectY == -1 && schemX != -1 && schemY != -1){
|
||||
if(!Core.scene.hasKeyboard() && selectX == -1 && selectY == -1 && schemX != -1 && schemY != -1){
|
||||
if(Core.input.keyRelease(Binding.schematic_select)){
|
||||
lastSchematic = schematics.create(schemX, schemY, rawCursorX, rawCursorY);
|
||||
useSchematic(lastSchematic);
|
||||
|
||||
@@ -83,6 +83,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
public boolean overrideLineRotation;
|
||||
public int rotation;
|
||||
public boolean droppingItem;
|
||||
public float itemDepositCooldown;
|
||||
public Group uiGroup;
|
||||
public boolean isBuilding = true, buildWasAutoPaused = false, wasShooting = false;
|
||||
public @Nullable UnitType controlledType;
|
||||
@@ -142,6 +143,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
Events.on(ResetEvent.class, e -> {
|
||||
logicCutscene = false;
|
||||
itemDepositCooldown = 0f;
|
||||
Arrays.fill(controlGroups, null);
|
||||
});
|
||||
}
|
||||
@@ -423,6 +425,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
if(player == null || build == null || !player.within(build, itemTransferRange) || build.items == null || player.dead() || (state.rules.onlyDepositCore && !(build instanceof CoreBuild))) return;
|
||||
|
||||
if(net.server() && (player.unit().stack.amount <= 0 || !Units.canInteract(player, build) ||
|
||||
//to avoid rejecting deposit packets that happen to overlap due to packet speed differences, the actual cap is double the cooldown with 2 deposits.
|
||||
(!player.isLocal() && !player.itemDepositRate.allow((long)(state.rules.itemDepositCooldown * 1000 * 2), 2)) ||
|
||||
|
||||
!netServer.admins.allowAction(player, ActionType.depositItem, build.tile, action -> {
|
||||
action.itemAmount = player.unit().stack.amount;
|
||||
action.item = player.unit().item();
|
||||
@@ -796,6 +801,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
logicCutsceneZoom = -1f;
|
||||
}
|
||||
|
||||
itemDepositCooldown -= Time.delta / 60f;
|
||||
|
||||
commandBuildings.removeAll(b -> !b.isValid());
|
||||
|
||||
if(!commandMode){
|
||||
@@ -1859,8 +1866,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
if(build != null && build.acceptStack(stack.item, stack.amount, player.unit()) > 0 && build.interactable(player.team()) &&
|
||||
build.block.hasItems && player.unit().stack().amount > 0 && build.interactable(player.team())){
|
||||
if(!(state.rules.onlyDepositCore && !(build instanceof CoreBuild))){
|
||||
|
||||
if(!(state.rules.onlyDepositCore && !(build instanceof CoreBuild)) && itemDepositCooldown <= 0f){
|
||||
Call.transferInventory(player, build);
|
||||
itemDepositCooldown = state.rules.itemDepositCooldown;
|
||||
}
|
||||
}else{
|
||||
Call.dropItem(player.angleTo(x, y));
|
||||
|
||||
@@ -1923,7 +1923,7 @@ public class LStatements{
|
||||
table.add(" on ");
|
||||
fields(table, channel, str -> channel = str);
|
||||
table.add(", reliable ");
|
||||
fields(table, channel, str -> channel = str);
|
||||
fields(table, reliable, str -> reliable = str);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -99,7 +99,7 @@ public class StatusEffect extends UnlockableContent{
|
||||
boolean reacts = false;
|
||||
|
||||
for(var e : opposites.toSeq().sort()){
|
||||
stats.add(Stat.opposites, e.emoji() + "" + e);
|
||||
stats.add(Stat.opposites, e.emoji() + e);
|
||||
}
|
||||
|
||||
if(reactive){
|
||||
|
||||
@@ -259,6 +259,8 @@ public class UnitType extends UnlockableContent implements Senseable{
|
||||
public Color healColor = Pal.heal;
|
||||
/** Color of light that this unit produces when lighting is enabled in the map. */
|
||||
public Color lightColor = Pal.powerLight;
|
||||
/** override for unit shield colour. */
|
||||
public @Nullable Color shieldColor;
|
||||
/** sound played when this unit explodes (*not* when it is shot down) */
|
||||
public Sound deathSound = Sounds.bang;
|
||||
/** sound played on loop when this unit is around. */
|
||||
@@ -826,6 +828,10 @@ public class UnitType extends UnlockableContent implements Senseable{
|
||||
|
||||
if(canBoost){
|
||||
cmds.add(UnitCommand.boostCommand);
|
||||
|
||||
if(buildSpeed > 0f){
|
||||
cmds.add(UnitCommand.rebuildCommand, UnitCommand.assistCommand);
|
||||
}
|
||||
}
|
||||
|
||||
//healing, mining and building is only supported for flying units; pathfinding to ambiguously reachable locations is hard.
|
||||
@@ -1305,6 +1311,12 @@ public class UnitType extends UnlockableContent implements Senseable{
|
||||
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
//...where do I put this
|
||||
public Color shieldColor(Unit unit){
|
||||
return shieldColor == null ? unit.team.color : shieldColor;
|
||||
}
|
||||
|
||||
|
||||
public void drawMining(Unit unit){
|
||||
if(!unit.mining()) return;
|
||||
@@ -1345,7 +1357,7 @@ public class UnitType extends UnlockableContent implements Senseable{
|
||||
float radius = unit.hitSize() * 1.3f;
|
||||
Fill.light(unit.x, unit.y, Lines.circleVertices(radius), radius,
|
||||
Color.clear,
|
||||
Tmp.c2.set(unit.team.color).lerp(Color.white, Mathf.clamp(unit.hitTime() / 2f)).a(0.7f * alpha)
|
||||
Tmp.c2.set(unit.type.shieldColor(unit)).lerp(Color.white, Mathf.clamp(unit.hitTime() / 2f)).a(0.7f * alpha)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,16 +30,24 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
private Table main;
|
||||
private Prov<Rules> resetter;
|
||||
private LoadoutDialog loadoutDialog;
|
||||
|
||||
public boolean showRuleEditRule;
|
||||
public Seq<Table> categories;
|
||||
public Table current;
|
||||
public Seq<String> categoryNames;
|
||||
public String currentName;
|
||||
public String currentName = "";
|
||||
public String ruleSearch = "";
|
||||
public Seq<Runnable> additionalSetup; // for modding to easily add new rules
|
||||
|
||||
public CustomRulesDialog(){
|
||||
this(false);
|
||||
}
|
||||
|
||||
public CustomRulesDialog(boolean showRuleEditRule){
|
||||
super("@mode.custom");
|
||||
|
||||
this.showRuleEditRule = showRuleEditRule;
|
||||
|
||||
loadoutDialog = new LoadoutDialog();
|
||||
|
||||
setFillParent(true);
|
||||
@@ -49,8 +57,6 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
additionalSetup = new Seq<>();
|
||||
categories = new Seq<>();
|
||||
categoryNames = new Seq<>();
|
||||
currentName = "";
|
||||
ruleSearch = "";
|
||||
|
||||
buttons.button("@edit", Icon.pencil, () -> {
|
||||
BaseDialog dialog = new BaseDialog("@waves.edit");
|
||||
@@ -209,7 +215,6 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
main.left().defaults().fillX().left();
|
||||
main.row();
|
||||
|
||||
|
||||
category("waves");
|
||||
check("@rules.waves", b -> rules.waves = b, () -> rules.waves);
|
||||
check("@rules.wavesending", b -> rules.waveSending = b, () -> rules.waveSending, () -> rules.waves);
|
||||
@@ -352,6 +357,10 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
|
||||
|
||||
category("teams");
|
||||
//not sure where else to put this
|
||||
if(showRuleEditRule){
|
||||
check("@rules.allowedit", b -> rules.allowEditRules = b, () -> rules.allowEditRules);
|
||||
}
|
||||
team("@rules.playerteam", t -> rules.defaultTeam = t, () -> rules.defaultTeam);
|
||||
team("@rules.enemyteam", t -> rules.waveTeam = t, () -> rules.waveTeam);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import static mindustry.Vars.*;
|
||||
public class MapPlayDialog extends BaseDialog{
|
||||
public @Nullable Runnable playListener;
|
||||
|
||||
CustomRulesDialog dialog = new CustomRulesDialog();
|
||||
CustomRulesDialog dialog = new CustomRulesDialog(true);
|
||||
Rules rules;
|
||||
Gamemode selectedGamemode = Gamemode.survival;
|
||||
Map lastMap;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package mindustry.ui.dialogs;
|
||||
|
||||
import arc.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import mindustry.*;
|
||||
import mindustry.editor.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
@@ -10,12 +13,28 @@ public class PausedDialog extends BaseDialog{
|
||||
private MapProcessorsDialog processors = new MapProcessorsDialog();
|
||||
private SaveDialog save = new SaveDialog();
|
||||
private LoadDialog load = new LoadDialog();
|
||||
private boolean wasClient = false;
|
||||
private CustomRulesDialog rulesDialog = new CustomRulesDialog();
|
||||
|
||||
public PausedDialog(){
|
||||
super("@menu");
|
||||
shouldPause = true;
|
||||
|
||||
clearChildren();
|
||||
add(titleTable).growX().row();
|
||||
|
||||
stack(cont, new Table(t -> {
|
||||
t.bottom().left();
|
||||
t.button(Icon.book, () -> {
|
||||
Rules toEdit = Vars.state.rules.copy();
|
||||
rulesDialog.show(toEdit, () -> state.rules.copy());
|
||||
rulesDialog.hidden(() -> {
|
||||
//apply rule changes only once it is hidden
|
||||
Vars.state.rules = toEdit;
|
||||
Call.setRules(toEdit);
|
||||
});
|
||||
}).size(70f).tooltip("@customize").visible(() -> state.rules.allowEditRules && (net.server() || !net.active()));
|
||||
})).grow().row();
|
||||
|
||||
shown(this::rebuild);
|
||||
|
||||
addCloseListener();
|
||||
@@ -130,7 +149,7 @@ public class PausedDialog extends BaseDialog{
|
||||
}
|
||||
|
||||
public void runExitSave(){
|
||||
wasClient = net.client();
|
||||
boolean wasClient = net.client();
|
||||
if(net.client()) netClient.disconnectQuietly();
|
||||
|
||||
if(state.isEditor() && !wasClient){
|
||||
|
||||
@@ -297,6 +297,7 @@ public class SettingsMenuDialog extends BaseDialog{
|
||||
}
|
||||
|
||||
void addSettings(){
|
||||
sound.checkPref("alwaysmusic", false);
|
||||
sound.sliderPref("musicvol", 100, 0, 100, 1, i -> i + "%");
|
||||
sound.sliderPref("sfxvol", 100, 0, 100, 1, i -> i + "%");
|
||||
sound.sliderPref("ambientvol", 100, 0, 100, 1, i -> i + "%");
|
||||
|
||||
@@ -91,7 +91,7 @@ public class Build{
|
||||
}
|
||||
|
||||
//repair derelict tile
|
||||
if(tile.team() == Team.derelict && tile.block == result && tile.build != null && tile.block.allowDerelictRepair && state.rules.derelictRepair){
|
||||
if(tile.team() == Team.derelict && team != Team.derelict && tile.block == result && tile.build != null && tile.block.allowDerelictRepair && state.rules.derelictRepair){
|
||||
float healthf = tile.build.healthf();
|
||||
var config = tile.build.config();
|
||||
|
||||
@@ -231,11 +231,11 @@ public class Build{
|
||||
(type.size == 2 && world.getDarkness(wx, wy) >= 3) ||
|
||||
(state.rules.staticFog && state.rules.fog && !fogControl.isDiscovered(team, wx, wy)) ||
|
||||
(check.floor().isDeep() && !type.floating && !type.requiresWater && !type.placeableLiquid) || //deep water
|
||||
(type == check.block() && check.build != null && rotation == check.build.rotation && type.rotate && !((type == check.block && check.team() == Team.derelict))) || //same block, same rotation
|
||||
(type == check.block() && check.build != null && rotation == check.build.rotation && type.rotate && !((type == check.block && team != Team.derelict && check.team() == Team.derelict))) || //same block, same rotation
|
||||
!check.interactable(team) || //cannot interact
|
||||
!check.floor().placeableOn || //solid floor
|
||||
(!checkVisible && !check.block().alwaysReplace) || //replacing a block that should be replaced (e.g. payload placement)
|
||||
!(((type.canReplace(check.block()) || (type == check.block && state.rules.derelictRepair && check.team() == Team.derelict)) || //can replace type OR can replace derelict block of same type
|
||||
!(((type.canReplace(check.block()) || (type == check.block && team != Team.derelict && state.rules.derelictRepair && check.team() == Team.derelict)) || //can replace type OR can replace derelict block of same type
|
||||
(check.build instanceof ConstructBuild build && build.current == type && check.centerX() == tile.x && check.centerY() == tile.y)) && //same type in construction
|
||||
type.bounds(tile.x, tile.y, Tmp.r1).grow(0.01f).contains(check.block.bounds(check.centerX(), check.centerY(), Tmp.r2))) || //no replacement
|
||||
(type.requiresWater && check.floor().liquidDrop != Liquids.water) //requires water but none found
|
||||
|
||||
@@ -4,7 +4,6 @@ import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.consumers.*;
|
||||
|
||||
public class PowerGraph{
|
||||
private static final Queue<Building> queue = new Queue<>();
|
||||
@@ -109,7 +108,7 @@ public class PowerGraph{
|
||||
for(int i = 0; i < consumers.size; i++){
|
||||
var consumer = items[i];
|
||||
var consumePower = consumer.block.consPower;
|
||||
if(otherConsumersAreValid(consumer, consumePower)){
|
||||
if(consumer.shouldConsumePower){
|
||||
powerNeeded += consumePower.requestedPower(consumer) * consumer.delta();
|
||||
}
|
||||
}
|
||||
@@ -201,7 +200,7 @@ public class PowerGraph{
|
||||
}
|
||||
}else{
|
||||
//valid consumers get power as usual
|
||||
if(otherConsumersAreValid(consumer, cons)){
|
||||
if(consumer.shouldConsumePower){
|
||||
consumer.power.status = coverage;
|
||||
}else{ //invalid consumers get an estimate, if they were to activate
|
||||
consumer.power.status = Math.min(1, produced / (needed + cons.usage * consumer.delta()));
|
||||
@@ -381,24 +380,6 @@ public class PowerGraph{
|
||||
return graphID;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private boolean otherConsumersAreValid(Building build, Consume consumePower){
|
||||
if(!build.enabled) return false;
|
||||
|
||||
float f = build.efficiency;
|
||||
//hack so liquids output positive efficiency values
|
||||
build.efficiency = 1f;
|
||||
for(Consume cons : build.block.nonOptionalConsumers){
|
||||
//TODO fix this properly
|
||||
if(cons != consumePower && cons.efficiency(build) <= 0.0000001f){
|
||||
build.efficiency = f;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
build.efficiency = f;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "PowerGraph{" +
|
||||
|
||||
Reference in New Issue
Block a user