Core Database Content Classification Subdivison (#11506)
* test * test * test * Core database content subdivision * Core database content subdivision * undo some old change * Revert "test" This reverts commitada9dca787. * Revert "test" This reverts commitd7c81185* undo some old change * cleanup * Update core/assets/bundles/bundle.properties * Format and Cleanup * Format and Cleanup * gradle toggle * Update core/assets/bundles/bundle.properties * Update core/assets/bundles/bundle.properties * Update core/assets/bundles/bundle.properties --------- Co-authored-by: Anuken <arnukren@gmail.com>
This commit is contained in:
@@ -1538,13 +1538,27 @@ rules.randomwaveai.info = Makes units spawned in waves target random structures
|
|||||||
rules.placerangecheck.info = Prevents players from placing anything near enemy buildings. When trying to place a turret, the range is increased, so the turret will not be able to reach the enemy.
|
rules.placerangecheck.info = Prevents players from placing anything near enemy buildings. When trying to place a turret, the range is increased, so the turret will not be able to reach the enemy.
|
||||||
rules.onlydepositcore.info = Prevents units from depositing items into any buildings except cores.
|
rules.onlydepositcore.info = Prevents units from depositing items into any buildings except cores.
|
||||||
|
|
||||||
content.item.name = Items
|
database-category.item = Items
|
||||||
content.liquid.name = Fluids
|
database-category.liquid = Fluids
|
||||||
content.unit.name = Units
|
database-category.unit = Units
|
||||||
content.block.name = Blocks
|
database-category.block = Blocks
|
||||||
content.status.name = Status Effects
|
database-category.status = Status Effects
|
||||||
content.sector.name = Sectors
|
database-category.sector = Sectors
|
||||||
content.team.name = Factions
|
database-category.team = Factions
|
||||||
|
|
||||||
|
database-tag.turret = Turret
|
||||||
|
database-tag.production = Production
|
||||||
|
database-tag.distribution = Distribution
|
||||||
|
database-tag.liquid = Liquid
|
||||||
|
database-tag.power = Power
|
||||||
|
database-tag.defense = Defense
|
||||||
|
database-tag.crafting = Crafting
|
||||||
|
database-tag.units = Units
|
||||||
|
database-tag.effect = Effect
|
||||||
|
database-tag.logic = Logic
|
||||||
|
database-tag.unit-air = Air
|
||||||
|
database-tag.unit-naval = Naval
|
||||||
|
database-tag.unit-ground = Ground
|
||||||
|
|
||||||
wallore = (Wall)
|
wallore = (Wall)
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,19 @@ public abstract class UnlockableContent extends MappableContent{
|
|||||||
* If shownPlanets is also empty, it will use Serpulo as the "default" tab.
|
* If shownPlanets is also empty, it will use Serpulo as the "default" tab.
|
||||||
* */
|
* */
|
||||||
public ObjectSet<UnlockableContent> databaseTabs = new ObjectSet<>();
|
public ObjectSet<UnlockableContent> databaseTabs = new ObjectSet<>();
|
||||||
|
/**
|
||||||
|
* Content category. Defines the primary category of content classification in core database.
|
||||||
|
* For example, "block", "liquid", "unit".
|
||||||
|
* Uses getContentType().name() as a fallback when the value is null or empty.
|
||||||
|
* */
|
||||||
|
public @Nullable String databaseCategory;
|
||||||
|
/**
|
||||||
|
* Category tags. Secondary category of content classification in core database.
|
||||||
|
* For example, "turret", "wall" under databaseCategory "block", "core-unit", "ground-unit" under databaseCategory "units".
|
||||||
|
* Uses "default" as a fallback when the value is null or empty. When using "default", no extra tag label are displayed.
|
||||||
|
* */
|
||||||
|
public @Nullable String databaseTag;
|
||||||
|
|
||||||
/** The tech tree node for this content, if applicable. Null if not part of a tech tree. */
|
/** The tech tree node for this content, if applicable. Null if not part of a tech tree. */
|
||||||
@NoPatch
|
@NoPatch
|
||||||
public @Nullable TechNode techNode;
|
public @Nullable TechNode techNode;
|
||||||
@@ -84,6 +97,9 @@ public abstract class UnlockableContent extends MappableContent{
|
|||||||
public void postInit(){
|
public void postInit(){
|
||||||
super.postInit();
|
super.postInit();
|
||||||
|
|
||||||
|
if(databaseCategory == null || databaseCategory.isEmpty()) databaseCategory = getContentType().name();
|
||||||
|
if(databaseTag == null || databaseTag.isEmpty()) databaseTag = "default";
|
||||||
|
|
||||||
databaseTabs.addAll(shownPlanets);
|
databaseTabs.addAll(shownPlanets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -529,6 +529,21 @@ public class UnitType extends UnlockableContent implements Senseable{
|
|||||||
selectionSize = 30f;
|
selectionSize = 30f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(){
|
||||||
|
if(databaseTag == null || databaseTag.isEmpty()){
|
||||||
|
if(flying){
|
||||||
|
databaseTag = "unit-air";
|
||||||
|
}else if(naval){
|
||||||
|
databaseTag = "unit-naval";
|
||||||
|
}else{
|
||||||
|
databaseTag = "unit-ground";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.postInit();
|
||||||
|
}
|
||||||
|
|
||||||
public UnitController createController(Unit unit){
|
public UnitController createController(Unit unit){
|
||||||
return controller.get(unit);
|
return controller.get(unit);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ import static arc.Core.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class DatabaseDialog extends BaseDialog{
|
public class DatabaseDialog extends BaseDialog{
|
||||||
|
private final OrderedMap<String, OrderedMap<String, Seq<UnlockableContent>>> sortedContents = new OrderedMap<>();
|
||||||
|
private final OrderedMap<String, Seq<UnlockableContent>> tmpCategory = new OrderedMap<>();
|
||||||
|
|
||||||
private TextField search;
|
private TextField search;
|
||||||
private Table all = new Table();
|
private Table all = new Table();
|
||||||
|
|
||||||
@@ -36,6 +39,7 @@ public class DatabaseDialog extends BaseDialog{
|
|||||||
addCloseButton();
|
addCloseButton();
|
||||||
shown(() -> {
|
shown(() -> {
|
||||||
checkTabList();
|
checkTabList();
|
||||||
|
sortContents();
|
||||||
if(state.isCampaign() && allTabs.contains(state.getPlanet())){
|
if(state.isCampaign() && allTabs.contains(state.getPlanet())){
|
||||||
tab = state.getPlanet();
|
tab = state.getPlanet();
|
||||||
}else if(state.isGame() && state.rules.planet != null && allTabs.contains(state.rules.planet)){
|
}else if(state.isGame() && state.rules.planet != null && allTabs.contains(state.rules.planet)){
|
||||||
@@ -74,14 +78,28 @@ public class DatabaseDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sortContents(){
|
||||||
|
Seq<Content>[] allContent = Vars.content.getContentMap();
|
||||||
|
sortedContents.clear();
|
||||||
|
for(var contents : allContent){
|
||||||
|
for(var content : contents){
|
||||||
|
if(content instanceof UnlockableContent u){
|
||||||
|
var categoryContents = sortedContents.get(u.databaseCategory, new OrderedMap<>());
|
||||||
|
var taggedContents = categoryContents.get(u.databaseTag, new Seq<>());
|
||||||
|
taggedContents.add(u);
|
||||||
|
categoryContents.put(u.databaseTag, taggedContents);
|
||||||
|
sortedContents.put(u.databaseCategory, categoryContents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void rebuild(){
|
void rebuild(){
|
||||||
checkTabList();
|
checkTabList();
|
||||||
|
|
||||||
all.clear();
|
all.clear();
|
||||||
var text = search.getText().toLowerCase();
|
var text = search.getText().toLowerCase();
|
||||||
|
|
||||||
Seq<Content>[] allContent = Vars.content.getContentMap();
|
|
||||||
|
|
||||||
all.table(t -> {
|
all.table(t -> {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(var content : allTabs){
|
for(var content : allTabs){
|
||||||
@@ -96,71 +114,115 @@ public class DatabaseDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
}).row();
|
}).row();
|
||||||
|
|
||||||
for(int j = 0; j < allContent.length; j++){
|
boolean hasResult = false;
|
||||||
ContentType type = ContentType.all[j];
|
|
||||||
|
|
||||||
Seq<UnlockableContent> array = allContent[j]
|
for(int i = 0; i < sortedContents.size; i++){
|
||||||
.select(c -> c instanceof UnlockableContent u && !u.isHidden() && !u.hideDatabase && (tab == Planets.sun || u.allDatabaseTabs || u.databaseTabs.contains(tab)) &&
|
String categoryName = sortedContents.orderedKeys().get(i);
|
||||||
(text.isEmpty() || u.localizedName.toLowerCase().contains(text))).as();
|
OrderedMap<String, Seq<UnlockableContent>> categoryContents = sortedContents.get(categoryName);
|
||||||
|
|
||||||
if(array.size == 0) continue;
|
tmpCategory.clear();
|
||||||
|
|
||||||
//sorting only makes sense when in-game; otherwise, banned blocks can't exist
|
boolean categoryHasResult = false;
|
||||||
if(state.isGame()){
|
|
||||||
array.sort(Structs.comps(Structs.comparingBool(UnlockableContent::isBanned), Structs.comparingInt(u -> u.id)));
|
for(int j = 0; j < categoryContents.size; j++){
|
||||||
|
String tagName = categoryContents.orderedKeys().get(j);
|
||||||
|
Seq<UnlockableContent> array = categoryContents.get(tagName).select(u ->
|
||||||
|
!u.isHidden() && !u.hideDatabase &&
|
||||||
|
(tab == Planets.sun || u.allDatabaseTabs || u.databaseTabs.contains(tab)) &&
|
||||||
|
(text.isEmpty() || u.localizedName.toLowerCase().contains(text))).as();
|
||||||
|
if(array.isEmpty()) continue;
|
||||||
|
|
||||||
|
hasResult = true;
|
||||||
|
categoryHasResult = true;
|
||||||
|
|
||||||
|
//sorting only makes sense when in-game; otherwise, banned blocks can't exist
|
||||||
|
if(state.isGame()){
|
||||||
|
array.sort(Structs.comps(Structs.comparingBool(UnlockableContent::isBanned), Structs.comparingInt(u -> u.id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpCategory.put(tagName, array);
|
||||||
}
|
}
|
||||||
|
|
||||||
all.add("@content." + type.name() + ".name").growX().left().color(Pal.accent);
|
if(tmpCategory.isEmpty() || !categoryHasResult) continue;
|
||||||
|
|
||||||
|
all.add("@database-category." + categoryName).growX().left().color(Pal.accent);
|
||||||
all.row();
|
all.row();
|
||||||
all.image().growX().pad(5).padLeft(0).padRight(0).height(3).color(Pal.accent);
|
all.image().pad(5).padLeft(0).padRight(0).height(3).color(Pal.accent).growX();
|
||||||
all.row();
|
all.row();
|
||||||
all.table(list -> {
|
|
||||||
list.left();
|
|
||||||
|
|
||||||
int cols = (int)Mathf.clamp((Core.graphics.getWidth() - Scl.scl(30)) / Scl.scl(32 + 12), 1, 22);
|
all.table(sub -> {
|
||||||
int count = 0;
|
for(int j = 0; j < tmpCategory.size; j++){
|
||||||
|
String tagName = categoryContents.orderedKeys().get(j);
|
||||||
|
Seq<UnlockableContent> array = tmpCategory.get(tagName);
|
||||||
|
if(array == null || array.isEmpty()) continue;
|
||||||
|
|
||||||
for(var unlock : array){
|
if(!"default".equals(tagName)){
|
||||||
Image image = unlocked(unlock) ? new Image(new TextureRegionDrawable(unlock.uiIcon), mobile ? Color.white : Color.lightGray).setScaling(Scaling.fit) : new Image(Icon.lock, Pal.gray);
|
sub.table(tag -> {
|
||||||
|
tag.add("@database-tag." + tagName).left().color(Pal.gray);
|
||||||
//banned cross
|
tag.image().growX().pad(5).height(3).color(Pal.gray);
|
||||||
if(state.isGame() && unlock.isBanned()){
|
}).pad(4, 8, 4, 8).growX();
|
||||||
list.stack(image, new Image(Icon.cancel){{
|
sub.row();
|
||||||
setColor(Color.scarlet);
|
|
||||||
touchable = Touchable.disabled;
|
|
||||||
}}).size(8 * 4).pad(3);
|
|
||||||
}else{
|
|
||||||
list.add(image).size(8 * 4).pad(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickListener listener = new ClickListener();
|
sub.table(list -> {
|
||||||
image.addListener(listener);
|
list.left();
|
||||||
if(!mobile && unlocked(unlock)){
|
|
||||||
image.addListener(new HandCursorListener());
|
|
||||||
image.update(() -> image.color.lerp(!listener.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(unlocked(unlock)){
|
int cols = (int)Mathf.clamp((Core.graphics.getWidth() - Scl.scl(30)) / Scl.scl(32 + 12), 1, 22);
|
||||||
image.clicked(() -> {
|
int count = 0;
|
||||||
if(Core.input.keyDown(KeyCode.shiftLeft) && Fonts.getUnicode(unlock.name) != 0){
|
|
||||||
Core.app.setClipboardText((char)Fonts.getUnicode(unlock.name) + "");
|
for(var unlock : array){
|
||||||
ui.showInfoFade("@copied");
|
Image image = unlocked(unlock) ? new Image(new TextureRegionDrawable(unlock.uiIcon), mobile ? Color.white : Color.lightGray).setScaling(Scaling.fit) : new Image(Icon.lock, Pal.gray);
|
||||||
|
|
||||||
|
//banned cross
|
||||||
|
if(state.isGame() && unlock.isBanned()){
|
||||||
|
list.stack(image, new Image(Icon.cancel){{
|
||||||
|
setColor(Color.scarlet);
|
||||||
|
touchable = Touchable.disabled;
|
||||||
|
}}).size(8 * 4).pad(3);
|
||||||
}else{
|
}else{
|
||||||
ui.content.show(unlock);
|
list.add(image).size(8 * 4).pad(3);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
image.addListener(new Tooltip(t -> t.background(Tex.button).add(unlock.localizedName + (settings.getBool("console") ? "\n[gray]" + unlock.name : ""))));
|
|
||||||
}
|
|
||||||
|
|
||||||
if((++count) % cols == 0){
|
ClickListener listener = new ClickListener();
|
||||||
list.row();
|
image.addListener(listener);
|
||||||
}
|
if(!mobile && unlocked(unlock)){
|
||||||
|
image.addListener(new HandCursorListener());
|
||||||
|
image.update(() -> image.color.lerp(!listener.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(unlocked(unlock)){
|
||||||
|
image.clicked(() -> {
|
||||||
|
if(Core.input.keyDown(KeyCode.shiftLeft) && Fonts.getUnicode(unlock.name) != 0){
|
||||||
|
Core.app.setClipboardText((char)Fonts.getUnicode(unlock.name) + "");
|
||||||
|
ui.showInfoFade("@copied");
|
||||||
|
}else{
|
||||||
|
ui.content.show(unlock);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
image.addListener(new Tooltip(t -> t.background(Tex.button).add(unlock.localizedName + (settings.getBool("console") ? "\n[gray]" + unlock.name : ""))));
|
||||||
|
}
|
||||||
|
|
||||||
|
if((++count) % cols == 0){
|
||||||
|
list.row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int k = 0; k < cols - count; k++){
|
||||||
|
Image image = new Image();
|
||||||
|
image.setColor(Color.clear);
|
||||||
|
list.add(image).size(8 * 4).pad(3);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sub.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}).growX().left().padBottom(10);
|
}).growX().left().padBottom(10);
|
||||||
|
|
||||||
all.row();
|
all.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(all.getChildren().isEmpty()){
|
if(!hasResult){
|
||||||
all.add("@none.found");
|
all.add("@none.found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1251,6 +1251,10 @@ public class Block extends UnlockableContent implements Senseable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(databaseTag == null || databaseTag.isEmpty()){
|
||||||
|
databaseTag = category.name();
|
||||||
|
}
|
||||||
|
|
||||||
super.postInit();
|
super.postInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user