Removing Nulls.unit

This commit is contained in:
Anuken
2024-07-10 15:54:46 -04:00
parent e3ba8b714b
commit 295573142f
12 changed files with 106 additions and 188 deletions

View File

@@ -851,89 +851,6 @@ public class EntityProcess extends BaseProcessor{
for(TypeSpec.Builder b : baseClasses){ for(TypeSpec.Builder b : baseClasses){
write(b, imports.toSeq()); write(b, imports.toSeq());
} }
//TODO nulls were an awful idea
//store nulls
TypeSpec.Builder nullsBuilder = TypeSpec.classBuilder("Nulls").addModifiers(Modifier.PUBLIC).addModifiers(Modifier.FINAL);
//TODO should be dynamic
ObjectSet<String> nullList = ObjectSet.with("unit");
//create mock types of all components
for(Stype interf : allInterfaces){
//indirect interfaces to implement methods for
Seq<Stype> dependencies = interf.allInterfaces().add(interf);
Seq<Smethod> methods = dependencies.flatMap(Stype::methods);
methods.sortComparing(Object::toString);
//optionally add superclass
Stype superclass = dependencies.map(this::interfaceToComp).find(s -> s != null && s.annotation(Component.class).base());
//use the base type when the interface being emulated has a base
TypeName type = superclass != null && interfaceToComp(interf).annotation(Component.class).base() ? tname(baseName(superclass)) : interf.tname();
//used method signatures
ObjectSet<String> signatures = new ObjectSet<>();
//create null builder
String baseName = interf.name().substring(0, interf.name().length() - 1);
//prevent Nulls bloat
if(!nullList.contains(Strings.camelize(baseName))){
continue;
}
String className = "Null" + baseName;
TypeSpec.Builder nullBuilder = TypeSpec.classBuilder(className)
.addModifiers(Modifier.FINAL);
skipDeprecated(nullBuilder);
nullBuilder.addSuperinterface(interf.tname());
if(superclass != null) nullBuilder.superclass(tname(baseName(superclass)));
for(Smethod method : methods){
String signature = method.toString();
if(!signatures.add(signature)) continue;
Stype compType = interfaceToComp(method.type());
MethodSpec.Builder builder = MethodSpec.overriding(method.e).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
int index = 0;
for(ParameterSpec spec : builder.parameters){
Reflect.set(spec, "name", "arg" + index++);
}
builder.addAnnotation(OverrideCallSuper.class); //just in case
if(!method.isVoid()){
String methodName = method.name();
switch(methodName){
case "isNull":
builder.addStatement("return true");
break;
case "id":
builder.addStatement("return -1");
break;
case "toString":
builder.addStatement("return $S", className);
break;
default:
Svar variable = compType == null || method.params().size > 0 ? null : compType.fields().find(v -> v.name().equals(methodName));
String desc = variable == null ? null : variable.descString();
if(variable == null || !varInitializers.containsKey(desc)){
builder.addStatement("return " + getDefault(method.ret().toString()));
}else{
String init = varInitializers.get(desc);
builder.addStatement("return " + (init.equals("{}") ? "new " + variable.mirror().toString() : "") + init);
}
}
}
nullBuilder.addMethod(builder.build());
}
nullsBuilder.addField(FieldSpec.builder(type, Strings.camelize(baseName)).initializer("new " + className + "()").addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC).build());
write(nullBuilder, imports.toSeq());
}
write(nullsBuilder);
} }
} }

View File

