Merge branch 'master' of https://github.com/Anuken/Mindustry
This commit is contained in:
@@ -62,7 +62,9 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
||||
}
|
||||
long ram = Runtime.getRuntime().maxMemory();
|
||||
boolean gb = ram >= 1024 * 1024 * 1024;
|
||||
Log.info("[RAM] Available: @ @", Strings.fixed(gb ? ram / 1024f / 1024 / 1024f : ram / 1024f / 1024f, 1), gb ? "GB" : "MB");
|
||||
if(!OS.isIos){
|
||||
Log.info("[RAM] Available: @ @", Strings.fixed(gb ? ram / 1024f / 1024 / 1024f : ram / 1024f / 1024f, 1), gb ? "GB" : "MB");
|
||||
}
|
||||
|
||||
Time.setDeltaProvider(() -> {
|
||||
float result = Core.graphics.getDeltaTime() * 60f;
|
||||
|
||||
@@ -1513,27 +1513,23 @@ public class Blocks{
|
||||
requirements(Category.defense, with(Items.copper, 6));
|
||||
health = 80 * wallHealthMultiplier;
|
||||
researchCostMultiplier = 0.1f;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
copperWallLarge = new Wall("copper-wall-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(copperWall.requirements, 4));
|
||||
health = 80 * 4 * wallHealthMultiplier;
|
||||
size = 2;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
titaniumWall = new Wall("titanium-wall"){{
|
||||
requirements(Category.defense, with(Items.titanium, 6));
|
||||
health = 110 * wallHealthMultiplier;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
titaniumWallLarge = new Wall("titanium-wall-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(titaniumWall.requirements, 4));
|
||||
health = 110 * wallHealthMultiplier * 4;
|
||||
size = 2;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
plastaniumWall = new Wall("plastanium-wall"){{
|
||||
@@ -1542,7 +1538,6 @@ public class Blocks{
|
||||
insulated = true;
|
||||
absorbLasers = true;
|
||||
schematicPriority = 10;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
plastaniumWallLarge = new Wall("plastanium-wall-large"){{
|
||||
@@ -1552,20 +1547,17 @@ public class Blocks{
|
||||
insulated = true;
|
||||
absorbLasers = true;
|
||||
schematicPriority = 10;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
thoriumWall = new Wall("thorium-wall"){{
|
||||
requirements(Category.defense, with(Items.thorium, 6));
|
||||
health = 200 * wallHealthMultiplier;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
thoriumWallLarge = new Wall("thorium-wall-large"){{
|
||||
requirements(Category.defense, ItemStack.mult(thoriumWall.requirements, 4));
|
||||
health = 200 * wallHealthMultiplier * 4;
|
||||
size = 2;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
phaseWall = new Wall("phase-wall"){{
|
||||
@@ -1573,7 +1565,6 @@ public class Blocks{
|
||||
health = 150 * wallHealthMultiplier;
|
||||
chanceDeflect = 10f;
|
||||
flashHit = true;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
phaseWallLarge = new Wall("phase-wall-large"){{
|
||||
@@ -1582,14 +1573,12 @@ public class Blocks{
|
||||
size = 2;
|
||||
chanceDeflect = 10f;
|
||||
flashHit = true;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
surgeWall = new Wall("surge-wall"){{
|
||||
requirements(Category.defense, with(Items.surgeAlloy, 6));
|
||||
health = 230 * wallHealthMultiplier;
|
||||
lightningChance = 0.05f;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
surgeWallLarge = new Wall("surge-wall-large"){{
|
||||
@@ -1597,13 +1586,11 @@ public class Blocks{
|
||||
health = 230 * 4 * wallHealthMultiplier;
|
||||
size = 2;
|
||||
lightningChance = 0.05f;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
door = new Door("door"){{
|
||||
requirements(Category.defense, with(Items.titanium, 6, Items.silicon, 4));
|
||||
health = 100 * wallHealthMultiplier;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
doorLarge = new Door("door-large"){{
|
||||
@@ -1612,14 +1599,12 @@ public class Blocks{
|
||||
closefx = Fx.doorcloselarge;
|
||||
health = 100 * 4 * wallHealthMultiplier;
|
||||
size = 2;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
scrapWall = new Wall("scrap-wall"){{
|
||||
requirements(Category.defense, BuildVisibility.sandboxOnly, with(Items.scrap, 6));
|
||||
health = 60 * wallHealthMultiplier;
|
||||
variants = 5;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
scrapWallLarge = new Wall("scrap-wall-large"){{
|
||||
@@ -1627,7 +1612,6 @@ public class Blocks{
|
||||
health = 60 * 4 * wallHealthMultiplier;
|
||||
size = 2;
|
||||
variants = 4;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
scrapWallHuge = new Wall("scrap-wall-huge"){{
|
||||
@@ -1635,21 +1619,18 @@ public class Blocks{
|
||||
health = 60 * 9 * wallHealthMultiplier;
|
||||
size = 3;
|
||||
variants = 3;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
scrapWallGigantic = new Wall("scrap-wall-gigantic"){{
|
||||
requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.mult(scrapWall.requirements, 16));
|
||||
health = 60 * 16 * wallHealthMultiplier;
|
||||
size = 4;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
thruster = new Thruster("thruster"){{
|
||||
requirements(Category.defense, BuildVisibility.sandboxOnly, with(Items.scrap, 96));
|
||||
health = 55 * 16 * wallHealthMultiplier;
|
||||
size = 4;
|
||||
envDisabled |= Env.scorching;
|
||||
}};
|
||||
|
||||
berylliumWall = new Wall("beryllium-wall"){{
|
||||
|
||||
@@ -65,7 +65,6 @@ public class Planets{
|
||||
clearSectorOnLose = true;
|
||||
defaultCore = Blocks.coreBastion;
|
||||
iconColor = Color.valueOf("ff9266");
|
||||
hiddenItems.addAll(Items.serpuloItems).removeAll(Items.erekirItems);
|
||||
enemyBuildSpeedMultiplier = 0.4f;
|
||||
|
||||
//TODO disallowed for now
|
||||
@@ -152,7 +151,6 @@ public class Planets{
|
||||
startSector = 15;
|
||||
alwaysUnlocked = true;
|
||||
landCloudColor = Pal.spore.cpy().a(0.5f);
|
||||
hiddenItems.addAll(Items.erekirItems).removeAll(Items.serpuloItems);
|
||||
}};
|
||||
|
||||
verilus = makeAsteroid("verlius", sun, Blocks.stoneWall, Blocks.iceWall, 0.5f, 12, 2f, gen -> {
|
||||
|
||||
@@ -139,6 +139,16 @@ public class TechTree{
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds the specified database tab to all the content in this tree. */
|
||||
public void addDatabaseTab(UnlockableContent tab){
|
||||
each(node -> node.content.databaseTabs.add(tab));
|
||||
}
|
||||
|
||||
/** Adds the specified planet to the shownPlanets of all the content in this tree. */
|
||||
public void addPlanet(Planet planet){
|
||||
each(node -> node.content.shownPlanets.add(planet));
|
||||
}
|
||||
|
||||
public Drawable icon(){
|
||||
return icon == null ? new TextureRegionDrawable(content.uiIcon) : icon;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ public class ContentLoader{
|
||||
/** Calls Content#init() on everything. Use only after all modules have been created. */
|
||||
public void init(){
|
||||
initialize(Content::init);
|
||||
initialize(Content::postInit);
|
||||
if(logicVars != null) logicVars.init();
|
||||
Events.fire(new ContentInitEvent());
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class GameState{
|
||||
}
|
||||
|
||||
public @Nullable Planet getPlanet(){
|
||||
return rules.sector != null ? rules.sector.planet : null;
|
||||
return rules.sector != null ? rules.sector.planet : rules.planet;
|
||||
}
|
||||
|
||||
public boolean isEditor(){
|
||||
|
||||
@@ -140,10 +140,6 @@ public class Logic implements ApplicationListener{
|
||||
core.items.set(item, core.block.itemCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
//set up hidden items
|
||||
state.rules.hiddenBuildItems.clear();
|
||||
state.rules.hiddenBuildItems.addAll(state.rules.sector.planet.hiddenItems);
|
||||
}
|
||||
|
||||
//save settings
|
||||
|
||||
@@ -158,7 +158,7 @@ public class UI implements ApplicationListener, Loadable{
|
||||
Core.scene.draw();
|
||||
|
||||
if(Core.input.keyTap(KeyCode.mouseLeft) && Core.scene.hasField()){
|
||||
Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true);
|
||||
Element e = Core.scene.getHoverElement();
|
||||
if(!(e instanceof TextField)){
|
||||
Core.scene.setKeyboardFocus(null);
|
||||
}
|
||||
|
||||
@@ -321,8 +321,6 @@ public class World{
|
||||
state.rules.cloudColor = sector.planet.landCloudColor;
|
||||
state.rules.env = sector.planet.defaultEnv;
|
||||
state.rules.planet = sector.planet;
|
||||
state.rules.hiddenBuildItems.clear();
|
||||
state.rules.hiddenBuildItems.addAll(sector.planet.hiddenItems);
|
||||
sector.planet.applyRules(state.rules);
|
||||
sector.info.resources = content.toSeq();
|
||||
sector.info.resources.sort(Structs.comps(Structs.comparing(Content::getContentType), Structs.comparingInt(c -> c.id)));
|
||||
|
||||
@@ -25,6 +25,9 @@ public abstract class Content implements Comparable<Content>{
|
||||
/** Called after all content and modules are created. Do not use to load regions or texture data! */
|
||||
public void init(){}
|
||||
|
||||
/** Called after init(). */
|
||||
public void postInit(){}
|
||||
|
||||
/**
|
||||
* Called after all content is created, only on non-headless versions.
|
||||
* Use for loading regions or other image data.
|
||||
|
||||
@@ -35,8 +35,6 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
public boolean hideDetails = true;
|
||||
/** If false, all icon generation is disabled for this content; createIcons is not called. */
|
||||
public boolean generateIcons = true;
|
||||
/** Special logic icon ID. */
|
||||
public int iconId = 0;
|
||||
/** How big the content appears in certain selection menus */
|
||||
public float selectionSize = 24f;
|
||||
/** Icon of the content to use in UI. */
|
||||
@@ -45,11 +43,24 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
public TextureRegion fullIcon;
|
||||
/** Override for the full icon. Useful for mod content with duplicate icons. Overrides any other full icon.*/
|
||||
public String fullOverride = "";
|
||||
/** If true, this content will appear in all database tabs. */
|
||||
public boolean allDatabaseTabs = false;
|
||||
/**
|
||||
* Planets that this content is made for. If empty, a planet is decided based on item requirements.
|
||||
* Currently, this is only meaningful for blocks.
|
||||
* */
|
||||
public ObjectSet<Planet> shownPlanets = new ObjectSet<>();
|
||||
/**
|
||||
* Content - usually a planet - that dictates which database tab(s) this content will appear in.
|
||||
* If nothing is defined, it will use the values in shownPlanets.
|
||||
* If shownPlanets is also empty, it will use Serpulo as the "default" tab.
|
||||
* */
|
||||
public ObjectSet<UnlockableContent> databaseTabs = new ObjectSet<>();
|
||||
/** The tech tree node for this content, if applicable. Null if not part of a tech tree. */
|
||||
public @Nullable TechNode techNode;
|
||||
/** Tech nodes for all trees that this content is part of. */
|
||||
public Seq<TechNode> techNodes = new Seq<>();
|
||||
/** Unlock state. Loaded from settings. Do not modify outside of the constructor. */
|
||||
/** Unlock state. Loaded from settings. Do not modify outside the constructor. */
|
||||
protected boolean unlocked;
|
||||
|
||||
public UnlockableContent(String name){
|
||||
@@ -61,6 +72,13 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
this.unlocked = Core.settings != null && Core.settings.getBool(this.name + "-unlocked", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(){
|
||||
super.postInit();
|
||||
|
||||
databaseTabs.addAll(shownPlanets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadIcon(){
|
||||
fullIcon =
|
||||
@@ -74,6 +92,10 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
uiIcon = Core.atlas.find(getContentType().name() + "-" + name + "-ui", fullIcon);
|
||||
}
|
||||
|
||||
public boolean isOnPlanet(@Nullable Planet planet){
|
||||
return planet == null || shownPlanets.isEmpty() || shownPlanets.contains(planet);
|
||||
}
|
||||
|
||||
public int getLogicId(){
|
||||
return logicVars.lookupLogicId(this);
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ public class MapView extends Element implements GestureListener{
|
||||
return Core.scene != null && Core.scene.getKeyboardFocus() != null
|
||||
&& Core.scene.getKeyboardFocus().isDescendantOf(ui.editor)
|
||||
&& ui.editor.isShown() && tool == EditorTool.zoom &&
|
||||
Core.scene.hit(Core.input.mouse().x, Core.input.mouse().y, true) == this;
|
||||
Core.scene.getHoverElement() == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1370,6 +1370,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
/** Called when the block is destroyed. The tile is still intact at this stage. */
|
||||
public void onDestroyed(){
|
||||
if(sound != null){
|
||||
sound.stop();
|
||||
}
|
||||
|
||||
float explosiveness = block.baseExplosiveness;
|
||||
float flammability = 0f;
|
||||
float power = 0f;
|
||||
|
||||
@@ -153,8 +153,6 @@ public class Rules{
|
||||
public ObjectSet<Block> revealedBlocks = new ObjectSet<>();
|
||||
/** Unlocked content names. Only used in multiplayer when the campaign is enabled. */
|
||||
public ObjectSet<String> researched = new ObjectSet<>();
|
||||
/** Block containing these items as requirements are hidden. */
|
||||
public ObjectSet<Item> hiddenBuildItems = Items.erekirOnlyItems.asSet();
|
||||
/** In-map objective executor. */
|
||||
public MapObjectives objectives = new MapObjectives();
|
||||
/** Flags set by objectives. Used in world processors. */
|
||||
|
||||
@@ -8,6 +8,7 @@ import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.ai.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
@@ -359,6 +360,10 @@ public class Teams{
|
||||
//TODO this may cause a lot of packet spam, optimize?
|
||||
Call.setTeam(build, Team.derelict);
|
||||
|
||||
if(build.getPayload() instanceof UnitPayload){
|
||||
Call.destroyPayload(build);
|
||||
}
|
||||
|
||||
if(Mathf.chance(0.25)){
|
||||
Time.run(Mathf.random(0f, 60f * 6f), build::kill);
|
||||
}
|
||||
@@ -425,6 +430,14 @@ public class Teams{
|
||||
}
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server, unreliable = true)
|
||||
public static void destroyPayload(Building build){
|
||||
if(build != null && build.getPayload() instanceof UnitPayload && build.takePayload() instanceof UnitPayload unit){
|
||||
unit.dump();
|
||||
unit.unit.killed();
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents a block made by this team that was destroyed somewhere on the map.
|
||||
* This does not include deconstructed blocks.*/
|
||||
public static class BlockPlan{
|
||||
|
||||
@@ -132,7 +132,9 @@ public class GlobalVars{
|
||||
}
|
||||
|
||||
for(UnitType type : Vars.content.units()){
|
||||
put("@" + type.name, type);
|
||||
if(!type.internal){
|
||||
put("@" + type.name, type);
|
||||
}
|
||||
}
|
||||
|
||||
for(Weather weather : Vars.content.weathers()){
|
||||
|
||||
@@ -33,8 +33,9 @@ public class LAssembler{
|
||||
|
||||
Seq<LStatement> st = read(data, privileged);
|
||||
|
||||
asm.instructions = st.map(l -> l.build(asm)).retainAll(l -> l != null).toArray(LInstruction.class);
|
||||
asm.privileged = privileged;
|
||||
|
||||
asm.instructions = st.map(l -> l.build(asm)).retainAll(l -> l != null).toArray(LInstruction.class);
|
||||
return asm;
|
||||
}
|
||||
|
||||
@@ -58,7 +59,7 @@ public class LAssembler{
|
||||
/** @return a variable by name.
|
||||
* This may be a constant variable referring to a number or object. */
|
||||
public LVar var(String symbol){
|
||||
LVar constVar = Vars.logicVars.get(symbol);
|
||||
LVar constVar = Vars.logicVars.get(symbol, privileged);
|
||||
if(constVar != null) return constVar;
|
||||
|
||||
symbol = symbol.trim();
|
||||
|
||||
@@ -171,7 +171,7 @@ public class LCanvas extends Table{
|
||||
}
|
||||
|
||||
StatementElem checkHovered(){
|
||||
Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true);
|
||||
Element e = Core.scene.getHoverElement();
|
||||
if(e != null){
|
||||
while(e != null && !(e instanceof StatementElem)){
|
||||
e = e.parent;
|
||||
|
||||
@@ -555,7 +555,7 @@ public class LExecutor{
|
||||
int address = position.numi();
|
||||
Building from = target.building();
|
||||
|
||||
if(from instanceof MemoryBuild mem && (exec.privileged || from.team == exec.team)){
|
||||
if(from instanceof MemoryBuild mem && (exec.privileged || (from.team == exec.team && !mem.block.privileged))){
|
||||
output.setnum(address < 0 || address >= mem.memory.length ? 0 : mem.memory[address]);
|
||||
}
|
||||
}
|
||||
@@ -662,7 +662,7 @@ public class LExecutor{
|
||||
LogicAI ai = null;
|
||||
|
||||
if(base instanceof Ranged r && (exec.privileged || r.team() == exec.team) &&
|
||||
(base instanceof Building || (ai = UnitControlI.checkLogicAI(exec, base)) != null)){ //must be a building or a controllable unit
|
||||
((base instanceof Building b && (!b.block.privileged || exec.privileged)) || (ai = UnitControlI.checkLogicAI(exec, base)) != null)){ //must be a building or a controllable unit
|
||||
float range = r.range();
|
||||
|
||||
Healthc targeted;
|
||||
@@ -1050,7 +1050,7 @@ public class LExecutor{
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
|
||||
if(target.building() instanceof MessageBuild d && (d.team == exec.team || exec.privileged)){
|
||||
if(target.building() instanceof MessageBuild d && (exec.privileged || (d.team == exec.team && !d.block.privileged))){
|
||||
|
||||
d.message.setLength(0);
|
||||
d.message.append(exec.textBuffer, 0, Math.min(exec.textBuffer.length(), maxTextBuffer));
|
||||
@@ -1242,7 +1242,8 @@ public class LExecutor{
|
||||
result.setobj(units == null || i < 0 || i >= units.size ? null : units.get(i));
|
||||
}
|
||||
}
|
||||
case player -> result.setobj(i < 0 || i >= data.players.size ? null : data.players.get(i).unit());
|
||||
case player -> result.setobj(i < 0 || i >= data.players.size ? null :
|
||||
data.players.get(i).unit() instanceof BlockUnitc block ? block.tile() : data.players.get(i).unit());
|
||||
case core -> result.setobj(i < 0 || i >= data.cores.size ? null : data.cores.get(i));
|
||||
case build -> {
|
||||
Block block = extra.obj() instanceof Block b ? b : null;
|
||||
@@ -1295,7 +1296,7 @@ public class LExecutor{
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
Tile tile = world.tile(x.numi(), y.numi());
|
||||
Tile tile = world.tile(Mathf.round(x.numf()), Mathf.round(y.numf()));
|
||||
if(tile == null){
|
||||
dest.setobj(null);
|
||||
}else{
|
||||
@@ -1380,7 +1381,7 @@ public class LExecutor{
|
||||
|
||||
Team t = team.team();
|
||||
|
||||
if(type.obj() instanceof UnitType type && !type.hidden && t != null && Units.canCreate(t, type)){
|
||||
if(type.obj() instanceof UnitType type && !type.internal && !type.hidden && t != null && Units.canCreate(t, type)){
|
||||
//random offset to prevent stacking
|
||||
var unit = type.spawn(t, World.unconv(x.numf()) + Mathf.range(0.01f), World.unconv(y.numf()) + Mathf.range(0.01f));
|
||||
spawner.spawnEffect(unit, rotation.numf());
|
||||
|
||||
@@ -34,7 +34,7 @@ public class BaseGenerator{
|
||||
Seq<Block> wallsSmall = content.blocks().select(b -> b instanceof Wall && b.isVanilla() && b.size == size
|
||||
&& !b.insulated && b.buildVisibility == BuildVisibility.shown
|
||||
&& !(b instanceof Door)
|
||||
&& !(Structs.contains(b.requirements, i -> state.rules.hiddenBuildItems.contains(i.item))));
|
||||
&& b.isOnPlanet(state.getPlanet()));
|
||||
wallsSmall.sort(b -> b.buildCost);
|
||||
return wallsSmall.getFrac(difficulty * 0.91f);
|
||||
}
|
||||
|
||||
@@ -1097,29 +1097,41 @@ public class ContentParser{
|
||||
}
|
||||
Field field = metadata.field;
|
||||
try{
|
||||
boolean isMap = ObjectMap.class.isAssignableFrom(field.getType()) || ObjectIntMap.class.isAssignableFrom(field.getType()) || ObjectFloatMap.class.isAssignableFrom(field.getType());
|
||||
boolean mergeMap = isMap && child.has("add") && child.get("add").isBoolean() && child.getBoolean("add", false);
|
||||
if(child.isObject() && child.has("add") && (Seq.class.isAssignableFrom(field.getType()) || ObjectSet.class.isAssignableFrom(field.getType()))){
|
||||
Object readField = parser.readValue(field.getType(), metadata.elementType, child.get("add"), metadata.keyType);
|
||||
Object fieldObj = field.get(object);
|
||||
|
||||
if(mergeMap){
|
||||
child.remove("add");
|
||||
}
|
||||
|
||||
Object readField = parser.readValue(field.getType(), metadata.elementType, child, metadata.keyType);
|
||||
Object fieldObj = field.get(object);
|
||||
|
||||
//if a map has add: true, add its contents to the map instead
|
||||
if(mergeMap && (fieldObj instanceof ObjectMap<?,?> || fieldObj instanceof ObjectIntMap<?> || fieldObj instanceof ObjectFloatMap<?>)){
|
||||
if(field.get(object) instanceof ObjectMap<?,?> baseMap){
|
||||
baseMap.putAll((ObjectMap)readField);
|
||||
}else if(field.get(object) instanceof ObjectIntMap<?> baseMap){
|
||||
baseMap.putAll((ObjectIntMap)readField);
|
||||
}else if(field.get(object) instanceof ObjectFloatMap<?> baseMap){
|
||||
baseMap.putAll((ObjectFloatMap)readField);
|
||||
if(fieldObj instanceof ObjectSet set){
|
||||
set.addAll((ObjectSet)readField);
|
||||
}else if(fieldObj instanceof Seq seq){
|
||||
seq.addAll((Seq)readField);
|
||||
}else{
|
||||
throw new SerializationException("This should be impossible");
|
||||
}
|
||||
}else{
|
||||
field.set(object, readField);
|
||||
}
|
||||
boolean isMap = ObjectMap.class.isAssignableFrom(field.getType()) || ObjectIntMap.class.isAssignableFrom(field.getType()) || ObjectFloatMap.class.isAssignableFrom(field.getType());
|
||||
boolean mergeMap = isMap && child.has("add") && child.get("add").isBoolean() && child.getBoolean("add", false);
|
||||
|
||||
if(mergeMap){
|
||||
child.remove("add");
|
||||
}
|
||||
|
||||
Object readField = parser.readValue(field.getType(), metadata.elementType, child, metadata.keyType);
|
||||
Object fieldObj = field.get(object);
|
||||
|
||||
//if a map has add: true, add its contents to the map instead
|
||||
if(mergeMap && (fieldObj instanceof ObjectMap<?,?> || fieldObj instanceof ObjectIntMap<?> || fieldObj instanceof ObjectFloatMap<?>)){
|
||||
if(field.get(object) instanceof ObjectMap<?,?> baseMap){
|
||||
baseMap.putAll((ObjectMap)readField);
|
||||
}else if(field.get(object) instanceof ObjectIntMap<?> baseMap){
|
||||
baseMap.putAll((ObjectIntMap)readField);
|
||||
}else if(field.get(object) instanceof ObjectFloatMap<?> baseMap){
|
||||
baseMap.putAll((ObjectFloatMap)readField);
|
||||
}
|
||||
}else{
|
||||
field.set(object, readField);
|
||||
}
|
||||
}
|
||||
}catch(IllegalAccessException ex){
|
||||
throw new SerializationException("Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex);
|
||||
}catch(SerializationException ex){
|
||||
|
||||
@@ -81,12 +81,12 @@ public class GameService{
|
||||
}
|
||||
|
||||
private void registerEvents(){
|
||||
allTransportSerpulo = content.blocks().select(b -> b.category == Category.distribution && b.isVisibleOn(Planets.serpulo) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
allTransportErekir = content.blocks().select(b -> b.category == Category.distribution && b.isVisibleOn(Planets.erekir) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
allTransportSerpulo = content.blocks().select(b -> b.category == Category.distribution && b.isOnPlanet(Planets.serpulo) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
allTransportErekir = content.blocks().select(b -> b.category == Category.distribution && b.isOnPlanet(Planets.erekir) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
|
||||
//cores are ignored since they're upgrades and can be skipped
|
||||
allSerpuloBlocks = content.blocks().select(b -> b.synthetic() && b.isVisibleOn(Planets.serpulo) && b.isVanilla() && !(b instanceof CoreBlock) && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
allErekirBlocks = content.blocks().select(b -> b.synthetic() && b.isVisibleOn(Planets.erekir) && b.isVanilla() && !(b instanceof CoreBlock) && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
allSerpuloBlocks = content.blocks().select(b -> b.synthetic() && b.isOnPlanet(Planets.serpulo) && b.isVanilla() && !(b instanceof CoreBlock) && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
allErekirBlocks = content.blocks().select(b -> b.synthetic() && b.isOnPlanet(Planets.erekir) && b.isVanilla() && !(b instanceof CoreBlock) && b.buildVisibility == BuildVisibility.shown).toArray(Block.class);
|
||||
|
||||
unitsBuilt = Core.settings.getJson("units-built" , ObjectSet.class, String.class, ObjectSet::new);
|
||||
blocksBuilt = Core.settings.getJson("blocks-built" , ObjectSet.class, String.class, ObjectSet::new);
|
||||
@@ -526,7 +526,7 @@ public class GameService{
|
||||
}
|
||||
|
||||
for(Building entity : player.team().cores()){
|
||||
if(!content.items().contains(i -> !state.rules.hiddenBuildItems.contains(i) && entity.items.get(i) < entity.block.itemCapacity)){
|
||||
if(!content.items().contains(i -> i.isOnPlanet(state.getPlanet()) && entity.items.get(i) < entity.block.itemCapacity)){
|
||||
fillCoreAllCampaign.complete();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,9 @@ public class Item extends UnlockableContent implements Senseable{
|
||||
/** If true, this material is used by buildings. If false, this material will be incinerated in certain cores. */
|
||||
public boolean buildable = true;
|
||||
public boolean hidden = false;
|
||||
/** For mods. Adds this item to the listed planets' hidden items Seq. */
|
||||
|
||||
/** @deprecated no-op, do not use. */
|
||||
@Deprecated
|
||||
public @Nullable Planet[] hiddenOnPlanets;
|
||||
|
||||
public Item(String name, Color color){
|
||||
@@ -60,14 +62,9 @@ public class Item extends UnlockableContent implements Senseable{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
|
||||
if(hiddenOnPlanets != null){
|
||||
for(Planet planet : hiddenOnPlanets){
|
||||
planet.hiddenItems.add(this);
|
||||
}
|
||||
}
|
||||
public boolean isOnPlanet(Planet planet){
|
||||
//hidden items should not appear on any planet's resource selection screen
|
||||
return super.isOnPlanet(planet) && !hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,7 +15,6 @@ import mindustry.content.*;
|
||||
import mindustry.content.TechTree.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.game.EventType.ContentInitEvent;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.graphics.g3d.*;
|
||||
@@ -146,10 +145,8 @@ public class Planet extends UnlockableContent{
|
||||
public @Nullable TechNode techTree;
|
||||
/** TODO remove? Planets that can be launched to from this one. Made mutual in init(). */
|
||||
public Seq<Planet> launchCandidates = new Seq<>();
|
||||
/** Items not available on this planet. Left out for backwards compatibility. */
|
||||
public Seq<Item> hiddenItems = new Seq<>();
|
||||
/** The only items available on this planet, if defined. */
|
||||
public Seq<Item> itemWhitelist = new Seq<>();
|
||||
/** If true, all content in this planet's tech tree will be assigned this planet in their shownPlanets. */
|
||||
public boolean autoAssignPlanet = true;
|
||||
/** Content (usually planet-specific) that is unlocked upon landing here. */
|
||||
public Seq<UnlockableContent> unlockedOnLand = new Seq<>();
|
||||
/** Loads the mesh. Clientside only. Defaults to a boring sphere mesh. */
|
||||
@@ -157,6 +154,11 @@ public class Planet extends UnlockableContent{
|
||||
/** Loads the planet grid outline mesh. Clientside only. */
|
||||
public Prov<Mesh> gridMeshLoader = () -> MeshBuilder.buildPlanetGrid(grid, outlineColor, outlineRad * radius);
|
||||
|
||||
/** @deprecated no-op, do not use. */
|
||||
@Deprecated
|
||||
public Seq<Item> itemWhitelist = new Seq<>(), hiddenItems = new Seq<>();
|
||||
|
||||
|
||||
public Planet(String name, Planet parent, float radius){
|
||||
super(name);
|
||||
|
||||
@@ -179,13 +181,6 @@ public class Planet extends UnlockableContent{
|
||||
parent.updateTotalRadius();
|
||||
}
|
||||
|
||||
//if an item whitelist exists, add everything else not in that whitelist to hidden items
|
||||
Events.on(ContentInitEvent.class, e -> {
|
||||
if(itemWhitelist.size > 0){
|
||||
hiddenItems.addAll(content.items().select(i -> !itemWhitelist.contains(i)));
|
||||
}
|
||||
});
|
||||
|
||||
//calculate solar system
|
||||
for(solarSystem = this; solarSystem.parent != null; solarSystem = solarSystem.parent);
|
||||
}
|
||||
@@ -216,8 +211,6 @@ public class Planet extends UnlockableContent{
|
||||
rules.attributes.add(defaultAttributes);
|
||||
rules.env = defaultEnv;
|
||||
rules.planet = this;
|
||||
rules.hiddenBuildItems.clear();
|
||||
rules.hiddenBuildItems.addAll(hiddenItems);
|
||||
}
|
||||
|
||||
public @Nullable Sector getLastSector(){
|
||||
@@ -338,6 +331,11 @@ public class Planet extends UnlockableContent{
|
||||
techTree = TechTree.roots.find(n -> n.planet == this);
|
||||
}
|
||||
|
||||
if(techTree != null && autoAssignPlanet){
|
||||
techTree.addDatabaseTab(this);
|
||||
techTree.addPlanet(this);
|
||||
}
|
||||
|
||||
for(Sector sector : sectors){
|
||||
sector.loadInfo();
|
||||
}
|
||||
|
||||
@@ -68,10 +68,12 @@ public class StatusEffect extends UnlockableContent{
|
||||
|
||||
public StatusEffect(String name){
|
||||
super(name);
|
||||
allDatabaseTabs = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
if(initblock != null){
|
||||
initblock.run();
|
||||
}
|
||||
|
||||
@@ -675,6 +675,8 @@ public class UnitType extends UnlockableContent implements Senseable{
|
||||
@CallSuper
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
|
||||
if(constructor == null) throw new IllegalArgumentException("no constructor set up for unit '" + name + "'");
|
||||
|
||||
Unit example = constructor.get();
|
||||
|
||||
@@ -111,7 +111,7 @@ public class Minimap extends Table{
|
||||
|
||||
update(() -> {
|
||||
|
||||
Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true);
|
||||
Element e = Core.scene.getHoverElement();
|
||||
if(e != null && e.isDescendantOf(this)){
|
||||
requestScroll();
|
||||
}else if(hasScroll()){
|
||||
|
||||
@@ -229,19 +229,8 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
}
|
||||
number("@rules.dropzoneradius", false, f -> rules.dropZoneRadius = f * tilesize, () -> rules.dropZoneRadius / tilesize, () -> rules.waves);
|
||||
|
||||
|
||||
category("resourcesbuilding");
|
||||
check("@rules.infiniteresources", b -> {
|
||||
rules.infiniteResources = b;
|
||||
|
||||
//reset to serpulo if any env was enabled
|
||||
if(!b && rules.hiddenBuildItems.isEmpty()){
|
||||
rules.env = Planets.serpulo.defaultEnv;
|
||||
rules.hiddenBuildItems.clear();
|
||||
rules.hiddenBuildItems.addAll(Planets.serpulo.hiddenItems);
|
||||
setup();
|
||||
}
|
||||
}, () -> rules.infiniteResources);
|
||||
check("@rules.infiniteresources", b -> rules.infiniteResources = b, () -> rules.infiniteResources);
|
||||
check("@rules.onlydepositcore", b -> rules.onlyDepositCore = b, () -> rules.onlyDepositCore);
|
||||
check("@rules.derelictrepair", b -> rules.derelictRepair = b, () -> rules.derelictRepair);
|
||||
check("@rules.reactorexplosions", b -> rules.reactorExplosions = b, () -> rules.reactorExplosions);
|
||||
@@ -349,7 +338,6 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
|
||||
t.button("@rules.anyenv", style, () -> {
|
||||
rules.env = Vars.defaultEnv;
|
||||
rules.hiddenBuildItems.clear();
|
||||
rules.planet = Planets.sun;
|
||||
}).group(group).checked(b -> rules.planet == Planets.sun);
|
||||
}).left().fill(false).expand(false, false).row();
|
||||
|
||||
@@ -5,11 +5,13 @@ import arc.graphics.*;
|
||||
import arc.input.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.event.*;
|
||||
import arc.scene.style.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
@@ -24,16 +26,30 @@ public class DatabaseDialog extends BaseDialog{
|
||||
private TextField search;
|
||||
private Table all = new Table();
|
||||
|
||||
private @Nullable Seq<UnlockableContent> allTabs;
|
||||
//sun means "all content"
|
||||
private UnlockableContent tab = Planets.sun;
|
||||
|
||||
public DatabaseDialog(){
|
||||
super("@database");
|
||||
|
||||
shouldPause = true;
|
||||
addCloseButton();
|
||||
shown(this::rebuild);
|
||||
shown(() -> {
|
||||
checkTabList();
|
||||
if(state.isCampaign() && allTabs.contains(state.getPlanet())){
|
||||
tab = state.getPlanet();
|
||||
}else if(state.isGame() && state.rules.planet != null && allTabs.contains(state.rules.planet)){
|
||||
tab = state.rules.planet;
|
||||
}
|
||||
|
||||
rebuild();
|
||||
});
|
||||
onResize(this::rebuild);
|
||||
|
||||
all.margin(20).marginTop(0f);
|
||||
|
||||
cont.top();
|
||||
cont.table(s -> {
|
||||
s.image(Icon.zoom).padRight(8);
|
||||
search = s.field(null, text -> rebuild()).growX().get();
|
||||
@@ -43,18 +59,51 @@ public class DatabaseDialog extends BaseDialog{
|
||||
cont.pane(all).scrollX(false);
|
||||
}
|
||||
|
||||
void checkTabList(){
|
||||
if(allTabs == null){
|
||||
Seq<Content>[] allContent = Vars.content.getContentMap();
|
||||
ObjectSet<UnlockableContent> all = new ObjectSet<>();
|
||||
for(var contents : allContent){
|
||||
for(var content : contents){
|
||||
if(content instanceof UnlockableContent u){
|
||||
all.addAll(u.databaseTabs);
|
||||
}
|
||||
}
|
||||
}
|
||||
allTabs = all.toSeq().sort();
|
||||
allTabs.insert(0, Planets.sun);
|
||||
}
|
||||
}
|
||||
|
||||
void rebuild(){
|
||||
checkTabList();
|
||||
|
||||
all.clear();
|
||||
var text = search.getText().toLowerCase();
|
||||
|
||||
Seq<Content>[] allContent = Vars.content.getContentMap();
|
||||
|
||||
all.table(t -> {
|
||||
int i = 0;
|
||||
for(var content : allTabs){
|
||||
t.button(content == Planets.sun ? Icon.eyeSmall : content instanceof Planet ? Icon.planet : new TextureRegionDrawable(content.uiIcon), Styles.clearNoneTogglei, iconMed, () -> {
|
||||
tab = content;
|
||||
rebuild();
|
||||
}).size(50f).checked(b -> tab == content).tooltip(content == Planets.sun ? "@all" : content.localizedName).with(but -> {
|
||||
but.getStyle().imageUpColor = content instanceof Planet p ? p.iconColor : Color.white.cpy();
|
||||
});
|
||||
|
||||
if(++i % 10 == 0) t.row();
|
||||
}
|
||||
}).row();;
|
||||
|
||||
for(int j = 0; j < allContent.length; j++){
|
||||
ContentType type = ContentType.all[j];
|
||||
|
||||
Seq<UnlockableContent> array = allContent[j]
|
||||
.select(c -> c instanceof UnlockableContent u && !u.isHidden() &&
|
||||
.select(c -> c instanceof UnlockableContent u && !u.isHidden() && (tab == Planets.sun || u.allDatabaseTabs || u.databaseTabs.contains(tab)) &&
|
||||
(text.isEmpty() || u.localizedName.toLowerCase().contains(text))).as();
|
||||
|
||||
if(array.size == 0) continue;
|
||||
|
||||
all.add("@content." + type.name() + ".name").growX().left().color(Pal.accent);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
||||
ItemSeq launch = universe.getLaunchResources();
|
||||
if(sector.planet.allowLaunchLoadout){
|
||||
for(var item : content.items()){
|
||||
if(sector.planet.hiddenItems.contains(item)){
|
||||
if(!item.isOnPlanet(sector.planet)){
|
||||
launch.set(item, 0);
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
||||
if(destination.preset != null){
|
||||
var rules = destination.preset.generator.map.rules();
|
||||
for(var stack : rules.loadout){
|
||||
if(!sector.planet.hiddenItems.contains(stack.item)){
|
||||
if(stack.item.isOnPlanet(sector.planet)){
|
||||
resources.add(stack.item, stack.amount);
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
||||
ItemSeq realItems = sitems.copy();
|
||||
selected.requirements().each(realItems::remove);
|
||||
|
||||
loadout.show(lastCapacity, realItems, out, i -> i.unlocked() && !sector.planet.hiddenItems.contains(i), out::clear, () -> {}, () -> {
|
||||
loadout.show(lastCapacity, realItems, out, i -> i.unlocked() && i.isOnPlanet(sector.planet), out::clear, () -> {}, () -> {
|
||||
universe.updateLaunchResources(new ItemSeq(out));
|
||||
update.run();
|
||||
rebuildItems.run();
|
||||
@@ -172,7 +172,7 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
||||
Cons<Schematic> handler = s -> {
|
||||
if(s.tiles.contains(tile -> !tile.block.supportsEnv(sector.planet.defaultEnv) ||
|
||||
//make sure block can be built here.
|
||||
(!sector.planet.hiddenItems.isEmpty() && Structs.contains(tile.block.requirements, stack -> sector.planet.hiddenItems.contains(stack.item))))){
|
||||
!tile.block.isOnPlanet(sector.planet))){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -587,7 +587,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
|
||||
@Override
|
||||
public void act(float delta){
|
||||
if(scene.getDialog() == PlanetDialog.this && !scene.hit(input.mouseX(), input.mouseY(), true).isDescendantOf(e -> e instanceof ScrollPane)){
|
||||
if(scene.getDialog() == PlanetDialog.this && (scene.getHoverElement() == null || !scene.getHoverElement().isDescendantOf(e -> e instanceof ScrollPane))){
|
||||
scene.setScrollFocus(PlanetDialog.this);
|
||||
}
|
||||
|
||||
|
||||
@@ -472,7 +472,7 @@ public class ResearchDialog extends BaseDialog{
|
||||
|
||||
if(mobile){
|
||||
tapped(() -> {
|
||||
Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true);
|
||||
Element e = Core.scene.getHoverElement();
|
||||
if(e == this){
|
||||
hoverNode = null;
|
||||
rebuild();
|
||||
|
||||
@@ -67,7 +67,7 @@ public class BlockConfigFragment{
|
||||
}
|
||||
|
||||
public boolean hasConfigMouse(){
|
||||
Element e = Core.scene.hit(Core.input.mouseX(), Core.graphics.getHeight() - Core.input.mouseY(), true);
|
||||
Element e = Core.scene.getHoverElement();
|
||||
return e != null && (e == table || e.isDescendantOf(table));
|
||||
}
|
||||
|
||||
|
||||
@@ -615,7 +615,7 @@ public class PlacementFragment{
|
||||
blocksSelect.margin(4).marginTop(0);
|
||||
blockPane = blocksSelect.pane(blocks -> blockTable = blocks).height(194f).update(pane -> {
|
||||
if(pane.hasScroll()){
|
||||
Element result = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true);
|
||||
Element result = Core.scene.getHoverElement();
|
||||
if(result == null || !result.isDescendantOf(pane)){
|
||||
Core.scene.setScrollFocus(null);
|
||||
}
|
||||
|
||||
@@ -899,10 +899,6 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
return !isHidden() && (state.rules.editor || (!state.rules.hideBannedBlocks || !state.rules.isBanned(this)));
|
||||
}
|
||||
|
||||
public boolean isVisibleOn(Planet planet){
|
||||
return !Structs.contains(requirements, i -> planet.hiddenItems.contains(i.item));
|
||||
}
|
||||
|
||||
public boolean isPlaceable(){
|
||||
return isVisible() && (!state.rules.isBanned(this) || state.rules.editor) && supportsEnv(state.rules.env);
|
||||
}
|
||||
@@ -948,7 +944,7 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
}
|
||||
|
||||
public boolean environmentBuildable(){
|
||||
return (state.rules.hiddenBuildItems.isEmpty() || !Structs.contains(requirements, i -> state.rules.hiddenBuildItems.contains(i.item)));
|
||||
return isOnPlanet(state.getPlanet());
|
||||
}
|
||||
|
||||
public boolean isStatic(){
|
||||
@@ -1164,10 +1160,28 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
return buildVisibility != BuildVisibility.hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(){
|
||||
//usually, an empty set of planets is a configuration error. auto-assign based on requirements
|
||||
if(requirements.length > 0 && shownPlanets.isEmpty()){
|
||||
for(Planet planet : content.planets()){
|
||||
if(planet.isLandable()){
|
||||
if(!Structs.contains(requirements, s -> !s.item.isOnPlanet(planet))){
|
||||
shownPlanets.add(planet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.postInit();
|
||||
}
|
||||
|
||||
/** Called after all blocks are created. */
|
||||
@Override
|
||||
@CallSuper
|
||||
public void init(){
|
||||
super.init();
|
||||
|
||||
//disable standard shadow
|
||||
if(customShadow){
|
||||
hasShadow = false;
|
||||
|
||||
@@ -9,7 +9,6 @@ import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
@@ -65,7 +64,7 @@ public class ItemSelection{
|
||||
|
||||
Seq<T> list = items.select(u -> (text.isEmpty() || u.localizedName.toLowerCase().contains(text.toLowerCase())));
|
||||
for(T item : list){
|
||||
if(!item.unlockedNow() || (item instanceof Item checkVisible && state.rules.hiddenBuildItems.contains(checkVisible)) || item.isHidden()) continue;
|
||||
if(!item.unlockedNow() || !item.isOnPlanet(state.getPlanet()) || item.isHidden()) continue;
|
||||
|
||||
ImageButton button = cont.button(Tex.whiteui, Styles.clearNoneTogglei, Mathf.clamp(item.selectionSize, 0f, 40f), () -> {
|
||||
if(closeSelect) control.input.config.hideConfig();
|
||||
|
||||
@@ -6,6 +6,7 @@ import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
@@ -266,6 +267,14 @@ public class ForceProjector extends Block{
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void overwrote(Seq<Building> previous){
|
||||
if(previous.size > 0 && previous.first().block == block && previous.first() instanceof ForceBuild b){
|
||||
broken = b.broken;
|
||||
buildup = b.buildup;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Writes write){
|
||||
super.write(write);
|
||||
|
||||
@@ -53,6 +53,7 @@ public class BuildPayload implements Payload{
|
||||
|
||||
@Override
|
||||
public void destroyed(){
|
||||
build.dead = true;
|
||||
build.onDestroyed();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user