Tag hopping

- Ponder UIs opened from a tag screen now skip to the first scene with a matching tag if available
This commit is contained in:
simibubi 2021-03-09 17:32:01 +01:00
parent d252a204ef
commit 6b999fa7d4
7 changed files with 104 additions and 39 deletions

View file

@ -2,6 +2,7 @@ package com.simibubi.create.foundation.gui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableBoolean;
@ -145,7 +146,7 @@ public abstract class AbstractSimiScreen extends Screen {
return true; return true;
if (code == GLFW.GLFW_KEY_BACKSPACE) { if (code == GLFW.GLFW_KEY_BACKSPACE) {
ScreenOpener.openPreviousScreen(this); ScreenOpener.openPreviousScreen(this, Optional.empty());
return true; return true;
} }
@ -242,9 +243,7 @@ public abstract class AbstractSimiScreen extends Screen {
private static String screenTitle(Screen screen) { private static String screenTitle(Screen screen) {
if (screen instanceof AbstractSimiScreen) if (screen instanceof AbstractSimiScreen)
return ((AbstractSimiScreen) screen).getBreadcrumbTitle(); return ((AbstractSimiScreen) screen).getBreadcrumbTitle();
return "<";
return screen.getClass()
.getSimpleName();
} }
protected String getBreadcrumbTitle() { protected String getBreadcrumbTitle() {
@ -275,9 +274,11 @@ public abstract class AbstractSimiScreen extends Screen {
double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight(); double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight();
centerScalingOn((int) mouseX, (int) mouseY); centerScalingOn((int) mouseX, (int) mouseY);
} }
public boolean isEquivalentTo(AbstractSimiScreen other) { public boolean isEquivalentTo(AbstractSimiScreen other) {
return false; return false;
} }
public void shareContextWith(AbstractSimiScreen other) {}
} }

View file

@ -4,6 +4,7 @@ import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Deque; import java.util.Deque;
import java.util.List; import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -34,14 +35,17 @@ public class ScreenOpener {
openScreen(toOpen); openScreen(toOpen);
} }
public static void openPreviousScreen(Screen current) { public static void openPreviousScreen(Screen current, Optional<AbstractSimiScreen> screenWithContext) {
if (backStack.isEmpty()) if (backStack.isEmpty())
return; return;
backSteppedFrom = current; backSteppedFrom = current;
Screen previousScreen = backStack.pop(); Screen previousScreen = backStack.pop();
if (previousScreen instanceof AbstractSimiScreen) if (previousScreen instanceof AbstractSimiScreen) {
((AbstractSimiScreen) previousScreen).transition.startWithValue(-0.1) AbstractSimiScreen previousAbstractSimiScreen = (AbstractSimiScreen) previousScreen;
screenWithContext.ifPresent(s -> s.shareContextWith(previousAbstractSimiScreen));
previousAbstractSimiScreen.transition.startWithValue(-0.1)
.chase(-1, .4f, LerpedFloat.Chaser.EXP); .chase(-1, .4f, LerpedFloat.Chaser.EXP);
}
openScreen(previousScreen); openScreen(previousScreen);
} }
@ -65,7 +69,7 @@ public class ScreenOpener {
if (!screen.isEquivalentTo((AbstractSimiScreen) previouslyRenderedScreen)) if (!screen.isEquivalentTo((AbstractSimiScreen) previouslyRenderedScreen))
return false; return false;
openPreviousScreen(Minecraft.getInstance().currentScreen); openPreviousScreen(Minecraft.getInstance().currentScreen, Optional.of(screen));
return true; return true;
} }

View file

