petroleum/src/main/java/pm/j4/petroleum/mixin/TitleScreenMixin.java

142 lines
4.4 KiB
Java

package pm.j4.petroleum.mixin;
import java.util.Optional;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import pm.j4.petroleum.PetroleumMod;
import pm.j4.petroleum.modules.splash.SplashText;
import pm.j4.petroleum.util.config.ConfigHolder;
import pm.j4.petroleum.util.config.ConfigManager;
import pm.j4.petroleum.util.module.ModuleBase;
import pm.j4.petroleum.util.module.option.BooleanOption;
import pm.j4.petroleum.util.module.option.ConfigurationOption;
/**
* Mixin attached to the TitleScreen.
* Currently, it is only used to display a string of text with the mod's version.
* Any other modules will likely extend the options screen or pause screen,
* so the module is unlikely to be used elsewhere.
*/
@Mixin(TitleScreen.class)
public class TitleScreenMixin extends Screen {
/**
* The Opacity.
*/
private double opacity = 0;
/**
* The Ascending.
*/
private boolean ascending = false;
/**
* Stub method.
* Since the mixin injects itself into the *actual* TitleScreen used by the game,
* this should never run.
*
* @param title the title
*/
protected TitleScreenMixin(Text title) {
super(title);
}
/**
* Mixin injection into the render method.
* It captures locals so that the text can be rendered alongside the
* screen fade-in.
* It injects before the call to @link com.mojang.bridge.game.GameVersion#getName() using INVOKE_ASSIGN,
* because attempting to use a regular invoke statement on @link net.minecraft.client.gui.DrawHelper#drawStringWithShadow()
* repeatedly failed.
* <p>
*
* @param matrices the matrices
* @param mouseX the mouse x
* @param mouseY the mouse y
* @param delta the delta
* @param ci the ci
* @param f the f
* @param i the
* @param j the j
* @param g the g
* @param l the l
*/
@Inject(method = "render",
at = @At(
value = "INVOKE_ASSIGN",
target = "Lcom/mojang/bridge/game/GameVersion;getName()Ljava/lang/String;",
ordinal = 0),
locals = LocalCapture.CAPTURE_FAILSOFT)
private void render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci, float f, int i, int j, float g, int l) {
Optional<ConfigHolder> config = ConfigManager.getConfig();
Optional<ModuleBase> splashText = PetroleumMod.getMod("petroleum.splashtext");
if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext")
&& splashText.isPresent()) {
Optional<ConfigurationOption> isActive = splashText.get().getConfigOption("petroleum.splashtext.active");
if(isActive.isPresent() && ((BooleanOption)isActive.get()).getValue()) {
drawStringWithShadow(matrices, this.textRenderer, SplashText.get(), 2, this.height - 20, blink(13108374) | l);
}
}
}
/**
* fades an integer color based on the values declared at the top of the class.
*
* @param color the integer representation of the color to fade. this should generally remain constant.
* @return the color, adjusted for "opacity". It's RGB and not RGBA, so it just lowers all color values.
*/
@SuppressWarnings("SameParameterValue")
private int blink(int color) {
/*
The Speed.
*/
int speed = 3;
/*
The Opacity max.
*/
double opacity_max = 1000;
if (ascending) {
opacity += speed;
if (opacity > opacity_max) {
opacity = opacity_max;
ascending = false;
}
} else {
opacity -= speed;
/*
The Opacity min.
*/
double opacity_min = 500;
if (opacity < opacity_min) {
opacity = opacity_min;
ascending = true;
}
}
double opacityD = (opacity / opacity_max);
/*
The R mask.
*/
int r_mask = 16711680;
int r = ((color & r_mask) / Integer.parseInt("010000", 16));
/*
The G mask.
*/
int g_mask = 65280;
int g = ((color & g_mask) / Integer.parseInt("000100", 16));
/*
The B mask.
*/
int b_mask = 255;
int b = ((color & b_mask));
return ((int) (r * opacityD) * Integer.parseInt("010000", 16)) |
((int) (g * opacityD) * Integer.parseInt("000100", 16)) |
((int) (b * opacityD));
}
}