From 2dbd9e5ea951fd013622dd0fa6f7287bddcbc1ff Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 21 Aug 2024 18:01:16 -0400 Subject: [PATCH] Added shownPlanets for content --- core/src/mindustry/content/TechTree.java | 7 ++- .../mindustry/ctype/UnlockableContent.java | 30 ++++++++++- core/src/mindustry/mod/ContentParser.java | 50 ++++++++++++------- core/src/mindustry/type/Planet.java | 6 +++ .../mindustry/ui/dialogs/DatabaseDialog.java | 4 +- core/src/mindustry/world/Block.java | 6 ++- 6 files changed, 77 insertions(+), 26 deletions(-) diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index e169c82845..c4e05638b0 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -139,11 +139,16 @@ public class TechTree{ } } - /** Adds the specified tab to all the content in this tree. */ + /** 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; } diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index 55628afe0c..e727e933fe 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -9,6 +9,7 @@ import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; import mindustry.annotations.Annotations.*; +import mindustry.content.*; import mindustry.content.TechTree.*; import mindustry.game.EventType.*; import mindustry.graphics.*; @@ -45,14 +46,25 @@ public abstract class UnlockableContent extends MappableContent{ public String fullOverride = ""; /** If true, this content will appear in all database tabs. */ public boolean allDatabaseTabs = false; - /** Content - usually a planet - that dictates which database tab(s) this content will appear in. If nothing is defined, Serpulo is considered to be the "default" tab. */ + /** + * Planets that this content is made for. If empty, it is shown on all planets. + * Currently, this is only meaningful for blocks. + * */ + public ObjectSet 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. + * Note: When reading, use {@link #getDatabaseTabs} instead. + * */ public ObjectSet 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 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; + private boolean initializedDatabaseTabs; public UnlockableContent(String name){ super(name); @@ -63,6 +75,20 @@ public abstract class UnlockableContent extends MappableContent{ this.unlocked = Core.settings != null && Core.settings.getBool(this.name + "-unlocked", false); } + public ObjectSet getDatabaseTabs(){ + //the problem here is that the planet hasn't initialized yet in init(), which means it hasn't assigned the shownPlanets yet. + //initialization has to be deferred to a getter + if(!initializedDatabaseTabs){ + initializedDatabaseTabs = true; + + databaseTabs.addAll(shownPlanets); + if(databaseTabs.isEmpty()){ + databaseTabs.add(Planets.serpulo); + } + } + return databaseTabs; + } + @Override public void loadIcon(){ fullIcon = diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 19d033b01c..0cbcdbcea3 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -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)fieldObj); + }else if(fieldObj instanceof Seq seq){ + seq.addAll((Seq)fieldObj); + }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){ diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java index b8bd7e0646..72e901d51e 100644 --- a/core/src/mindustry/type/Planet.java +++ b/core/src/mindustry/type/Planet.java @@ -150,6 +150,8 @@ public class Planet extends UnlockableContent{ public Seq hiddenItems = new Seq<>(); /** The only items available on this planet, if defined. */ public Seq 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 unlockedOnLand = new Seq<>(); /** Loads the mesh. Clientside only. Defaults to a boring sphere mesh. */ @@ -340,6 +342,10 @@ public class Planet extends UnlockableContent{ if(techTree != null){ techTree.addDatabaseTab(this); + + if(autoAssignPlanet){ + techTree.addPlanet(this); + } } for(Sector sector : sectors){ diff --git a/core/src/mindustry/ui/dialogs/DatabaseDialog.java b/core/src/mindustry/ui/dialogs/DatabaseDialog.java index a8ca315826..1951bf61cf 100644 --- a/core/src/mindustry/ui/dialogs/DatabaseDialog.java +++ b/core/src/mindustry/ui/dialogs/DatabaseDialog.java @@ -66,7 +66,7 @@ public class DatabaseDialog extends BaseDialog{ for(var contents : allContent){ for(var content : contents){ if(content instanceof UnlockableContent u){ - all.addAll(u.databaseTabs); + all.addAll(u.getDatabaseTabs()); } } } @@ -101,7 +101,7 @@ public class DatabaseDialog extends BaseDialog{ ContentType type = ContentType.all[j]; Seq array = allContent[j] - .select(c -> c instanceof UnlockableContent u && !u.isHidden() && (tab == Planets.sun || u.allDatabaseTabs || (u.databaseTabs.isEmpty() && tab == Planets.serpulo) || u.databaseTabs.contains(tab)) && + .select(c -> c instanceof UnlockableContent u && !u.isHidden() && (tab == Planets.sun || u.allDatabaseTabs || u.getDatabaseTabs().contains(tab)) && (text.isEmpty() || u.localizedName.toLowerCase().contains(text))).as(); if(array.size == 0) continue; diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 11cd6fee57..7b2f60c399 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -900,7 +900,7 @@ public class Block extends UnlockableContent implements Senseable{ } public boolean isVisibleOn(Planet planet){ - return !Structs.contains(requirements, i -> planet.hiddenItems.contains(i.item)); + return !Structs.contains(requirements, i -> planet.hiddenItems.contains(i.item)) && (shownPlanets.isEmpty() || shownPlanets.contains(planet)); } public boolean isPlaceable(){ @@ -948,7 +948,9 @@ 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 + (state.rules.hiddenBuildItems.isEmpty() || !Structs.contains(requirements, i -> state.rules.hiddenBuildItems.contains(i.item))) && + (state.getPlanet() == null || shownPlanets.isEmpty() || shownPlanets.contains(state.getPlanet())); } public boolean isStatic(){