diff --git a/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearchType.java b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearchType.java index df38bf138..b9d8a4153 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearchType.java +++ b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearchType.java @@ -18,6 +18,7 @@ public class AndroidResearchType extends ForgeRegistr } private List> blocking; + private List> unlocks; /** * @return List of research blocked once this research is unlocked @@ -38,6 +39,25 @@ public class AndroidResearchType extends ForgeRegistr return blocking; } + /** + * @return List of research unlocked once this research is unlocked + */ + public List> getUnlocks() { + if (unlocks == null) { + var list = new ArrayList>(); + + for (var type : Registry.ANDROID_RESEARCH()) { + if (type.getPrerequisites().contains(this)) { + list.add(type); + } + } + + unlocks = List.copyOf(list); + } + + return unlocks; + } + /** * @return List of research once unlocked blocks this research */ diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java index 19e0d08e2..f33b24e2d 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java @@ -9,6 +9,7 @@ import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.world.entity.player.Inventory; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.android.AndroidResearch; +import ru.dbotthepony.mc.otm.android.AndroidResearchType; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; @@ -17,8 +18,7 @@ import ru.dbotthepony.mc.otm.menu.widget.GaugeWidget; import ru.dbotthepony.mc.otm.screen.panels.*; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class AndroidStationScreen extends MatteryScreen implements MatteryScreen.IMatteryScreenGaugeGetter, MatteryScreen.IMatteryScreenBatteryGetter { class AndroidResearchButton extends EditablePanel { @@ -32,7 +32,7 @@ public class AndroidStationScreen extends MatteryScreen impl public AndroidResearchButton(@Nullable EditablePanel parent, AndroidResearch node) { super(AndroidStationScreen.this, parent, 0, 0, BUTTON_SIZE, BUTTON_SIZE); this.node = node; - setDockMargin(2, 2, 0, 0); + setDockMargin(2, 2, 2, 2); } @Override @@ -92,7 +92,6 @@ public class AndroidStationScreen extends MatteryScreen impl public static final int FRAME_WIDTH = 210; public static final int GRID_WIDTH = 5; - public static final int GRID_HEIGHT = 5; public static final int FRAME_HEIGHT = 120; public AndroidStationScreen(AndroidStationMenu p_97741_, Inventory p_97742_, Component p_97743_) { @@ -109,6 +108,59 @@ public class AndroidStationScreen extends MatteryScreen impl return List.of(menu.battery_slot); } + private final EditablePanel[] rows = new EditablePanel[100]; + private final Set> seen = new HashSet<>(); + private float next_x = 0; + private float[] rows_width = new float[100]; + private final AndroidResearchButton[][] created_buttons = new AndroidResearchButton[100][1000]; + private final int[] created_buttons_idx = new int[100]; + + private void dive(AndroidCapabilityPlayer cap, AndroidResearchType research, int level) { + if (seen.contains(research)) + return; + + seen.add(research); + + if (rows[level] == null) { + rows[level] = new EditablePanel(this, canvas, 0, level * 22, 1000, 22) { + @Override + protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) { + return false; + } + + @Override + protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) { + return false; + } + + @Override + protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) { + return false; + } + }; + } + + var row = rows[level]; + var button = new AndroidResearchButton(row, cap.getResearch(research)); + button.setPos(next_x + rows_width[level], 2); + created_buttons[level][created_buttons_idx[level]] = button; + created_buttons_idx[level]++; + + rows_width[level] += 22; + + for (var _research : research.getUnlocks()) { + dive(cap, _research, level + 1); + } + + if (level > 0) { + for (var _research : research.getPrerequisites()) { + dive(cap, _research, level - 1); + } + } + } + + private DraggableCanvasPanel canvas; + @Nullable @Override protected FramePanel makeMainFrame() { @@ -116,7 +168,7 @@ public class AndroidStationScreen extends MatteryScreen impl autoAttachToFrame(frame); - var canvas = new DraggableCanvasPanel(this, frame, 0, 0, GRID_WIDTH * 22, 0) { + canvas = new DraggableCanvasPanel(this, frame, 0, 0, GRID_WIDTH * 22, 0) { @Override protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) { RenderHelper.setDrawColor(RGBAColor.BLACK); @@ -124,40 +176,50 @@ public class AndroidStationScreen extends MatteryScreen impl } }; - var grid = new GridPanel(this, canvas, 0, 0, 0, 0, GRID_WIDTH, GRID_HEIGHT) { - @Override - protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) { - // pass event to canvas - return false; - } - - @Override - protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) { - // pass event to canvas - return false; - } - - @Override - protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) { - // pass event to canvas - return false; - } - }; - minecraft.player.getCapability(MatteryCapability.ANDROID).ifPresent(_cap -> { if (_cap instanceof AndroidCapabilityPlayer cap) { - for (var feature : Registry.ANDROID_RESEARCH().getValues()) { - var node = cap.getResearch(feature); + for (var research : Registry.ANDROID_RESEARCH().getValues()) { + if (research.getPrerequisites().size() == 0) { + dive(cap, research, 0); + float max = 0; - if (node != null) { - new AndroidResearchButton(grid, node); + for (float v : rows_width) + max = Math.max(max, v); + + for (var button_list : created_buttons) { + int count = 0; + + for (int i = 0; i < button_list.length; i++) { + if (button_list[i] == null) { + count = i; + break; + } + } + + if (count > 0) { + float this_x = next_x + max / 2f - (count * 22f) / 2f; + + for (int i = 0; i < count; i++) { + button_list[i].setPos(this_x, 2); + this_x += 22; + } + } + } + + for (var v : created_buttons) + Arrays.fill(v, null); + + next_x += max; + Arrays.fill(rows_width, 0); + Arrays.fill(created_buttons_idx, 0); } } + + seen.clear(); } }); canvas.setDock(Dock.RIGHT); - grid.setDock(Dock.FILL); return frame; } diff --git a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json index c86054b17..9fb0b6331 100644 --- a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json +++ b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json @@ -73,7 +73,7 @@ "android_research.overdrive_that_matters.nanobots_armor_speed": "Nanobots armor build speed %s", "android_research.overdrive_that_matters.nanobots_armor_speed.description": "Reduces time required for nanobots to form protection layer", - "android_research.overdrive_that_matters.nanobots_armor_strength": "Nanobots armor build speed %s", + "android_research.overdrive_that_matters.nanobots_armor_strength": "Nanobots armor strength %s", "android_research.overdrive_that_matters.nanobots_armor_strength.description": "Increases impact absorption strength of nanobots", "stat.overdrive_that_matters.health_regenerated": "Damage Regenerated by Nanobots",