Added shownPlanets for content

This commit is contained in:
Anuken 2024-08-21 18:01:16 -04:00
parent e1fb13847b
commit 2dbd9e5ea9
6 changed files with 77 additions and 26 deletions

View File

@ -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;
}

View File

@ -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<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.
* Note: When reading, use {@link #getDatabaseTabs} instead.
* */
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;
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<UnlockableContent> 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 =

View File

@ -1097,6 +1097,18 @@ public class ContentParser{
}
Field field = metadata.field;
try{
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(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{
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);
@ -1119,7 +1131,7 @@ public class ContentParser{
}else{
field.set(object, readField);
}
}
}catch(IllegalAccessException ex){
throw new SerializationException("Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex);
}catch(SerializationException ex){

View File

@ -150,6 +150,8 @@ public class Planet extends UnlockableContent{
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. */
@ -340,6 +342,10 @@ public class Planet extends UnlockableContent{
if(techTree != null){
techTree.addDatabaseTab(this);
if(autoAssignPlanet){
techTree.addPlanet(this);
}
}
for(Sector sector : sectors){

View File

@ -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<UnlockableContent> 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;

View File

@ -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(){