@ -39,15 +39,20 @@ public class PonderRegistry {
public static final PonderChapterRegistry chapters = new PonderChapterRegistry(); public static final PonderChapterRegistry chapters = new PonderChapterRegistry();
public static Map<ResourceLocation, List<PonderStoryBoardEntry>> all = new HashMap<>(); public static Map<ResourceLocation, List<PonderStoryBoardEntry>> all = new HashMap<>();
public static PonderSceneBuilder addStoryBoard(ItemProviderEntry<?> component, String schematic, PonderStoryBoard storyBoard) { public static PonderSceneBuilder addStoryBoard(ItemProviderEntry<?> component, String schematic,
PonderStoryBoard storyBoard, PonderTag... tags) {
ResourceLocation id = component.getId(); ResourceLocation id = component.getId();
PonderStoryBoardEntry entry = new PonderStoryBoardEntry(storyBoard, schematic, id); PonderStoryBoardEntry entry = new PonderStoryBoardEntry(storyBoard, schematic, id);
PonderSceneBuilder builder = new PonderSceneBuilder(entry); PonderSceneBuilder builder = new PonderSceneBuilder(entry);
all.computeIfAbsent(id, _$ -> new ArrayList<>()).add(entry); if (tags.length > 0)
builder.highlightTags(tags);
all.computeIfAbsent(id, _$ -> new ArrayList<>())
.add(entry);
return builder; return builder;
} }
public static PonderSceneBuilder addStoryBoard(PonderChapter chapter, ResourceLocation component, String schematic, PonderStoryBoard storyBoard) { public static PonderSceneBuilder addStoryBoard(PonderChapter chapter, ResourceLocation component, String schematic,
PonderStoryBoard storyBoard) {
if (component == null) if (component == null)
component = new ResourceLocation("minecraft", "stick"); component = new ResourceLocation("minecraft", "stick");
@ -94,7 +99,8 @@ public class PonderRegistry {
public static PonderScene compileScene(int i, PonderStoryBoardEntry sb, PonderWorld world) { public static PonderScene compileScene(int i, PonderStoryBoardEntry sb, PonderWorld world) {
PonderScene scene = new PonderScene(world, sb.getComponent(), sb.getTags()); PonderScene scene = new PonderScene(world, sb.getComponent(), sb.getTags());
SceneBuilder builder = scene.builder(); SceneBuilder builder = scene.builder();
sb.getBoard().program(builder, scene.getSceneBuildingUtil()); sb.getBoard()
.program(builder, scene.getSceneBuildingUtil());
return scene; return scene;
} }
@ -135,10 +141,16 @@ public class PonderRegistry {
} }
public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard) { public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard) {
return addStoryBoard(schematicPath, storyBoard, PonderSceneBuilder::highlightAllTags); return addStoryBoard(schematicPath, storyBoard, $ -> {
});
} }
public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard, Consumer<PonderSceneBuilder> extras) { public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard, PonderTag... tags) {
return addStoryBoard(schematicPath, storyBoard, sb -> sb.highlightTags(tags));
}
public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard,
Consumer<PonderSceneBuilder> extras) {
components.forEach(c -> extras.accept(PonderRegistry.addStoryBoard(c, schematicPath, storyBoard))); components.forEach(c -> extras.accept(PonderRegistry.addStoryBoard(c, schematicPath, storyBoard)));
return this; return this;
} }
@ -154,12 +166,14 @@ public class PonderRegistry {
} }
public PonderSceneBuilder highlightAllTags() { public PonderSceneBuilder highlightAllTags() {
entry.getTags().add(PonderTag.Highlight.ALL); entry.getTags()
.add(PonderTag.Highlight.ALL);
return this; return this;
} }
public PonderSceneBuilder highlightTags(PonderTag... tags) { public PonderSceneBuilder highlightTags(PonderTag... tags) {
entry.getTags().addAll(Arrays.asList(tags)); entry.getTags()
.addAll(Arrays.asList(tags));
return this; return this;
} }

View file

@ -77,6 +77,7 @@ public class PonderUI extends AbstractSimiScreen {
private LerpedFloat lazyIndex; private LerpedFloat lazyIndex;
private int index = 0; private int index = 0;
private PonderTag referredToByTag;
private PonderButton left, right, scan, chap; private PonderButton left, right, scan, chap;
@ -85,6 +86,13 @@ public class PonderUI extends AbstractSimiScreen {
.getRegistryName())); .getRegistryName()));
} }
public static PonderUI of(ItemStack item, PonderTag tag) {
PonderUI ponderUI = new PonderUI(PonderRegistry.compile(item.getItem()
.getRegistryName()));
ponderUI.referredToByTag = tag;
return ponderUI;
}
public static PonderUI of(PonderChapter chapter) { public static PonderUI of(PonderChapter chapter) {
PonderUI ui = new PonderUI(PonderRegistry.compile(chapter)); PonderUI ui = new PonderUI(PonderRegistry.compile(chapter));
ui.chapter = chapter; ui.chapter = chapter;
@ -186,6 +194,26 @@ public class PonderUI extends AbstractSimiScreen {
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
if (referredToByTag != null) {
for (int i = 0; i < scenes.size(); i++) {
PonderScene ponderScene = scenes.get(i);
if (!ponderScene.tags.contains(referredToByTag))
continue;
if (i == index)
break;
scenes.get(index)
.fadeOut();
index = i;
scenes.get(index)
.begin();
lazyIndex.chase(index, 1 / 4f, Chaser.EXP);
identifyMode = false;
break;
}
referredToByTag = null;
}
PonderScene activeScene = scenes.get(index); PonderScene activeScene = scenes.get(index);
if (!identifyMode) if (!identifyMode)
activeScene.tick(); activeScene.tick();
@ -743,4 +771,10 @@ public class PonderUI extends AbstractSimiScreen {
return super.isEquivalentTo(other); return super.isEquivalentTo(other);
} }
@Override
public void shareContextWith(AbstractSimiScreen other) {
if (other instanceof PonderUI)
((PonderUI) other).referredToByTag = referredToByTag;
}
} }