@@ -622,21 +622,22 @@ public class NetClient implements ApplicationListener{
void sync(){ void sync(){
if(timer.get(0, playerSyncTime)){ if(timer.get(0, playerSyncTime)){
Unit unit = player.dead() ? Nulls.unit : player.unit(); boolean dead = player.dead();
int uid = player.dead() ? -1 : unit.id; Unit unit = dead ? null : player.unit();
int uid = dead || unit == null ? -1 : unit.id;
Call.clientSnapshot( Call.clientSnapshot(
lastSent++, lastSent++,
uid, uid,
player.dead(), dead,
player.dead() ? player.x : unit.x, player.dead() ? player.y : unit.y, dead ? player.x : unit.x, dead ? player.y : unit.y,
player.unit().aimX(), player.unit().aimY(), dead ? 0f : unit.aimX(), dead ? 0f : unit.aimY(),
unit.rotation, unit == null ? 0f : unit.rotation,
unit instanceof Mechc m ? m.baseRotation() : 0, unit instanceof Mechc m ? m.baseRotation() : 0,
unit.vel.x, unit.vel.y, unit == null ? 0f : unit.vel.x, unit == null ? 0f : unit.vel.y,
player.unit().mineTile, dead ? null : unit.mineTile,
player.boosting, player.shooting, ui.chatfrag.shown(), control.input.isBuilding, player.boosting, player.shooting, ui.chatfrag.shown(), control.input.isBuilding,
player.isBuilder() ? player.unit().plans : null, player.isBuilder() && unit != null ? unit.plans : null,
Core.camera.position.x, Core.camera.position.y, Core.camera.position.x, Core.camera.position.y,
Core.camera.width, Core.camera.height Core.camera.width, Core.camera.height
); );

View File

@@ -660,12 +660,11 @@ public class NetServer implements ApplicationListener{
player.shooting = shooting; player.shooting = shooting;
player.boosting = boosting; player.boosting = boosting;
player.unit().controlWeapons(shooting, shooting); @Nullable var unit = player.unit();
player.unit().aim(pointerX, pointerY);
if(player.isBuilder()){ if(player.isBuilder()){
player.unit().clearBuilding(); unit.clearBuilding();
player.unit().updateBuilding(building); unit.updateBuilding(building);
if(plans != null){ if(plans != null){
for(BuildPlan req : plans){ for(BuildPlan req : plans){
@@ -694,12 +693,12 @@ public class NetServer implements ApplicationListener{
} }
} }
player.unit().mineTile = mining;
con.rejectedRequests.clear(); con.rejectedRequests.clear();
if(!player.dead()){ if(!player.dead()){
Unit unit = player.unit(); unit.controlWeapons(shooting, shooting);
unit.aim(pointerX, pointerY);
unit.mineTile = mining;
long elapsed = Math.min(Time.timeSinceMillis(con.lastReceivedClientTime), 1500); long elapsed = Math.min(Time.timeSinceMillis(con.lastReceivedClientTime), 1500);
float maxSpeed = unit.speed(); float maxSpeed = unit.speed();

View File

@@ -35,10 +35,6 @@ abstract class EntityComp{
return ((Object)this) instanceof Unitc u && u.isPlayer() && !isLocal(); return ((Object)this) instanceof Unitc u && u.isPlayer() && !isLocal();
} }
boolean isNull(){
return false;
}
/** Replaced with `this` after code generation. */ /** Replaced with `this` after code generation. */
<T extends Entityc> T self(){ <T extends Entityc> T self(){
return (T)this; return (T)this;

View File

@@ -33,7 +33,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
@Import float x, y; @Import float x, y;
@ReadOnly Unit unit = Nulls.unit; @ReadOnly @Nullable Unit unit;
transient @Nullable NetConnection con; transient @Nullable NetConnection con;
@ReadOnly Team team = Team.sharded; @ReadOnly Team team = Team.sharded;
@SyncLocal boolean typing, shooting, boosting; @SyncLocal boolean typing, shooting, boosting;
@@ -49,12 +49,12 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
transient float textFadeTime; transient float textFadeTime;
transient Ratekeeper itemDepositRate = new Ratekeeper(); transient Ratekeeper itemDepositRate = new Ratekeeper();
transient private Unit lastReadUnit = Nulls.unit; transient private @Nullable Unit lastReadUnit;
transient private int wrongReadUnits; transient private int wrongReadUnits;
transient @Nullable Unit justSwitchFrom, justSwitchTo; transient @Nullable Unit justSwitchFrom, justSwitchTo;
public boolean isBuilder(){ public boolean isBuilder(){
return unit.canBuild(); return unit != null && unit.canBuild();
} }
public @Nullable CoreBuild closestCore(){ public @Nullable CoreBuild closestCore(){
@@ -89,7 +89,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
x = y = 0f; x = y = 0f;
if(!dead()){ if(!dead()){
unit.resetController(); unit.resetController();
unit = Nulls.unit; unit = null;
} }
} }
@@ -105,7 +105,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
@Replace @Replace
public float clipSize(){ public float clipSize(){
return unit.isNull() ? 20 : unit.type.hitSize * 2f; return unit == null ? 20 : unit.type.hitSize * 2f;
} }
@Override @Override
@@ -131,17 +131,18 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
unit = lastReadUnit; unit = lastReadUnit;
unit(set); unit(set);
lastReadUnit = unit; lastReadUnit = unit;
if(unit != null){
unit.aim(mouseX, mouseY); unit.aim(mouseX, mouseY);
//this is only necessary when the thing being controlled isn't synced //this is only necessary when the thing being controlled isn't synced
unit.controlWeapons(shooting, shooting); unit.controlWeapons(shooting, shooting);
//extra precaution, necessary for non-synced things //extra precaution, necessary for non-synced things
unit.controller(this); unit.controller(this);
} }
}
@Override @Override
public void update(){ public void update(){
if(!unit.isValid()){ if(unit != null && !unit.isValid()){
clearUnit(); clearUnit();
} }
@@ -181,42 +182,43 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
@Override @Override
public void remove(){ public void remove(){
//clear unit upon removal //clear unit upon removal
if(!unit.isNull()){ if(unit != null){
clearUnit(); clearUnit();
} }
lastReadUnit = Nulls.unit; lastReadUnit = null;
justSwitchTo = justSwitchFrom = null; justSwitchTo = justSwitchFrom = null;
} }
public void team(Team team){ public void team(Team team){
this.team = team; this.team = team;
if(unit != null){
unit.team(team); unit.team(team);
} }
}
public void clearUnit(){ public void clearUnit(){
unit(Nulls.unit); unit(null);
} }
public Unit unit(){ public @Nullable Unit unit(){
return unit; return unit;
} }
public void unit(Unit unit){ public void unit(@Nullable Unit unit){
//refuse to switch when the unit was just transitioned from //refuse to switch when the unit was just transitioned from
if(isLocal() && unit == justSwitchFrom && justSwitchFrom != null && justSwitchTo != null){ if(isLocal() && unit == justSwitchFrom && justSwitchFrom != null && justSwitchTo != null){
return; return;
} }
if(unit == null) throw new IllegalArgumentException("Unit cannot be null. Use clearUnit() instead.");
if(this.unit == unit) return; if(this.unit == unit) return;
//save last command this unit had //save last command this unit had
if(unit.controller() instanceof CommandAI ai){ if(unit != null && unit.controller() instanceof CommandAI ai){
lastCommand = ai.command; lastCommand = ai.command;
} }
if(this.unit != Nulls.unit){ if(this.unit != null){
//un-control the old unit //un-control the old unit
this.unit.resetController(); this.unit.resetController();
//restore last command issued before it was controlled //restore last command issued before it was controlled
@@ -225,7 +227,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
} }
} }
this.unit = unit; this.unit = unit;
if(unit != Nulls.unit){ if(unit != null){
unit.team(team); unit.team(team);
unit.controller(this); unit.controller(this);
@@ -244,7 +246,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
} }
boolean dead(){ boolean dead(){
return unit.isNull() || !unit.isValid(); return unit == null || !unit.isValid();
} }
String ip(){ String ip(){

View File

@@ -116,7 +116,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
private WidgetGroup group = new WidgetGroup(); private WidgetGroup group = new WidgetGroup();
private final Eachable<BuildPlan> allPlans = cons -> { private final Eachable<BuildPlan> allPlans = cons -> {
if(!player.dead()){
player.unit().plans().each(cons); player.unit().plans().each(cons);
}
selectPlans.each(cons); selectPlans.each(cons);
linePlans.each(cons); linePlans.each(cons);
}; };
@@ -236,9 +238,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public static void commandUnits(Player player, int[] unitIds, @Nullable Building buildTarget, @Nullable Unit unitTarget, @Nullable Vec2 posTarget, boolean queueCommand, boolean finalBatch){ public static void commandUnits(Player player, int[] unitIds, @Nullable Building buildTarget, @Nullable Unit unitTarget, @Nullable Vec2 posTarget, boolean queueCommand, boolean finalBatch){
if(player == null || unitIds == null) return; if(player == null || unitIds == null) return;
//why did I ever think this was a good idea
if(unitTarget != null && unitTarget.isNull()) unitTarget = null;
if(net.server() && !netServer.admins.allowAction(player, ActionType.commandUnits, event -> { if(net.server() && !netServer.admins.allowAction(player, ActionType.commandUnits, event -> {
event.unitIDs = unitIds; event.unitIDs = unitIds;
})){ })){
@@ -489,8 +488,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
@Remote(targets = Loc.server, called = Loc.server) @Remote(targets = Loc.server, called = Loc.server)
public static void pickedUnitPayload(Unit unit, Unit target){ public static void pickedUnitPayload(Unit unit, Unit target){
if(target == Nulls.unit) return;
if(target != null && unit instanceof Payloadc pay){ if(target != null && unit instanceof Payloadc pay){
pay.pickup(target); pay.pickup(target);
}else if(target != null){ }else if(target != null){
@@ -697,7 +694,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
player.unit(unit); player.unit(unit);
if(before != null && !before.isNull()){ if(before != null){
if(before.spawnedByCore){ if(before.spawnedByCore){
unit.dockedType = before.type; unit.dockedType = before.type;
}else if(before.dockedType != null && before.dockedType.coreUnitDock){ }else if(before.dockedType != null && before.dockedType.coreUnitDock){
@@ -812,7 +809,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
} }
playerPlanTree.clear(); playerPlanTree.clear();
if(!player.dead()){
player.unit().plans.each(playerPlanTree::insert); player.unit().plans.each(playerPlanTree::insert);
}
player.typing = ui.chatfrag.shown(); player.typing = ui.chatfrag.shown();
@@ -824,7 +823,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
player.unit().updateBuilding(isBuilding); player.unit().updateBuilding(isBuilding);
} }
if(player.shooting && !wasShooting && player.unit().hasWeapons() && state.rules.unitAmmo && !player.team().rules().infiniteAmmo && player.unit().ammo <= 0){ if(!player.dead() && player.shooting && !wasShooting && player.unit().hasWeapons() && state.rules.unitAmmo && !player.team().rules().infiniteAmmo && player.unit().ammo <= 0){
player.unit().type.weapons.first().noAmmoSound.at(player.unit()); player.unit().type.weapons.first().noAmmoSound.at(player.unit());
} }

View File

@@ -90,7 +90,7 @@ public class MobileInput extends InputHandler implements GestureListener{
void checkTargets(float x, float y){ void checkTargets(float x, float y){
Unit unit = Units.closestEnemy(player.team(), x, y, 20f, u -> !u.dead); Unit unit = Units.closestEnemy(player.team(), x, y, 20f, u -> !u.dead);
if(unit != null && player.unit().type.canAttack){ if(unit != null && !player.dead() && player.unit().type.canAttack){
player.unit().mineTile = null; player.unit().mineTile = null;
target = unit; target = unit;
}else{ }else{
@@ -126,6 +126,7 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
} }
if(!player.dead()){
for(var plan : player.unit().plans()){ for(var plan : player.unit().plans()){
Tile other = world.tile(plan.x, plan.y); Tile other = world.tile(plan.x, plan.y);
@@ -138,6 +139,8 @@ public class MobileInput extends InputHandler implements GestureListener{
return true; return true;
} }
} }
}
return false; return false;
} }
@@ -263,7 +266,7 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
boolean showCancel(){ boolean showCancel(){
return (player.unit().isBuilding() || block != null || mode == breaking || !selectPlans.isEmpty()) && !hasSchem(); return !player.dead() && (player.unit().isBuilding() || block != null || mode == breaking || !selectPlans.isEmpty()) && !hasSchem();
} }
boolean hasSchem(){ boolean hasSchem(){
@@ -277,7 +280,9 @@ public class MobileInput extends InputHandler implements GestureListener{
t.visible(this::showCancel); t.visible(this::showCancel);
t.bottom().left(); t.bottom().left();
t.button("@cancel", Icon.cancel, () -> { t.button("@cancel", Icon.cancel, () -> {
if(!player.dead()){
player.unit().clearBuilding(); player.unit().clearBuilding();
}
selectPlans.clear(); selectPlans.clear();
mode = none; mode = none;
block = null; block = null;
@@ -864,7 +869,7 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
} }
if(player.shooting && (player.unit().activelyBuilding() || player.unit().mining())){ if(player.shooting && !player.dead() && (player.unit().activelyBuilding() || player.unit().mining())){
player.shooting = false; player.shooting = false;
} }
} }
@@ -1037,7 +1042,7 @@ public class MobileInput extends InputHandler implements GestureListener{
unit.movePref(movement); unit.movePref(movement);
//update shooting if not building + not mining //update shooting if not building + not mining
if(!player.unit().activelyBuilding() && player.unit().mineTile == null){ if(!unit.activelyBuilding() && unit.mineTile == null){
//autofire targeting //autofire targeting
if(manualShooting){ if(manualShooting){
@@ -1046,7 +1051,7 @@ public class MobileInput extends InputHandler implements GestureListener{
}else if(target == null){ }else if(target == null){
player.shooting = false; player.shooting = false;
if(Core.settings.getBool("autotarget") && !(player.unit() instanceof BlockUnitUnit u && u.tile() instanceof ControlBlock c && !c.shouldAutoTarget())){ if(Core.settings.getBool("autotarget") && !(player.unit() instanceof BlockUnitUnit u && u.tile() instanceof ControlBlock c && !c.shouldAutoTarget())){
if(player.unit().type.canAttack){ if(unit.type.canAttack){
target = Units.closestTarget(unit.team, unit.x, unit.y, range, u -> u.checkTarget(type.targetAir, type.targetGround), u -> type.targetGround); target = Units.closestTarget(unit.team, unit.x, unit.y, range, u -> u.checkTarget(type.targetAir, type.targetGround), u -> type.targetGround);
} }

View File

@@ -279,7 +279,7 @@ public class TypeIO{
} }
public static void writeUnit(Writes write, Unit unit){ public static void writeUnit(Writes write, Unit unit){
write.b(unit == null || unit.isNull() ? 0 : unit instanceof BlockUnitc ? 1 : 2); write.b(unit == null ? 0 : unit instanceof BlockUnitc ? 1 : 2);
//block units are special //block units are special
if(unit instanceof BlockUnitc){ if(unit instanceof BlockUnitc){
@@ -295,15 +295,14 @@ public class TypeIO{
byte type = read.b(); byte type = read.b();
int id = read.i(); int id = read.i();
//nothing //nothing
if(type == 0) return Nulls.unit; if(type == 0) return null;
if(type == 2){ //standard unit if(type == 2){ //standard unit
Unit unit = Groups.unit.getByID(id); return Groups.unit.getByID(id);
return unit == null ? Nulls.unit : unit;
}else if(type == 1){ //block }else if(type == 1){ //block
Building tile = world.build(id); Building tile = world.build(id);
return tile instanceof ControlBlock cont ? cont.unit() : Nulls.unit; return tile instanceof ControlBlock cont ? cont.unit() : null;
} }
return Nulls.unit; return null;
} }
public static void writeCommand(Writes write, @Nullable UnitCommand command){ public static void writeCommand(Writes write, @Nullable UnitCommand command){

View File

@@ -1242,7 +1242,7 @@ public class LExecutor{
result.setobj(units == null || i < 0 || i >= units.size ? null : units.get(i)); result.setobj(units == null || i < 0 || i >= units.size ? null : units.get(i));
} }
} }
case player -> result.setobj(i < 0 || i >= data.players.size || data.players.get(i).unit().isNull() ? null : data.players.get(i).unit()); case player -> result.setobj(i < 0 || i >= data.players.size ? null : data.players.get(i).unit());
case core -> result.setobj(i < 0 || i >= data.cores.size ? null : data.cores.get(i)); case core -> result.setobj(i < 0 || i >= data.cores.size ? null : data.cores.get(i));
case build -> { case build -> {
Block block = extra.obj() instanceof Block b ? b : null; Block block = extra.obj() instanceof Block b ? b : null;

View File

@@ -152,7 +152,7 @@ public class BlockInventoryFragment{
container.add(i); container.add(i);
Boolp canPick = () -> player.unit().acceptsItem(item) && !state.isPaused() && player.within(build, itemTransferRange); Boolp canPick = () -> !player.dead() && player.unit().acceptsItem(item) && !state.isPaused() && player.within(build, itemTransferRange);
HandCursorListener l = new HandCursorListener(); HandCursorListener l = new HandCursorListener();
l.enabled = canPick; l.enabled = canPick;

View File

@@ -167,7 +167,7 @@ public class HintsFragment{
zoom(visibleDesktop, () -> Core.input.axis(KeyCode.scroll) != 0), zoom(visibleDesktop, () -> Core.input.axis(KeyCode.scroll) != 0),
breaking(() -> isTutorial.get() && state.rules.defaultTeam.data().getCount(Blocks.conveyor) > 5, () -> ui.hints.events.contains("break")), breaking(() -> isTutorial.get() && state.rules.defaultTeam.data().getCount(Blocks.conveyor) > 5, () -> ui.hints.events.contains("break")),
desktopShoot(visibleDesktop, () -> isSerpulo() && Vars.state.enemies > 0, () -> player.shooting), desktopShoot(visibleDesktop, () -> isSerpulo() && Vars.state.enemies > 0, () -> player.shooting),
depositItems(() -> player.unit().hasItem(), () -> !player.unit().hasItem()), depositItems(() -> !player.dead() && player.unit().hasItem(), () -> !player.dead() && !player.unit().hasItem()),
desktopPause(visibleDesktop, () -> isTutorial.get() && !Vars.net.active() && state.wave >= 2, () -> Core.input.keyTap(Binding.pause)), desktopPause(visibleDesktop, () -> isTutorial.get() && !Vars.net.active() && state.wave >= 2, () -> Core.input.keyTap(Binding.pause)),
unitControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 2 && !net.active() && !player.dead(), () -> !player.dead() && !player.unit().spawnedByCore), unitControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 2 && !net.active() && !player.dead(), () -> !player.dead() && !player.unit().spawnedByCore),
unitSelectControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 3 && !net.active() && !player.dead(), unitSelectControl(() -> isSerpulo() && state.rules.defaultTeam.data().units.size > 3 && !net.active() && !player.dead(),
@@ -179,8 +179,8 @@ public class HintsFragment{
boost(visibleDesktop, () -> !player.dead() && player.unit().type.canBoost, () -> Core.input.keyDown(Binding.boost)), boost(visibleDesktop, () -> !player.dead() && player.unit().type.canBoost, () -> Core.input.keyDown(Binding.boost)),
blockInfo(() -> !(state.isCampaign() && state.rules.sector == SectorPresets.groundZero.sector && state.wave < 3), () -> ui.content.isShown()), blockInfo(() -> !(state.isCampaign() && state.rules.sector == SectorPresets.groundZero.sector && state.wave < 3), () -> ui.content.isShown()),
derelict(() -> ui.hints.events.contains("derelictmouse") && !isTutorial.get(), () -> ui.hints.events.contains("derelictbreak")), derelict(() -> ui.hints.events.contains("derelictmouse") && !isTutorial.get(), () -> ui.hints.events.contains("derelictbreak")),
payloadPickup(() -> isSerpulo() && !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), () -> player.unit() instanceof Payloadc p && p.payloads().any()), payloadPickup(() -> isSerpulo() && !player.dead() && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), () -> player.unit() instanceof Payloadc p && p.payloads().any()),
payloadDrop(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().any(), () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty()), payloadDrop(() -> !player.dead() && player.unit() instanceof Payloadc p && p.payloads().any(), () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty()),
waveFire(() -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0), waveFire(() -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0),
generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)), generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)),
rebuildSelect(() -> state.rules.defaultTeam.data().plans.size >= 10, () -> control.input.isRebuildSelecting()), rebuildSelect(() -> state.rules.defaultTeam.data().plans.size >= 10, () -> control.input.isRebuildSelecting()),

View File

@@ -767,7 +767,7 @@ public class HudFragment{
} }
}); });
t.add(new SideBar(() -> player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad); t.add(new SideBar(() -> player.dead() ? 0f : player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad);
t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f); t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f);
t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> { t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> {
b.color.set(player.displayAmmo() ? player.dead() || player.unit() instanceof BlockUnitc ? Pal.ammo : player.unit().type.ammoType.color() : Pal.health); b.color.set(player.displayAmmo() ? player.dead() || player.unit() instanceof BlockUnitc ? Pal.ammo : player.unit().type.ammoType.color() : Pal.health);
@@ -913,7 +913,7 @@ public class HudFragment{
table.table().update(t -> { table.table().update(t -> {
t.left(); t.left();
Bits applied = player.unit().statusBits(); Bits applied = player.unit() == null ? null : player.unit().statusBits();
if(!statuses.equals(applied)){ if(!statuses.equals(applied)){
t.clear(); t.clear();