View file

@ -16,20 +16,22 @@ public class PonderIndex {
// (!) Modifications inside storyboard methods only require re-opening the ui // (!) Modifications inside storyboard methods only require re-opening the ui
PonderRegistry.forComponents(AllBlocks.SHAFT) PonderRegistry.forComponents(AllBlocks.SHAFT)
.addStoryBoard("shaft/relay", KineticsScenes::shaftAsRelay); .addStoryBoard("shaft/relay", KineticsScenes::shaftAsRelay, PonderTag.KINETIC_RELAYS);
PonderRegistry.forComponents(AllBlocks.SHAFT, AllBlocks.ANDESITE_ENCASED_SHAFT, AllBlocks.BRASS_ENCASED_SHAFT) PonderRegistry.forComponents(AllBlocks.SHAFT, AllBlocks.ANDESITE_ENCASED_SHAFT, AllBlocks.BRASS_ENCASED_SHAFT)
.addStoryBoard("shaft/encasing", KineticsScenes::shaftsCanBeEncased); .addStoryBoard("shaft/encasing", KineticsScenes::shaftsCanBeEncased);
PonderRegistry.forComponents(AllBlocks.COGWHEEL) PonderRegistry.forComponents(AllBlocks.COGWHEEL)
.addStoryBoard("cog/small", KineticsScenes::cogAsRelay) .addStoryBoard("cog/small", KineticsScenes::cogAsRelay, PonderTag.KINETIC_RELAYS)
.addStoryBoard("cog/speedup", KineticsScenes::cogsSpeedUp); .addStoryBoard("cog/speedup", KineticsScenes::cogsSpeedUp);
PonderRegistry.forComponents(AllBlocks.LARGE_COGWHEEL) PonderRegistry.forComponents(AllBlocks.LARGE_COGWHEEL)
.addStoryBoard("cog/speedup", KineticsScenes::cogsSpeedUp) .addStoryBoard("cog/speedup", KineticsScenes::cogsSpeedUp)
.addStoryBoard("cog/large", KineticsScenes::largeCogAsRelay); .addStoryBoard("cog/large", KineticsScenes::largeCogAsRelay, PonderTag.KINETIC_RELAYS);
PonderRegistry.forComponents(AllItems.BELT_CONNECTOR) PonderRegistry.forComponents(AllItems.BELT_CONNECTOR)
.addStoryBoard("belt/connect", BeltScenes::beltConnector) .addStoryBoard("belt/connect", BeltScenes::beltConnector, PonderTag.KINETIC_RELAYS)
.addStoryBoard("belt/directions", BeltScenes::directions) .addStoryBoard("belt/directions", BeltScenes::directions)
.addStoryBoard("belt/transport", BeltScenes::transport) .addStoryBoard("belt/transport", BeltScenes::transport, PonderTag.LOGISTICS)
.addStoryBoard("belt/encasing", BeltScenes::beltsCanBeEncased); .addStoryBoard("belt/encasing", BeltScenes::beltsCanBeEncased);
PonderRegistry.forComponents(AllBlocks.ANDESITE_CASING, AllBlocks.BRASS_CASING) PonderRegistry.forComponents(AllBlocks.ANDESITE_CASING, AllBlocks.BRASS_CASING)
@ -37,31 +39,38 @@ public class PonderIndex {
.addStoryBoard("belt/encasing", BeltScenes::beltsCanBeEncased); .addStoryBoard("belt/encasing", BeltScenes::beltsCanBeEncased);
PonderRegistry.forComponents(AllBlocks.GEARBOX, AllItems.VERTICAL_GEARBOX) PonderRegistry.forComponents(AllBlocks.GEARBOX, AllItems.VERTICAL_GEARBOX)
.addStoryBoard("gearbox", KineticsScenes::gearbox); .addStoryBoard("gearbox", KineticsScenes::gearbox, PonderTag.KINETIC_RELAYS);
PonderRegistry.addStoryBoard(AllBlocks.CLUTCH, "clutch", KineticsScenes::clutch);
PonderRegistry.addStoryBoard(AllBlocks.GEARSHIFT, "gearshift", KineticsScenes::gearshift); PonderRegistry.addStoryBoard(AllBlocks.CLUTCH, "clutch", KineticsScenes::clutch, PonderTag.KINETIC_RELAYS);
PonderRegistry.addStoryBoard(AllBlocks.GEARSHIFT, "gearshift", KineticsScenes::gearshift,
PonderTag.KINETIC_RELAYS);
PonderRegistry.forComponents(AllBlocks.ENCASED_FAN) PonderRegistry.forComponents(AllBlocks.ENCASED_FAN)
.addStoryBoard("fan/direction", FanScenes::direction) .addStoryBoard("fan/direction", FanScenes::direction, PonderTag.KINETIC_APPLIANCES)
.addStoryBoard("fan/processing", FanScenes::processing) .addStoryBoard("fan/processing", FanScenes::processing)
.addStoryBoard("fan/source", FanScenes::source); .addStoryBoard("fan/source", FanScenes::source, PonderTag.KINETIC_SOURCES);
PonderRegistry.addStoryBoard(AllBlocks.CREATIVE_MOTOR, "creative_motor", KineticsScenes::creativeMotor); PonderRegistry.addStoryBoard(AllBlocks.CREATIVE_MOTOR, "creative_motor", KineticsScenes::creativeMotor,
PonderRegistry.addStoryBoard(AllBlocks.WATER_WHEEL, "water_wheel", KineticsScenes::waterWheel); PonderTag.KINETIC_SOURCES);
PonderRegistry.addStoryBoard(AllBlocks.HAND_CRANK, "hand_crank", KineticsScenes::handCrank); PonderRegistry.addStoryBoard(AllBlocks.WATER_WHEEL, "water_wheel", KineticsScenes::waterWheel,
PonderRegistry.addStoryBoard(AllBlocks.COPPER_VALVE_HANDLE, "valve_handle", KineticsScenes::valveHandle); PonderTag.KINETIC_SOURCES);
PonderRegistry.addStoryBoard(AllBlocks.HAND_CRANK, "hand_crank", KineticsScenes::handCrank,
PonderTag.KINETIC_SOURCES);
PonderRegistry.addStoryBoard(AllBlocks.COPPER_VALVE_HANDLE, "valve_handle", KineticsScenes::valveHandle,
PonderTag.KINETIC_SOURCES);
PonderRegistry.forComponents(AllBlocks.DYED_VALVE_HANDLES) PonderRegistry.forComponents(AllBlocks.DYED_VALVE_HANDLES)
.addStoryBoard("valve_handle", KineticsScenes::valveHandle); .addStoryBoard("valve_handle", KineticsScenes::valveHandle);
PonderRegistry.addStoryBoard(AllBlocks.ENCASED_CHAIN_DRIVE, "chain_drive/relay", PonderRegistry.addStoryBoard(AllBlocks.ENCASED_CHAIN_DRIVE, "chain_drive/relay",
ChainDriveScenes::chainDriveAsRelay); ChainDriveScenes::chainDriveAsRelay, PonderTag.KINETIC_RELAYS);
PonderRegistry.forComponents(AllBlocks.ENCASED_CHAIN_DRIVE, AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT) PonderRegistry.forComponents(AllBlocks.ENCASED_CHAIN_DRIVE, AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT)
.addStoryBoard("chain_drive/gearshift", ChainDriveScenes::adjustableChainGearshift); .addStoryBoard("chain_drive/gearshift", ChainDriveScenes::adjustableChainGearshift);
// Funnels // Funnels
PonderRegistry.addStoryBoard(AllBlocks.BRASS_FUNNEL, "funnels/brass", FunnelScenes::brass); PonderRegistry.addStoryBoard(AllBlocks.BRASS_FUNNEL, "funnels/brass", FunnelScenes::brass);
PonderRegistry.forComponents(AllBlocks.ANDESITE_FUNNEL, AllBlocks.BRASS_FUNNEL) PonderRegistry.forComponents(AllBlocks.ANDESITE_FUNNEL, AllBlocks.BRASS_FUNNEL)
.addStoryBoard("funnels/intro", FunnelScenes::intro) .addStoryBoard("funnels/intro", FunnelScenes::intro, PonderTag.LOGISTICS)
.addStoryBoard("funnels/direction", FunnelScenes::directionality) .addStoryBoard("funnels/direction", FunnelScenes::directionality)
.addStoryBoard("funnels/compat", FunnelScenes::compat) .addStoryBoard("funnels/compat", FunnelScenes::compat)
.addStoryBoard("funnels/redstone", FunnelScenes::redstone) .addStoryBoard("funnels/redstone", FunnelScenes::redstone)
@ -69,8 +78,11 @@ public class PonderIndex {
PonderRegistry.addStoryBoard(AllBlocks.ANDESITE_FUNNEL, "funnels/brass", FunnelScenes::brass); PonderRegistry.addStoryBoard(AllBlocks.ANDESITE_FUNNEL, "funnels/brass", FunnelScenes::brass);
// Gantries // Gantries
PonderRegistry.addStoryBoard(AllBlocks.GANTRY_SHAFT, "gantry/intro", GantryScenes::introForShaft); PonderRegistry.addStoryBoard(AllBlocks.GANTRY_SHAFT, "gantry/intro", GantryScenes::introForShaft,
PonderRegistry.addStoryBoard(AllBlocks.GANTRY_CARRIAGE, "gantry/intro", GantryScenes::introForPinion); PonderTag.KINETIC_APPLIANCES, PonderTag.MOVEMENT_ANCHOR);
PonderRegistry.addStoryBoard(AllBlocks.GANTRY_CARRIAGE, "gantry/intro", GantryScenes::introForPinion,
PonderTag.KINETIC_APPLIANCES, PonderTag.MOVEMENT_ANCHOR);
PonderRegistry.forComponents(AllBlocks.GANTRY_SHAFT, AllBlocks.GANTRY_CARRIAGE) PonderRegistry.forComponents(AllBlocks.GANTRY_SHAFT, AllBlocks.GANTRY_CARRIAGE)
.addStoryBoard("gantry/redstone", GantryScenes::redstone) .addStoryBoard("gantry/redstone", GantryScenes::redstone)
.addStoryBoard("gantry/direction", GantryScenes::direction) .addStoryBoard("gantry/direction", GantryScenes::direction)
@ -78,7 +90,7 @@ public class PonderIndex {
// Movement Actors // Movement Actors
PonderRegistry.forComponents(AllBlocks.PORTABLE_STORAGE_INTERFACE) PonderRegistry.forComponents(AllBlocks.PORTABLE_STORAGE_INTERFACE)
.addStoryBoard("portable_interface/transfer", MovementActorScenes::psiTransfer) .addStoryBoard("portable_interface/transfer", MovementActorScenes::psiTransfer, PonderTag.CONTRAPTION_ACTOR)
.addStoryBoard("portable_interface/redstone", MovementActorScenes::psiRedstone); .addStoryBoard("portable_interface/redstone", MovementActorScenes::psiRedstone);
// Debug scenes, can be found in game via the Brass Hand // Debug scenes, can be found in game via the Brass Hand

View file

@ -82,7 +82,7 @@ public class PonderTagScreen extends AbstractSimiScreen {
if (!PonderRegistry.all.containsKey(i.getRegistryName())) if (!PonderRegistry.all.containsKey(i.getRegistryName()))
return; return;
centerScalingOn(mouseX, mouseY); centerScalingOn(mouseX, mouseY);
ScreenOpener.transitionTo(PonderUI.of(new ItemStack(i))); ScreenOpener.transitionTo(PonderUI.of(new ItemStack(i), tag));
}).showing(new ItemStack(i)); }).showing(new ItemStack(i));
button.fade(1); button.fade(1);
@ -99,7 +99,7 @@ public class PonderTagScreen extends AbstractSimiScreen {
.getRegistryName())) .getRegistryName()))
return; return;
centerScalingOn(mouseX, mouseY); centerScalingOn(mouseX, mouseY);
ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem())); ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem(), tag));
}).showing(tag.getMainItem()); }).showing(tag.getMainItem());
button.fade(1); button.fade(1);

View file

@ -95,7 +95,7 @@ public class PonderButton extends AbstractSimiWidget {
float flashValue = flash.getValue(partialTicks); float flashValue = flash.getValue(partialTicks);
if (flashValue > .1f) if (flashValue > .1f)
fade *= 3 * flashValue + ((Math.sin(AnimationTickHolder.getTicks() + partialTicks) / 6)) / 1f; fade *= 3 * flashValue + Math.sin((AnimationTickHolder.getTicks() + partialTicks) / 6);
int backgroundColor = ColorHelper.applyAlpha(0xdd000000, fade); int backgroundColor = ColorHelper.applyAlpha(0xdd000000, fade);
int borderColorStart = ColorHelper.applyAlpha(isHovered ? 0x70ffffff : 0x40aa9999, fade); int borderColorStart = ColorHelper.applyAlpha(isHovered ? 0x70ffffff : 0x40aa9999, fade);