generated from MrSphay/codex-agent-repository-kit
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.ModSounds;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.neoforged.neoforge.registries.RegistryObject;
|
||||
|
||||
public class AnimationSoundManager {
|
||||
private static final RandomSource RANDOM = RandomSource.m_216327_();
|
||||
private static final List<RegistryObject<SoundEvent>> ANIMATION_SOUNDS = new ArrayList<RegistryObject<SoundEvent>>();
|
||||
private static final List<RegistryObject<SoundEvent>> FAR_POWER_2_SOUNDS = new ArrayList<RegistryObject<SoundEvent>>();
|
||||
private static final List<RegistryObject<SoundEvent>> FAR_POWER_3_SOUNDS = new ArrayList<RegistryObject<SoundEvent>>();
|
||||
private static final List<RegistryObject<SoundEvent>> MEDIUM_CAVE_POWER_4_SOUNDS = new ArrayList<RegistryObject<SoundEvent>>();
|
||||
private static final List<RegistryObject<SoundEvent>> SUPERFAR_POWER_4_SOUNDS = new ArrayList<RegistryObject<SoundEvent>>();
|
||||
private static int lastAnimationSoundIndex = -1;
|
||||
private static int lastFarPower2SoundIndex = -1;
|
||||
private static int lastFarPower3SoundIndex = -1;
|
||||
private static int lastMediumCavePower4SoundIndex = -1;
|
||||
private static int lastSuperfar4SoundIndex = -1;
|
||||
|
||||
private static int getNextRandomIndex(List<?> list, int lastIndex) {
|
||||
int nextIndex;
|
||||
if (list.size() <= 1) {
|
||||
return 0;
|
||||
}
|
||||
while ((nextIndex = RANDOM.m_188503_(list.size())) == lastIndex) {
|
||||
}
|
||||
return nextIndex;
|
||||
}
|
||||
|
||||
public static void playRandomAnimationSound() {
|
||||
if (ANIMATION_SOUNDS.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
lastAnimationSoundIndex = AnimationSoundManager.getNextRandomIndex(ANIMATION_SOUNDS, lastAnimationSoundIndex);
|
||||
SoundEvent sound = (SoundEvent)ANIMATION_SOUNDS.get(lastAnimationSoundIndex).get();
|
||||
Minecraft.m_91087_().m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119752_((SoundEvent)sound, (float)1.0f));
|
||||
}
|
||||
|
||||
public static void playRandomFarPower2Sound() {
|
||||
if (FAR_POWER_2_SOUNDS.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
lastFarPower2SoundIndex = AnimationSoundManager.getNextRandomIndex(FAR_POWER_2_SOUNDS, lastFarPower2SoundIndex);
|
||||
SoundEvent sound = (SoundEvent)FAR_POWER_2_SOUNDS.get(lastFarPower2SoundIndex).get();
|
||||
Minecraft.m_91087_().m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119752_((SoundEvent)sound, (float)1.0f));
|
||||
}
|
||||
|
||||
public static void playRandomFarPower3Sound() {
|
||||
if (FAR_POWER_3_SOUNDS.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
lastFarPower3SoundIndex = AnimationSoundManager.getNextRandomIndex(FAR_POWER_3_SOUNDS, lastFarPower3SoundIndex);
|
||||
SoundEvent sound = (SoundEvent)FAR_POWER_3_SOUNDS.get(lastFarPower3SoundIndex).get();
|
||||
Minecraft.m_91087_().m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119752_((SoundEvent)sound, (float)1.0f));
|
||||
}
|
||||
|
||||
public static void playRandomMediumCavePower4Sound() {
|
||||
if (MEDIUM_CAVE_POWER_4_SOUNDS.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
lastMediumCavePower4SoundIndex = AnimationSoundManager.getNextRandomIndex(MEDIUM_CAVE_POWER_4_SOUNDS, lastMediumCavePower4SoundIndex);
|
||||
SoundEvent sound = (SoundEvent)MEDIUM_CAVE_POWER_4_SOUNDS.get(lastMediumCavePower4SoundIndex).get();
|
||||
Minecraft.m_91087_().m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119752_((SoundEvent)sound, (float)1.0f));
|
||||
}
|
||||
|
||||
public static void playRandomSuperfar4Sound() {
|
||||
if (SUPERFAR_POWER_4_SOUNDS.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
lastSuperfar4SoundIndex = AnimationSoundManager.getNextRandomIndex(SUPERFAR_POWER_4_SOUNDS, lastSuperfar4SoundIndex);
|
||||
SoundEvent sound = (SoundEvent)SUPERFAR_POWER_4_SOUNDS.get(lastSuperfar4SoundIndex).get();
|
||||
Minecraft.m_91087_().m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119752_((SoundEvent)sound, (float)1.0f));
|
||||
}
|
||||
|
||||
static {
|
||||
ANIMATION_SOUNDS.add(ModSounds.EXPLODE_SUPERFAR_POWER_2_1);
|
||||
ANIMATION_SOUNDS.add(ModSounds.EXPLODE_SUPERFAR_POWER_2_2);
|
||||
ANIMATION_SOUNDS.add(ModSounds.EXPLODE_SUPERFAR_POWER_3_1);
|
||||
FAR_POWER_2_SOUNDS.add(ModSounds.EXPLODE_FAR_POWER_2_1);
|
||||
FAR_POWER_2_SOUNDS.add(ModSounds.EXPLODE_FAR_POWER_2_2);
|
||||
FAR_POWER_2_SOUNDS.add(ModSounds.EXPLODE_FAR_POWER_2_3);
|
||||
FAR_POWER_3_SOUNDS.add(ModSounds.EXPLODE_FAR_POWER_3_1);
|
||||
FAR_POWER_3_SOUNDS.add(ModSounds.EXPLODE_FAR_POWER_3_2);
|
||||
FAR_POWER_3_SOUNDS.add(ModSounds.EXPLODE_FAR_POWER_3_3);
|
||||
MEDIUM_CAVE_POWER_4_SOUNDS.add(ModSounds.EXPLODE_MEDIUM_CAVE_POWER_4_1);
|
||||
MEDIUM_CAVE_POWER_4_SOUNDS.add(ModSounds.EXPLODE_MEDIUM_CAVE_POWER_4_2);
|
||||
MEDIUM_CAVE_POWER_4_SOUNDS.add(ModSounds.EXPLODE_MEDIUM_CAVE_POWER_4_3);
|
||||
SUPERFAR_POWER_4_SOUNDS.add(ModSounds.EXPLODE_SUPERFAR_POWER_4_1);
|
||||
SUPERFAR_POWER_4_SOUNDS.add(ModSounds.EXPLODE_SUPERFAR_POWER_4_2);
|
||||
SUPERFAR_POWER_4_SOUNDS.add(ModSounds.EXPLODE_SUPERFAR_POWER_4_3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
public class BackgroundParticle {
|
||||
public float x;
|
||||
public float y;
|
||||
public float vx;
|
||||
public float vy;
|
||||
public float size;
|
||||
public float life;
|
||||
public float maxLife;
|
||||
public int color;
|
||||
public ParticleType type;
|
||||
|
||||
public BackgroundParticle(float x, float y, float vx, float vy, float size, float life, int color, ParticleType type) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.vx = vx;
|
||||
this.vy = vy;
|
||||
this.size = size;
|
||||
this.life = life;
|
||||
this.maxLife = life;
|
||||
this.color = color;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void tick(float deltaTime) {
|
||||
this.x += this.vx * deltaTime * 60.0f;
|
||||
this.y += this.vy * deltaTime * 60.0f;
|
||||
this.life -= deltaTime;
|
||||
if (this.type == ParticleType.EMBER) {
|
||||
this.vy += 0.5f * deltaTime * 60.0f;
|
||||
}
|
||||
if (this.type == ParticleType.SMOKE) {
|
||||
this.size += 0.3f * deltaTime * 60.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDead() {
|
||||
return this.life <= 0.0f;
|
||||
}
|
||||
|
||||
public float getAlpha() {
|
||||
float lifeRatio = this.life / this.maxLife;
|
||||
if (this.type == ParticleType.FLASH) {
|
||||
return lifeRatio > 0.7f ? 1.0f - (lifeRatio - 0.7f) / 0.3f : lifeRatio / 0.7f;
|
||||
}
|
||||
return Mth.m_14036_((float)lifeRatio, (float)0.0f, (float)1.0f);
|
||||
}
|
||||
|
||||
public static BackgroundParticle createSpark(RandomSource random, int screenWidth, int screenHeight) {
|
||||
float x = random.m_188501_() * (float)screenWidth;
|
||||
float y = random.m_188501_() * (float)screenHeight;
|
||||
float angle = random.m_188501_() * (float)Math.PI * 2.0f;
|
||||
float speed = 2.0f + random.m_188501_() * 4.0f;
|
||||
float vx = (float)Math.cos(angle) * speed;
|
||||
float vy = (float)Math.sin(angle) * speed;
|
||||
float size = 1.0f + random.m_188501_() * 2.0f;
|
||||
float life = 0.5f + random.m_188501_() * 1.5f;
|
||||
int[] colors = new int[]{-881908, -21965, -8841, -86};
|
||||
int color = colors[random.m_188503_(colors.length)];
|
||||
return new BackgroundParticle(x, y, vx, vy, size, life, color, ParticleType.SPARK);
|
||||
}
|
||||
|
||||
public static BackgroundParticle createEmber(RandomSource random, int screenWidth, int screenHeight) {
|
||||
float x = random.m_188501_() * (float)screenWidth;
|
||||
float y = -20.0f;
|
||||
float vx = (random.m_188501_() - 0.5f) * 2.0f;
|
||||
float vy = 1.0f + random.m_188501_() * 2.0f;
|
||||
float size = 2.0f + random.m_188501_() * 4.0f;
|
||||
float life = 3.0f + random.m_188501_() * 4.0f;
|
||||
int[] colors = new int[]{-4250588, -2529701, -10939115, -48094};
|
||||
int color = colors[random.m_188503_(colors.length)];
|
||||
return new BackgroundParticle(x, y, vx, vy, size, life, color, ParticleType.EMBER);
|
||||
}
|
||||
|
||||
public static BackgroundParticle createFlash(RandomSource random, int screenWidth, int screenHeight) {
|
||||
float x = random.m_188501_() * (float)screenWidth;
|
||||
float y = random.m_188501_() * (float)screenHeight;
|
||||
float size = 30.0f + random.m_188501_() * 70.0f;
|
||||
float life = 0.2f + random.m_188501_() * 0.4f;
|
||||
int[] colors = new int[]{-881908, -4250588, -21948};
|
||||
int color = colors[random.m_188503_(colors.length)];
|
||||
return new BackgroundParticle(x, y, 0.0f, 0.0f, size, life, color, ParticleType.FLASH);
|
||||
}
|
||||
|
||||
public static BackgroundParticle createSmoke(RandomSource random, int screenWidth, int screenHeight) {
|
||||
float x = random.m_188501_() * (float)screenWidth;
|
||||
float y = (float)screenHeight + 20.0f;
|
||||
float vx = (random.m_188501_() - 0.5f) * 1.0f;
|
||||
float vy = -1.0f - random.m_188501_() * 2.0f;
|
||||
float size = 15.0f + random.m_188501_() * 30.0f;
|
||||
float life = 4.0f + random.m_188501_() * 6.0f;
|
||||
int gray = 13 + random.m_188503_(30);
|
||||
int color = 0xFF000000 | gray << 16 | gray << 8 | gray;
|
||||
return new BackgroundParticle(x, y, vx, vy, size, life, color, ParticleType.SMOKE);
|
||||
}
|
||||
|
||||
public static enum ParticleType {
|
||||
SPARK,
|
||||
EMBER,
|
||||
FLASH,
|
||||
SMOKE;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,495 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.BlockIndexManager;
|
||||
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.CycleButton;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.neoforged.neoforge.registries.ForgeRegistries;
|
||||
|
||||
public class BlacklistScreen
|
||||
extends Screen {
|
||||
private static final int NAV_WIDTH = 160;
|
||||
private static final int PADDING = 12;
|
||||
private static final int HEADER_HEIGHT = 48;
|
||||
private static final int FOOTER_HEIGHT = 64;
|
||||
private static final int SEARCH_WIDTH = 200;
|
||||
private static final int INPUT_WIDTH = 240;
|
||||
private static final int BUTTON_HEIGHT = 20;
|
||||
private static final int SPACING = 4;
|
||||
private final Screen parent;
|
||||
private BlacklistList widget;
|
||||
private EditBox inputField;
|
||||
private Button addButton;
|
||||
private EditBox searchField;
|
||||
private Button backButton;
|
||||
private Button resetButton;
|
||||
private Button infoButton;
|
||||
private CycleButton<Boolean> defaultToggle;
|
||||
private final LinkedHashSet<String> persistedEntries = new LinkedHashSet();
|
||||
private final Map<String, ExplosionOverhaul.ExplosionSourceMode> persistedSourceModes = new HashMap<String, ExplosionOverhaul.ExplosionSourceMode>();
|
||||
private final Set<String> defaultEntries = new LinkedHashSet<String>();
|
||||
private boolean showDefaults = false;
|
||||
private final EnumMap<BlacklistCategory, Button> categoryButtons = new EnumMap(BlacklistCategory.class);
|
||||
private BlacklistCategory currentCategory = BlacklistCategory.EXPLOSION;
|
||||
private List<String> suggestions = Collections.emptyList();
|
||||
private List<String> registryCache = new ArrayList<String>();
|
||||
|
||||
public BlacklistScreen(Screen parent) {
|
||||
super((Component)Component.m_237115_((String)"title.explosionoverhaul.blacklist"));
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
protected void m_7856_() {
|
||||
this.categoryButtons.clear();
|
||||
this.setupLayout();
|
||||
this.addNavigation();
|
||||
this.addTopControls();
|
||||
this.addInputArea();
|
||||
this.updateCache();
|
||||
this.loadCurrentCategoryEntries();
|
||||
}
|
||||
|
||||
private void setupLayout() {
|
||||
int listTop = 48;
|
||||
int listBottom = this.f_96544_ - 64;
|
||||
int listWidth = this.f_96543_ - 160 - 24;
|
||||
int listLeft = 172;
|
||||
this.widget = new BlacklistList(this.f_96541_, listWidth, listBottom - listTop, listTop, listBottom, 24);
|
||||
this.widget.m_93507_(listLeft);
|
||||
this.m_142416_((GuiEventListener)this.widget);
|
||||
}
|
||||
|
||||
private void addNavigation() {
|
||||
int buttonY = 48;
|
||||
for (BlacklistCategory category : BlacklistCategory.values()) {
|
||||
Button button = Button.m_253074_((Component)this.formatCategoryLabel(category), b -> this.selectCategory(category)).m_252794_(12, buttonY).m_253046_(160, 20).m_257505_(Tooltip.m_257550_((Component)Component.m_237115_((String)category.getTooltipKey()))).m_253136_();
|
||||
this.categoryButtons.put(category, button);
|
||||
this.m_142416_((GuiEventListener)button);
|
||||
buttonY += 24;
|
||||
}
|
||||
}
|
||||
|
||||
private void addTopControls() {
|
||||
int listLeft = 172;
|
||||
this.backButton = Button.m_253074_((Component)Component.m_237115_((String)"gui.back"), b -> this.m_7379_()).m_252794_(12, 12).m_253046_(80, 20).m_253136_();
|
||||
this.m_142416_((GuiEventListener)this.backButton);
|
||||
this.searchField = new EditBox(this.f_96547_, listLeft, 26, 200, 18, (Component)Component.m_237119_());
|
||||
this.searchField.m_257771_((Component)Component.m_237115_((String)"option.explosionoverhaul.blacklist_search"));
|
||||
this.searchField.m_94151_(s -> this.refreshList());
|
||||
this.m_142416_((GuiEventListener)this.searchField);
|
||||
this.resetButton = Button.m_253074_((Component)Component.m_237115_((String)"option.explosionoverhaul.reset_list"), this::onResetClicked).m_252794_(this.f_96543_ - 250, 12).m_253046_(60, 20).m_257505_(Tooltip.m_257550_((Component)Component.m_237115_((String)"tooltip.explosionoverhaul.reset_list"))).m_253136_();
|
||||
this.m_142416_((GuiEventListener)this.resetButton);
|
||||
this.defaultToggle = CycleButton.m_168916_((boolean)this.showDefaults).m_232498_(value -> Tooltip.m_257550_((Component)Component.m_237115_((String)"tooltip.explosionoverhaul.show_defaults"))).m_168936_(this.f_96543_ - 180, 12, 168, 20, (Component)Component.m_237115_((String)"option.explosionoverhaul.show_defaults"), (btn, value) -> {
|
||||
this.showDefaults = value;
|
||||
this.refreshList();
|
||||
});
|
||||
this.m_142416_((GuiEventListener)this.defaultToggle);
|
||||
}
|
||||
|
||||
private void addInputArea() {
|
||||
int y = this.f_96544_ - 28;
|
||||
this.inputField = new EditBox(this.f_96547_, (this.f_96543_ - 240) / 2, y, 240, 18, (Component)Component.m_237119_());
|
||||
this.inputField.m_94199_(128);
|
||||
this.inputField.m_257771_((Component)Component.m_237115_((String)"option.explosionoverhaul.blacklist_input"));
|
||||
this.inputField.m_94151_(this::updateSuggestions);
|
||||
this.m_142416_((GuiEventListener)this.inputField);
|
||||
this.addButton = Button.m_253074_((Component)Component.m_237115_((String)"option.explosionoverhaul.blacklist_add"), b -> this.addCurrentInput()).m_252794_(this.inputField.m_252754_() + 240 + 8, this.inputField.m_252907_() - 1).m_253046_(80, 20).m_253136_();
|
||||
this.m_142416_((GuiEventListener)this.addButton);
|
||||
this.infoButton = Button.m_253074_((Component)Component.m_237115_((String)"option.explosionoverhaul.blacklist_info"), b -> {}).m_252794_(this.addButton.m_252754_() + 80 + 4, this.addButton.m_252907_()).m_253046_(40, 20).m_257505_(Tooltip.m_257550_((Component)Component.m_237115_((String)"tooltip.explosionoverhaul.blacklist_info"))).m_253136_();
|
||||
this.infoButton.f_93624_ = this.currentCategory == BlacklistCategory.SOURCES;
|
||||
this.m_142416_((GuiEventListener)this.infoButton);
|
||||
}
|
||||
|
||||
private void onResetClicked(Button b) {
|
||||
if (BlacklistScreen.m_96638_()) {
|
||||
List<String> defaults = this.currentCategory.loadDefaults();
|
||||
this.currentCategory.saveEntries(defaults);
|
||||
this.persistedEntries.clear();
|
||||
this.persistedEntries.addAll(defaults);
|
||||
if (this.currentCategory == BlacklistCategory.SOURCES) {
|
||||
this.persistedSourceModes.clear();
|
||||
this.save();
|
||||
}
|
||||
this.refreshList();
|
||||
this.displayStatus((Component)Component.m_237115_((String)"message.explosionoverhaul.list_reset"));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCache() {
|
||||
LinkedHashSet<String> uniqueRegistry = new LinkedHashSet<String>();
|
||||
if (this.currentCategory == BlacklistCategory.SOURCES) {
|
||||
uniqueRegistry.add("generic");
|
||||
ForgeRegistries.ENTITY_TYPES.getKeys().stream().map(ResourceLocation::toString).forEach(uniqueRegistry::add);
|
||||
ForgeRegistries.BLOCKS.getKeys().stream().map(ResourceLocation::toString).forEach(uniqueRegistry::add);
|
||||
ForgeRegistries.ITEMS.getKeys().stream().map(ResourceLocation::toString).forEach(uniqueRegistry::add);
|
||||
} else {
|
||||
ForgeRegistries.BLOCKS.getKeys().stream().map(ResourceLocation::toString).forEach(uniqueRegistry::add);
|
||||
}
|
||||
this.registryCache = new ArrayList<String>(uniqueRegistry);
|
||||
}
|
||||
|
||||
private void loadCurrentCategoryEntries() {
|
||||
this.persistedEntries.clear();
|
||||
this.persistedEntries.addAll(this.currentCategory.loadEntries());
|
||||
if (this.currentCategory == BlacklistCategory.SOURCES) {
|
||||
this.persistedSourceModes.clear();
|
||||
this.persistedSourceModes.putAll(ExplosionOverhaul.getSourceModes());
|
||||
}
|
||||
this.defaultEntries.clear();
|
||||
this.defaultEntries.addAll(this.currentCategory.loadDefaults());
|
||||
this.refreshList();
|
||||
}
|
||||
|
||||
private void selectCategory(BlacklistCategory category) {
|
||||
if (this.currentCategory == category) {
|
||||
return;
|
||||
}
|
||||
this.currentCategory = category;
|
||||
this.updateCache();
|
||||
this.loadCurrentCategoryEntries();
|
||||
this.updateCategoryButtons();
|
||||
if (this.infoButton != null) {
|
||||
boolean bl = this.infoButton.f_93624_ = this.currentCategory == BlacklistCategory.SOURCES;
|
||||
}
|
||||
if (this.inputField != null) {
|
||||
this.inputField.m_94144_("");
|
||||
this.updateSuggestions("");
|
||||
this.inputField.m_257771_((Component)Component.m_237115_((String)(this.currentCategory == BlacklistCategory.SOURCES ? "option.explosionoverhaul.blacklist_input_entities" : "option.explosionoverhaul.blacklist_input")));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCategoryButtons() {
|
||||
this.categoryButtons.forEach((category, button) -> button.m_93666_(this.formatCategoryLabel((BlacklistCategory)((Object)category))));
|
||||
}
|
||||
|
||||
private Component formatCategoryLabel(BlacklistCategory category) {
|
||||
MutableComponent label = Component.m_237115_((String)category.getLabelKey());
|
||||
if (category == this.currentCategory) {
|
||||
return Component.m_237113_((String)"\u25b6 ").m_7220_((Component)label);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
private void refreshList() {
|
||||
String query = this.searchField == null ? "" : this.searchField.m_94155_().trim().toLowerCase(Locale.ROOT);
|
||||
boolean hasQuery = !query.isEmpty();
|
||||
ArrayList<BlacklistEntry> entries = new ArrayList<BlacklistEntry>();
|
||||
for (String id : this.persistedEntries) {
|
||||
boolean isDefault = this.defaultEntries.contains(id);
|
||||
if (!hasQuery && !this.showDefaults && isDefault || hasQuery && !id.toLowerCase(Locale.ROOT).contains(query)) continue;
|
||||
entries.add(new BlacklistEntry(id, isDefault));
|
||||
}
|
||||
this.widget.rebuild(entries);
|
||||
}
|
||||
|
||||
private void addCurrentInput() {
|
||||
String normalized;
|
||||
String raw = this.inputField.m_94155_().trim().toLowerCase(Locale.ROOT);
|
||||
if (raw.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (raw.equals("generic")) {
|
||||
normalized = "generic";
|
||||
} else {
|
||||
ResourceLocation id = ResourceLocation.m_135820_((String)(raw.contains(":") ? raw : "minecraft:" + raw));
|
||||
if (id == null) {
|
||||
this.displayStatus((Component)Component.m_237115_((String)"message.explosionoverhaul.invalid_id"));
|
||||
return;
|
||||
}
|
||||
normalized = id.toString();
|
||||
}
|
||||
if (!this.persistedEntries.add(normalized)) {
|
||||
this.displayStatus((Component)Component.m_237115_((String)"message.explosionoverhaul.duplicate_entry"));
|
||||
return;
|
||||
}
|
||||
if (this.currentCategory == BlacklistCategory.SOURCES) {
|
||||
this.persistedSourceModes.put(normalized, ExplosionOverhaul.ExplosionSourceMode.DEFAULT);
|
||||
}
|
||||
this.save();
|
||||
this.inputField.m_94144_("");
|
||||
this.updateSuggestions("");
|
||||
this.refreshList();
|
||||
}
|
||||
|
||||
private void removeEntry(String id) {
|
||||
if (this.persistedEntries.remove(id)) {
|
||||
if (this.currentCategory == BlacklistCategory.SOURCES) {
|
||||
this.persistedSourceModes.remove(id);
|
||||
}
|
||||
this.save();
|
||||
this.refreshList();
|
||||
}
|
||||
}
|
||||
|
||||
private void save() {
|
||||
if (this.currentCategory == BlacklistCategory.SOURCES) {
|
||||
HashMap<String, ExplosionOverhaul.ExplosionSourceMode> toSave = new HashMap<String, ExplosionOverhaul.ExplosionSourceMode>();
|
||||
for (String id : this.persistedEntries) {
|
||||
toSave.put(id, this.persistedSourceModes.getOrDefault(id, ExplosionOverhaul.ExplosionSourceMode.DEFAULT));
|
||||
}
|
||||
ExplosionOverhaul.setSourceModes(toSave);
|
||||
} else {
|
||||
this.currentCategory.saveEntries(new ArrayList<String>(this.persistedEntries));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSuggestions(String current) {
|
||||
String query = current.trim().toLowerCase(Locale.ROOT);
|
||||
if (query.isEmpty()) {
|
||||
this.suggestions = Collections.emptyList();
|
||||
return;
|
||||
}
|
||||
this.suggestions = this.registryCache.stream().filter(name -> name.startsWith(query)).limit(12L).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void displayStatus(Component message) {
|
||||
if (this.f_96541_ != null && this.f_96541_.f_91065_ != null) {
|
||||
this.f_96541_.f_91065_.m_93063_(message, false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean m_7933_(int keyCode, int scanCode, int modifiers) {
|
||||
if (this.inputField.m_93696_() && (keyCode == 257 || keyCode == 335)) {
|
||||
this.addCurrentInput();
|
||||
return true;
|
||||
}
|
||||
return super.m_7933_(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public void m_88315_(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
|
||||
this.m_280273_(graphics);
|
||||
graphics.m_280614_(this.f_96547_, this.f_96539_, this.f_96543_ / 2 - this.f_96547_.m_92852_((FormattedText)this.f_96539_) / 2, 16, 0xFFFFFF, false);
|
||||
this.widget.m_88315_(graphics, mouseX, mouseY, delta);
|
||||
super.m_88315_(graphics, mouseX, mouseY, delta);
|
||||
this.inputField.m_88315_(graphics, mouseX, mouseY, delta);
|
||||
this.renderSuggestions(graphics, mouseX, mouseY);
|
||||
}
|
||||
|
||||
private void renderSuggestions(GuiGraphics graphics, int mouseX, int mouseY) {
|
||||
if (this.suggestions.isEmpty() || !this.inputField.m_93696_()) {
|
||||
return;
|
||||
}
|
||||
int x = this.inputField.m_252754_();
|
||||
int y = this.inputField.m_252907_() - this.suggestions.size() * 12 - 4;
|
||||
int width = this.inputField.m_5711_();
|
||||
int line = 0;
|
||||
for (String s : this.suggestions) {
|
||||
int yy = y + line * 12;
|
||||
graphics.m_280509_(x, yy, x + width, yy + 12, -1442840576);
|
||||
graphics.m_280056_(this.f_96547_, s, x + 4, yy + 2, 0xE0E0E0, false);
|
||||
++line;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean m_6375_(double mouseX, double mouseY, int button) {
|
||||
if (this.inputField.m_93696_() && !this.suggestions.isEmpty()) {
|
||||
int x = this.inputField.m_252754_();
|
||||
int y = this.inputField.m_252907_() - this.suggestions.size() * 12 - 4;
|
||||
int width = this.inputField.m_5711_();
|
||||
for (int i = 0; i < this.suggestions.size(); ++i) {
|
||||
int yy = y + i * 12;
|
||||
if (!(mouseX >= (double)x) || !(mouseX <= (double)(x + width)) || !(mouseY >= (double)yy) || !(mouseY <= (double)(yy + 12))) continue;
|
||||
this.inputField.m_94144_(this.suggestions.get(i));
|
||||
this.inputField.m_94196_(this.inputField.m_94155_().length());
|
||||
this.updateSuggestions(this.inputField.m_94155_());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.m_6375_(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public void m_7379_() {
|
||||
this.save();
|
||||
this.f_96541_.m_91152_(this.parent);
|
||||
}
|
||||
|
||||
private static enum BlacklistCategory {
|
||||
EXPLOSION("option.explosionoverhaul.blacklist_category_explosion", "tooltip.explosionoverhaul.blacklist_category_explosion", ExplosionOverhaul::getExplosionBlacklistList, ExplosionOverhaul::getDefaultExplosionBlacklist, ExplosionOverhaul::setExplosionBlacklistFromList),
|
||||
GLASS("option.explosionoverhaul.blacklist_category_glass", "tooltip.explosionoverhaul.blacklist_category_glass", BlockIndexManager::getReinforcedGlassBlacklist, BlockIndexManager::getDefaultReinforcedGlassBlacklist, BlockIndexManager::setReinforcedGlassBlacklistFromList),
|
||||
SOURCES("option.explosionoverhaul.blacklist_category_sources", "tooltip.explosionoverhaul.blacklist_category_sources", () -> new ArrayList<String>(ExplosionOverhaul.getSourceModes().keySet()), ArrayList::new, list -> {});
|
||||
|
||||
private final String labelKey;
|
||||
private final String tooltipKey;
|
||||
private final Supplier<List<String>> entriesSupplier;
|
||||
private final Supplier<List<String>> defaultsSupplier;
|
||||
private final Consumer<List<String>> saveAction;
|
||||
|
||||
private BlacklistCategory(String labelKey, String tooltipKey, Supplier<List<String>> entriesSupplier, Supplier<List<String>> defaultsSupplier, Consumer<List<String>> saveAction) {
|
||||
this.labelKey = labelKey;
|
||||
this.tooltipKey = tooltipKey;
|
||||
this.entriesSupplier = entriesSupplier;
|
||||
this.defaultsSupplier = defaultsSupplier;
|
||||
this.saveAction = saveAction;
|
||||
}
|
||||
|
||||
String getLabelKey() {
|
||||
return this.labelKey;
|
||||
}
|
||||
|
||||
String getTooltipKey() {
|
||||
return this.tooltipKey;
|
||||
}
|
||||
|
||||
List<String> loadEntries() {
|
||||
return this.entriesSupplier.get();
|
||||
}
|
||||
|
||||
List<String> loadDefaults() {
|
||||
return this.defaultsSupplier.get();
|
||||
}
|
||||
|
||||
void saveEntries(List<String> entries) {
|
||||
this.saveAction.accept(entries);
|
||||
}
|
||||
}
|
||||
|
||||
private class BlacklistList
|
||||
extends ObjectSelectionList<BlacklistEntry> {
|
||||
public BlacklistList(Minecraft mc, int width, int height, int top, int bottom, int itemHeight) {
|
||||
super(mc, width, height, top, bottom, itemHeight);
|
||||
}
|
||||
|
||||
void rebuild(List<BlacklistEntry> entries) {
|
||||
this.m_5988_(entries);
|
||||
}
|
||||
|
||||
public int m_5759_() {
|
||||
return this.f_93388_ - 12;
|
||||
}
|
||||
|
||||
protected int m_5756_() {
|
||||
return this.m_5747_() + this.m_5759_();
|
||||
}
|
||||
|
||||
public boolean m_7979_(double mouseX, double mouseY, int button, double dragX, double dragY) {
|
||||
return super.m_7979_(mouseX, mouseY, button, dragX, dragY);
|
||||
}
|
||||
}
|
||||
|
||||
private class BlacklistEntry
|
||||
extends ObjectSelectionList.Entry<BlacklistEntry> {
|
||||
private final String id;
|
||||
private final boolean isDefault;
|
||||
private final Button removeButton;
|
||||
private CycleButton<ExplosionOverhaul.ExplosionSourceMode> modeButton;
|
||||
private ItemStack icon;
|
||||
private int lastX;
|
||||
private int lastY;
|
||||
private int lastRowWidth;
|
||||
private int lastRowHeight;
|
||||
|
||||
BlacklistEntry(String id, boolean isDefault) {
|
||||
this.id = id;
|
||||
this.isDefault = isDefault;
|
||||
if (BlacklistScreen.this.currentCategory == BlacklistCategory.SOURCES) {
|
||||
if (id.equals("generic")) {
|
||||
this.icon = new ItemStack((ItemLike)Items.f_41996_);
|
||||
} else {
|
||||
ResourceLocation rl = ResourceLocation.m_135820_((String)id);
|
||||
ItemStack stack = ItemStack.f_41583_;
|
||||
if (rl != null) {
|
||||
Block b2;
|
||||
stack = new ItemStack((ItemLike)ForgeRegistries.ITEMS.getValue(rl));
|
||||
if (stack.m_41619_()) {
|
||||
stack = new ItemStack((ItemLike)ForgeRegistries.ITEMS.getValue(new ResourceLocation(rl.m_135827_(), rl.m_135815_() + "_spawn_egg")));
|
||||
}
|
||||
if (stack.m_41619_() && (b2 = (Block)ForgeRegistries.BLOCKS.getValue(rl)) != Blocks.f_50016_) {
|
||||
stack = new ItemStack((ItemLike)b2.m_5456_());
|
||||
}
|
||||
}
|
||||
this.icon = stack.m_41619_() ? new ItemStack((ItemLike)Items.f_41996_) : stack;
|
||||
}
|
||||
ExplosionOverhaul.ExplosionSourceMode currentMode = BlacklistScreen.this.persistedSourceModes.getOrDefault(id, ExplosionOverhaul.ExplosionSourceMode.DEFAULT);
|
||||
String entryId = id;
|
||||
this.modeButton = CycleButton.m_168894_(m -> Component.m_237115_((String)("option.explosionoverhaul.sourcemode_" + m.name().toLowerCase(Locale.ROOT)))).m_168961_((Object[])ExplosionOverhaul.ExplosionSourceMode.values()).m_168948_((Object)currentMode).m_232498_(m -> Tooltip.m_257550_((Component)Component.m_237115_((String)("tooltip.explosionoverhaul.sourcemode_" + m.name().toLowerCase(Locale.ROOT))))).m_168936_(0, 0, 150, 20, (Component)Component.m_237119_(), (btn, value) -> {
|
||||
BlacklistScreen.this.persistedSourceModes.put(entryId, (ExplosionOverhaul.ExplosionSourceMode)((Object)value));
|
||||
BlacklistScreen.this.save();
|
||||
});
|
||||
} else {
|
||||
ItemStack stack;
|
||||
Block block = (Block)ForgeRegistries.BLOCKS.getValue(ResourceLocation.m_135820_((String)id));
|
||||
ItemStack itemStack = stack = block == null || block == Blocks.f_50016_ ? ItemStack.f_41583_ : new ItemStack((ItemLike)block.m_5456_());
|
||||
if (stack.m_41619_()) {
|
||||
stack = new ItemStack((ItemLike)Items.f_42127_);
|
||||
}
|
||||
this.icon = stack;
|
||||
}
|
||||
this.removeButton = Button.m_253074_((Component)Component.m_237113_((String)"\u2715"), b -> BlacklistScreen.this.removeEntry(this.id)).m_252794_(0, 0).m_253046_(20, 20).m_253136_();
|
||||
}
|
||||
|
||||
public Component m_142172_() {
|
||||
return Component.m_237113_((String)this.id);
|
||||
}
|
||||
|
||||
public boolean m_6375_(double mouseX, double mouseY, int button) {
|
||||
if (this.modeButton != null && this.modeButton.m_6375_(mouseX, mouseY, button)) {
|
||||
return true;
|
||||
}
|
||||
int btnX = this.lastX + this.lastRowWidth - 26;
|
||||
int btnY = this.lastY + (this.lastRowHeight - 20) / 2;
|
||||
if (mouseX >= (double)btnX && mouseX <= (double)(btnX + 20) && mouseY >= (double)btnY && mouseY <= (double)(btnY + 20)) {
|
||||
BlacklistScreen.this.removeEntry(this.id);
|
||||
return true;
|
||||
}
|
||||
return super.m_6375_(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public void m_6311_(GuiGraphics graphics, int index, int y, int x, int rowWidth, int rowHeight, int mouseX, int mouseY, boolean hovered, float delta) {
|
||||
this.lastX = x;
|
||||
this.lastY = y;
|
||||
this.lastRowWidth = rowWidth;
|
||||
this.lastRowHeight = rowHeight;
|
||||
int iconX = x + 6;
|
||||
int iconY = y + (rowHeight - 16) / 2;
|
||||
try {
|
||||
graphics.m_280480_(this.icon, iconX, iconY);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
this.icon = new ItemStack((ItemLike)Items.f_42127_);
|
||||
graphics.m_280480_(this.icon, iconX, iconY);
|
||||
}
|
||||
int textX = iconX + 22;
|
||||
int color = this.isDefault ? -5197648 : -1;
|
||||
graphics.m_280056_(BlacklistScreen.this.f_96547_, this.id, textX, y + (rowHeight - 8) / 2, color, false);
|
||||
if (this.modeButton != null) {
|
||||
int modeX = x + rowWidth - 180;
|
||||
this.modeButton.m_264152_(modeX, y + (rowHeight - 20) / 2);
|
||||
this.modeButton.m_88315_(graphics, mouseX, mouseY, delta);
|
||||
}
|
||||
int btnX = x + rowWidth - 26;
|
||||
this.removeButton.m_264152_(btnX, y + (rowHeight - 20) / 2);
|
||||
this.removeButton.m_88315_(graphics, mouseX, mouseY, delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
262
src/main/java/com/vinlanx/explosionoverhaul/client/Blur.java
Normal file
262
src/main/java/com/vinlanx/explosionoverhaul/client/Blur.java
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderTarget;
|
||||
import com.mojang.blaze3d.pipeline.TextureTarget;
|
||||
import com.mojang.blaze3d.shaders.Uniform;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.BufferUploader;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.vinlanx.explosionoverhaul.client.ConcussionAudioEffect;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ShaderInstance;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(value=Dist.CLIENT)
|
||||
public class Blur {
|
||||
private static final int FADE_IN_TICKS = 40;
|
||||
private static final int FADE_OUT_TICKS = 100;
|
||||
private static Phase phase = Phase.IDLE;
|
||||
private static int holdTicks = 0;
|
||||
private static int ticksInPhase = 0;
|
||||
private static ShaderInstance shader;
|
||||
private static RenderTarget blurTarget;
|
||||
private static int lastWidth;
|
||||
private static int lastHeight;
|
||||
private static float currentIntensity;
|
||||
private static float targetIntensity;
|
||||
private static float currentDesaturation;
|
||||
public static boolean APPLY_TO_HUD;
|
||||
public static boolean APPLY_TO_HAND;
|
||||
|
||||
public static boolean isActive() {
|
||||
return phase != Phase.IDLE;
|
||||
}
|
||||
|
||||
public static float getCurrentIntensity() {
|
||||
return currentIntensity;
|
||||
}
|
||||
|
||||
public static void setShader(ShaderInstance instance) {
|
||||
shader = instance;
|
||||
}
|
||||
|
||||
public static void setDesaturation(float v) {
|
||||
currentDesaturation = Mth.m_14036_((float)v, (float)0.0f, (float)1.0f);
|
||||
}
|
||||
|
||||
public static void start(int seconds) {
|
||||
Blur.start(seconds, 1.0f);
|
||||
}
|
||||
|
||||
public static void start(int seconds, float intensity) {
|
||||
int newHoldTicks = Mth.m_14045_((int)seconds, (int)1, (int)100) * 20;
|
||||
float newIntensity = Mth.m_14036_((float)intensity, (float)0.0f, (float)1.0f);
|
||||
if (phase != Phase.IDLE) {
|
||||
targetIntensity = Mth.m_14036_((float)(targetIntensity + newIntensity), (float)0.0f, (float)1.0f);
|
||||
holdTicks = Math.min(2000, holdTicks + newHoldTicks);
|
||||
if (phase == Phase.FADE_OUT) {
|
||||
phase = Phase.HOLD;
|
||||
ticksInPhase = 0;
|
||||
}
|
||||
} else {
|
||||
holdTicks = newHoldTicks;
|
||||
ticksInPhase = 0;
|
||||
targetIntensity = newIntensity;
|
||||
phase = Phase.FADE_IN;
|
||||
currentIntensity = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public static void stop() {
|
||||
phase = Phase.IDLE;
|
||||
ticksInPhase = 0;
|
||||
holdTicks = 0;
|
||||
currentIntensity = 0.0f;
|
||||
targetIntensity = 0.0f;
|
||||
}
|
||||
|
||||
public static void onClientTick() {
|
||||
float intensity;
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.m_91104_() || phase == Phase.IDLE) {
|
||||
return;
|
||||
}
|
||||
++ticksInPhase;
|
||||
switch (phase) {
|
||||
case FADE_IN: {
|
||||
float t = Math.min(1.0f, (float)ticksInPhase / 40.0f);
|
||||
intensity = Blur.easeOutCubic(t) * targetIntensity;
|
||||
if (ticksInPhase < 40) break;
|
||||
phase = Phase.HOLD;
|
||||
ticksInPhase = 0;
|
||||
break;
|
||||
}
|
||||
case HOLD: {
|
||||
intensity = targetIntensity;
|
||||
if (ticksInPhase < holdTicks) break;
|
||||
phase = Phase.FADE_OUT;
|
||||
ticksInPhase = 0;
|
||||
break;
|
||||
}
|
||||
case FADE_OUT: {
|
||||
float t = Math.min(1.0f, (float)ticksInPhase / 100.0f);
|
||||
intensity = targetIntensity * (1.0f - Blur.easeInCubic(t));
|
||||
if (ticksInPhase < 100) break;
|
||||
currentIntensity = 0.0f;
|
||||
Blur.stop();
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
intensity = 0.0f;
|
||||
}
|
||||
}
|
||||
currentIntensity = intensity;
|
||||
if (mc.f_91074_ != null) {
|
||||
ConcussionAudioEffect.updateHeartbeat(mc.f_91074_, currentIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void render(RenderStage stage) {
|
||||
if (phase == Phase.IDLE || shader == null) {
|
||||
return;
|
||||
}
|
||||
if (!Blur.shouldRenderStage(stage)) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc == null) {
|
||||
return;
|
||||
}
|
||||
RenderTarget mainTarget = mc.m_91385_();
|
||||
if (mainTarget == null) {
|
||||
return;
|
||||
}
|
||||
Blur.ensureTarget(mainTarget.f_83915_, mainTarget.f_83916_);
|
||||
if (blurTarget == null) {
|
||||
return;
|
||||
}
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.depthMask((boolean)false);
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f);
|
||||
blurTarget.m_83947_(true);
|
||||
RenderSystem.viewport((int)0, (int)0, (int)Blur.blurTarget.f_83915_, (int)Blur.blurTarget.f_83916_);
|
||||
Blur.renderFullscreen(mainTarget.m_83975_(), currentIntensity, mainTarget.f_83915_, mainTarget.f_83916_);
|
||||
mainTarget.m_83947_(true);
|
||||
RenderSystem.viewport((int)0, (int)0, (int)mainTarget.f_83915_, (int)mainTarget.f_83916_);
|
||||
Blur.renderFullscreen(blurTarget.m_83975_(), 0.0f, mainTarget.f_83915_, mainTarget.f_83916_);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.depthMask((boolean)true);
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
|
||||
private static boolean shouldRenderStage(RenderStage stage) {
|
||||
if (APPLY_TO_HUD) {
|
||||
return stage == RenderStage.HUD;
|
||||
}
|
||||
if (APPLY_TO_HAND && Blur.isFirstPerson()) {
|
||||
return stage == RenderStage.HAND;
|
||||
}
|
||||
return stage == RenderStage.WORLD;
|
||||
}
|
||||
|
||||
private static boolean isFirstPerson() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc == null) {
|
||||
return false;
|
||||
}
|
||||
return mc.f_91066_.m_92176_().m_90612_();
|
||||
}
|
||||
|
||||
private static void ensureTarget(int width, int height) {
|
||||
if (blurTarget == null || width != lastWidth || height != lastHeight) {
|
||||
if (blurTarget != null) {
|
||||
blurTarget.m_83930_();
|
||||
}
|
||||
blurTarget = new TextureTarget(width, height, false, Minecraft.f_91002_);
|
||||
lastWidth = width;
|
||||
lastHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderFullscreen(int textureId, float intensity, int width, int height) {
|
||||
Uniform desatUniform;
|
||||
Uniform vignetteUniform;
|
||||
Uniform heartbeatUniform;
|
||||
Uniform outSizeUniform;
|
||||
Uniform inSizeUniform;
|
||||
RenderSystem.setShader(() -> shader);
|
||||
RenderSystem.setShaderTexture((int)0, (int)textureId);
|
||||
shader.m_173350_("DiffuseSampler", (Object)textureId);
|
||||
float clamped = Mth.m_14036_((float)intensity, (float)0.0f, (float)1.0f);
|
||||
Uniform intensityUniform = shader.m_173348_("Intensity");
|
||||
if (intensityUniform != null) {
|
||||
intensityUniform.m_5985_(clamped);
|
||||
}
|
||||
if ((inSizeUniform = shader.m_173348_("InSize")) != null) {
|
||||
inSizeUniform.m_7971_((float)width, (float)height);
|
||||
}
|
||||
if ((outSizeUniform = shader.m_173348_("OutSize")) != null) {
|
||||
outSizeUniform.m_7971_((float)width, (float)height);
|
||||
}
|
||||
if ((heartbeatUniform = shader.m_173348_("Heartbeat")) != null) {
|
||||
heartbeatUniform.m_5985_(ConcussionAudioEffect.getCurrentHeartbeatVisual());
|
||||
}
|
||||
if ((vignetteUniform = shader.m_173348_("Vignette")) != null) {
|
||||
vignetteUniform.m_5985_(1.0E-5f);
|
||||
}
|
||||
if ((desatUniform = shader.m_173348_("Desaturation")) != null) {
|
||||
desatUniform.m_5985_(clamped);
|
||||
}
|
||||
BufferBuilder builder = Tesselator.m_85913_().m_85915_();
|
||||
builder.m_166779_(VertexFormat.Mode.QUADS, DefaultVertexFormat.f_85817_);
|
||||
builder.m_5483_(-1.0, -1.0, 0.0).m_7421_(0.0f, 1.0f).m_5752_();
|
||||
builder.m_5483_(1.0, -1.0, 0.0).m_7421_(1.0f, 1.0f).m_5752_();
|
||||
builder.m_5483_(1.0, 1.0, 0.0).m_7421_(1.0f, 0.0f).m_5752_();
|
||||
builder.m_5483_(-1.0, 1.0, 0.0).m_7421_(0.0f, 0.0f).m_5752_();
|
||||
BufferUploader.m_231202_((BufferBuilder.RenderedBuffer)builder.m_231175_());
|
||||
}
|
||||
|
||||
private static float easeOutCubic(float t) {
|
||||
float inv = 1.0f - t;
|
||||
return 1.0f - inv * inv * inv;
|
||||
}
|
||||
|
||||
private static float easeInCubic(float t) {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
static {
|
||||
lastWidth = -1;
|
||||
lastHeight = -1;
|
||||
currentIntensity = 0.0f;
|
||||
targetIntensity = 1.0f;
|
||||
currentDesaturation = 0.0f;
|
||||
APPLY_TO_HUD = false;
|
||||
APPLY_TO_HAND = true;
|
||||
}
|
||||
|
||||
private static enum Phase {
|
||||
IDLE,
|
||||
FADE_IN,
|
||||
HOLD,
|
||||
FADE_OUT;
|
||||
|
||||
}
|
||||
|
||||
public static enum RenderStage {
|
||||
WORLD,
|
||||
HAND,
|
||||
HUD;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(value=Dist.CLIENT)
|
||||
public class CameraShakeConcussionEffect {
|
||||
private static final int FADE_IN_TICKS = 40;
|
||||
private static final int FADE_OUT_TICKS = 40;
|
||||
private static Phase phase = Phase.IDLE;
|
||||
private static int ticksInPhase = 0;
|
||||
private static int holdTicks = 0;
|
||||
private static float currentIntensity = 0.0f;
|
||||
private static float targetIntensity = 0.0f;
|
||||
private static float lastYawOffset = 0.0f;
|
||||
private static float lastPitchOffset = 0.0f;
|
||||
|
||||
public static boolean isActive() {
|
||||
return phase != Phase.IDLE;
|
||||
}
|
||||
|
||||
public static void start(int seconds, float intensity) {
|
||||
int newHoldTicks = Mth.m_14045_((int)seconds, (int)1, (int)100) * 20;
|
||||
float newIntensity = Math.max(0.0f, intensity);
|
||||
if (phase != Phase.IDLE) {
|
||||
targetIntensity += newIntensity;
|
||||
holdTicks = Math.min(2000, holdTicks + newHoldTicks);
|
||||
if (phase == Phase.FADE_OUT) {
|
||||
phase = Phase.HOLD;
|
||||
ticksInPhase = 0;
|
||||
}
|
||||
} else {
|
||||
targetIntensity = newIntensity;
|
||||
holdTicks = newHoldTicks;
|
||||
ticksInPhase = 0;
|
||||
phase = Phase.FADE_IN;
|
||||
currentIntensity = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public static void onClientTick() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.m_91104_()) {
|
||||
return;
|
||||
}
|
||||
LocalPlayer player = mc.f_91074_;
|
||||
if (player == null) {
|
||||
CameraShakeConcussionEffect.stop();
|
||||
return;
|
||||
}
|
||||
player.m_19884_((double)(-lastYawOffset), (double)(-lastPitchOffset));
|
||||
lastYawOffset = 0.0f;
|
||||
lastPitchOffset = 0.0f;
|
||||
if (phase == Phase.IDLE) {
|
||||
return;
|
||||
}
|
||||
++ticksInPhase;
|
||||
switch (phase) {
|
||||
case FADE_IN: {
|
||||
float t = (float)ticksInPhase / 40.0f;
|
||||
currentIntensity = CameraShakeConcussionEffect.easeInOutCubic(t) * targetIntensity;
|
||||
if (ticksInPhase < 40) break;
|
||||
phase = Phase.HOLD;
|
||||
ticksInPhase = 0;
|
||||
break;
|
||||
}
|
||||
case HOLD: {
|
||||
currentIntensity = targetIntensity;
|
||||
if (ticksInPhase < holdTicks) break;
|
||||
phase = Phase.FADE_OUT;
|
||||
ticksInPhase = 0;
|
||||
break;
|
||||
}
|
||||
case FADE_OUT: {
|
||||
float t = (float)ticksInPhase / 40.0f;
|
||||
currentIntensity = targetIntensity * CameraShakeConcussionEffect.easeInOutCubic(1.0f - t);
|
||||
if (ticksInPhase < 40) break;
|
||||
CameraShakeConcussionEffect.stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (currentIntensity > 0.0f) {
|
||||
CameraShakeConcussionEffect.applySway(player, (float)player.f_19797_ + mc.m_91296_());
|
||||
}
|
||||
}
|
||||
|
||||
private static void applySway(LocalPlayer player, float totalTicks) {
|
||||
float horizontalSway = Mth.m_14031_((float)(totalTicks * 0.04f)) * 1.5f + Mth.m_14031_((float)(totalTicks * 0.025f)) * 1.0f;
|
||||
float verticalSway = Mth.m_14089_((float)(totalTicks * 0.035f)) * 0.8f + Mth.m_14031_((float)(totalTicks * 0.015f)) * 0.5f;
|
||||
float yawChange = horizontalSway * currentIntensity * 50.0f;
|
||||
float pitchChange = verticalSway * currentIntensity * 30.0f;
|
||||
player.m_19884_((double)yawChange, (double)pitchChange);
|
||||
lastYawOffset = yawChange;
|
||||
lastPitchOffset = pitchChange;
|
||||
}
|
||||
|
||||
public static void stop() {
|
||||
phase = Phase.IDLE;
|
||||
ticksInPhase = 0;
|
||||
holdTicks = 0;
|
||||
currentIntensity = 0.0f;
|
||||
targetIntensity = 0.0f;
|
||||
lastYawOffset = 0.0f;
|
||||
lastPitchOffset = 0.0f;
|
||||
}
|
||||
|
||||
private static float easeInOutCubic(float t) {
|
||||
return t < 0.5f ? 4.0f * t * t * t : 1.0f - (float)Math.pow(-2.0f * t + 2.0f, 3.0) / 2.0f;
|
||||
}
|
||||
|
||||
private static enum Phase {
|
||||
IDLE,
|
||||
FADE_IN,
|
||||
HOLD,
|
||||
FADE_OUT;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.ModParticles;
|
||||
import com.vinlanx.explosionoverhaul.PlayTrackedSoundPacket;
|
||||
import com.vinlanx.explosionoverhaul.client.Blur;
|
||||
import com.vinlanx.explosionoverhaul.client.CameraShakeConcussionEffect;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionWindController;
|
||||
import com.vinlanx.explosionoverhaul.client.GroundDustEffect;
|
||||
import com.vinlanx.explosionoverhaul.client.GroundMistEffect;
|
||||
import com.vinlanx.explosionoverhaul.client.PhysicsBasedExplosionEffect;
|
||||
import com.vinlanx.explosionoverhaul.client.PositionalSoundInstance;
|
||||
import com.vinlanx.explosionoverhaul.client.ShockwaveEffect;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.BlockParticleOption;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.core.particles.SimpleParticleType;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiOverlayEvent;
|
||||
import net.neoforged.neoforge.registries.ForgeRegistries;
|
||||
|
||||
public class ClientEffects {
|
||||
private static float currentShakeIntensity = 0.0f;
|
||||
private static int shakeDurationTicks = 0;
|
||||
private static float currentPushIntensity = 0.0f;
|
||||
private static float lastYawOffset = 0.0f;
|
||||
private static float lastPitchOffset = 0.0f;
|
||||
private static final Random random = new Random();
|
||||
private static final List<PhysicsBasedExplosionEffect> activeExplosions = new ArrayList<PhysicsBasedExplosionEffect>();
|
||||
private static final List<TrackedSound> activeTrackedSounds = new ArrayList<TrackedSound>();
|
||||
private static final List<ShockwaveEffect> activeShockwaves = new ArrayList<ShockwaveEffect>();
|
||||
private static final List<GroundDustEffect> activeDustClouds = new ArrayList<GroundDustEffect>();
|
||||
private static final List<GroundMistEffect> activeMistClouds = new ArrayList<GroundMistEffect>();
|
||||
private static final List<FlashEffect> activeFlashEffects = new ArrayList<FlashEffect>();
|
||||
private static final List<PendingShake> pendingShakes = new ArrayList<PendingShake>();
|
||||
|
||||
public static void addTrackedSound(PlayTrackedSoundPacket msg) {
|
||||
SoundEvent sound = (SoundEvent)ForgeRegistries.SOUND_EVENTS.getValue(msg.getSoundId());
|
||||
if (sound != null) {
|
||||
activeTrackedSounds.add(new TrackedSound(msg.getExplosionPos(), sound, msg.getVolume(), msg.getPitch(), msg.getDelayTicks(), msg.isPlayerInHouse()));
|
||||
}
|
||||
}
|
||||
|
||||
private static Vec3 calculateSoundPosition(Player player, Vec3 explosionPos, boolean isPlayerInHouse) {
|
||||
float FIXED_DISTANCE = 45.0f;
|
||||
Vec3 playerPos = player.m_146892_();
|
||||
Vec3 startPos = isPlayerInHouse ? explosionPos : playerPos;
|
||||
Vec3 endPos = isPlayerInHouse ? playerPos : explosionPos;
|
||||
ClipContext context = new ClipContext(startPos, endPos, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, (Entity)player);
|
||||
BlockHitResult hitResult = player.m_9236_().m_45547_(context);
|
||||
if (hitResult.m_6662_() == HitResult.Type.MISS) {
|
||||
Vec3 direction = explosionPos.m_82546_(playerPos).m_82541_();
|
||||
if (direction.m_82556_() < 0.001) {
|
||||
direction = player.m_20154_();
|
||||
}
|
||||
return playerPos.m_82549_(direction.m_82490_(45.0));
|
||||
}
|
||||
Vec3 hitPos = hitResult.m_82450_();
|
||||
Vec3 rayDir = endPos.m_82546_(startPos).m_82541_();
|
||||
return hitPos.m_82546_(rayDir.m_82490_(0.1));
|
||||
}
|
||||
|
||||
private static void handleTrackedSoundsTick() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.f_91074_ == null || mc.m_91106_() == null) {
|
||||
return;
|
||||
}
|
||||
Iterator<TrackedSound> iterator = activeTrackedSounds.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
TrackedSound tracked = iterator.next();
|
||||
if (tracked.isFinished()) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
tracked.tick((Player)mc.f_91074_, mc.m_91106_(), mc.f_91074_.m_217043_());
|
||||
}
|
||||
}
|
||||
|
||||
public static void triggerLocalCameraShake(float intensity, int durationTicks, float pushIntensity) {
|
||||
if (!((Boolean)Config.CLIENT.enableCameraShake.get()).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
float amplifiedIntensity = intensity * (((Double)Config.CLIENT.cameraShakeAmplifier.get()).floatValue() * 10.0f);
|
||||
float amplifiedPush = 0.0f;
|
||||
if (((Boolean)Config.COMMON.enablePlayerShake.get()).booleanValue()) {
|
||||
amplifiedPush = pushIntensity * (((Double)Config.COMMON.playerShakeAmplifier.get()).floatValue() * 5.0f);
|
||||
}
|
||||
if (amplifiedIntensity > currentShakeIntensity || shakeDurationTicks == 0 || durationTicks > shakeDurationTicks) {
|
||||
currentShakeIntensity = amplifiedIntensity;
|
||||
shakeDurationTicks = durationTicks;
|
||||
currentPushIntensity = amplifiedPush;
|
||||
}
|
||||
}
|
||||
|
||||
public static void triggerDelayedCameraShake(float intensity, int durationTicks, float pushIntensity, int delayTicks) {
|
||||
if (!((Boolean)Config.CLIENT.enableCameraShake.get()).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
if (delayTicks <= 0) {
|
||||
ClientEffects.triggerLocalCameraShake(intensity, durationTicks, pushIntensity);
|
||||
return;
|
||||
}
|
||||
pendingShakes.add(new PendingShake(delayTicks, intensity, durationTicks, pushIntensity));
|
||||
}
|
||||
|
||||
public static void triggerRealisticExplosion(Vec3 position, float power) {
|
||||
activeExplosions.add(new PhysicsBasedExplosionEffect(position, power));
|
||||
}
|
||||
|
||||
public static void addFlashEffect(Vec3 explosionPos, float power) {
|
||||
activeFlashEffects.add(new FlashEffect(explosionPos, power));
|
||||
}
|
||||
|
||||
public static void onClientTick() {
|
||||
if (Minecraft.m_91087_().m_91104_()) {
|
||||
return;
|
||||
}
|
||||
Blur.onClientTick();
|
||||
CameraShakeConcussionEffect.onClientTick();
|
||||
ExplosionWindController.tick();
|
||||
ClientEffects.handleCameraShakeTick();
|
||||
ClientEffects.handlePendingShakesTick();
|
||||
ClientEffects.handleTrackedSoundsTick();
|
||||
activeExplosions.removeIf(effect -> {
|
||||
effect.tick();
|
||||
return effect.isFinished();
|
||||
});
|
||||
activeShockwaves.removeIf(effect -> {
|
||||
effect.tick();
|
||||
return effect.isFinished();
|
||||
});
|
||||
activeDustClouds.removeIf(effect -> {
|
||||
effect.tick();
|
||||
return effect.isFinished();
|
||||
});
|
||||
activeMistClouds.removeIf(effect -> {
|
||||
effect.tick();
|
||||
return effect.isFinished();
|
||||
});
|
||||
activeFlashEffects.removeIf(effect -> effect.isFinished());
|
||||
}
|
||||
|
||||
public static void renderFlash(RenderGuiOverlayEvent.Post event) {
|
||||
if (!((Boolean)Config.CLIENT.enableFlashEffect.get()).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.f_91074_ == null || activeFlashEffects.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
float maxOpacity = 0.0f;
|
||||
for (FlashEffect effect : activeFlashEffects) {
|
||||
float opacity = effect.getCurrentOpacity((Player)mc.f_91074_);
|
||||
if (!(opacity > maxOpacity)) continue;
|
||||
maxOpacity = opacity;
|
||||
}
|
||||
if (maxOpacity <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
int screenWidth = mc.m_91268_().m_85445_();
|
||||
int screenHeight = mc.m_91268_().m_85446_();
|
||||
ResourceLocation flashTexture = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)"textures/effects/flash.png");
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)maxOpacity);
|
||||
guiGraphics.m_280163_(flashTexture, 0, 0, 0.0f, 0.0f, screenWidth, screenHeight, screenWidth, screenHeight);
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f);
|
||||
}
|
||||
|
||||
private static void handlePendingShakesTick() {
|
||||
if (pendingShakes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Iterator<PendingShake> it = pendingShakes.iterator();
|
||||
while (it.hasNext()) {
|
||||
PendingShake ps = it.next();
|
||||
--ps.delayTicks;
|
||||
if (ps.delayTicks > 0) continue;
|
||||
ClientEffects.triggerLocalCameraShake(ps.intensity, ps.durationTicks, ps.pushIntensity);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public static void triggerShockwave(Vec3 position, float power) {
|
||||
activeShockwaves.add(new ShockwaveEffect(position, power));
|
||||
}
|
||||
|
||||
public static void triggerDustCloud(Vec3 position, float power) {
|
||||
if (!((Boolean)Config.CLIENT.enableGroundDustEffect.get()).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
activeDustClouds.add(new GroundDustEffect(position, power));
|
||||
}
|
||||
|
||||
public static void triggerMistCloud(Vec3 position, float power) {
|
||||
if (!((Boolean)Config.CLIENT.enableGroundMistEffect.get()).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
activeMistClouds.add(new GroundMistEffect(position, power));
|
||||
}
|
||||
|
||||
public static void triggerAmbientCaveDust(float power) {
|
||||
int i;
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
LocalPlayer player = mc.f_91074_;
|
||||
ClientLevel level = mc.f_91073_;
|
||||
if (player == null || level == null) {
|
||||
return;
|
||||
}
|
||||
int particleCount = 15 + (int)((double)(power / 10.0f) * 3.5);
|
||||
particleCount = Mth.m_14045_((int)particleCount, (int)10, (int)70);
|
||||
BlockPos playerPos = player.m_20183_();
|
||||
BlockState ceilingState = Blocks.f_50069_.m_49966_();
|
||||
for (i = 3; i < 10; ++i) {
|
||||
BlockState state = level.m_8055_(playerPos.m_6630_(i));
|
||||
if (state.m_60795_()) continue;
|
||||
ceilingState = state;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < particleCount; ++i) {
|
||||
double x = player.m_20185_() + (random.nextDouble() - 0.5) * 16.0;
|
||||
double z = player.m_20189_() + (random.nextDouble() - 0.5) * 16.0;
|
||||
double y = player.m_20186_() + 4.0 + random.nextDouble() * 6.0;
|
||||
level.m_7106_((ParticleOptions)new BlockParticleOption(ParticleTypes.f_123814_, ceilingState), x, y, z, 0.0, -0.15, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleCameraShakeTick() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
LocalPlayer player = mc.f_91074_;
|
||||
if (player == null) {
|
||||
if (shakeDurationTicks > 0 || lastYawOffset != 0.0f || lastPitchOffset != 0.0f) {
|
||||
lastYawOffset = 0.0f;
|
||||
lastPitchOffset = 0.0f;
|
||||
shakeDurationTicks = 0;
|
||||
currentShakeIntensity = 0.0f;
|
||||
currentPushIntensity = 0.0f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
player.m_19884_((double)(-lastYawOffset), (double)(-lastPitchOffset));
|
||||
lastYawOffset = 0.0f;
|
||||
lastPitchOffset = 0.0f;
|
||||
if (shakeDurationTicks > 0) {
|
||||
float progress = (float)shakeDurationTicks / 30.0f;
|
||||
float cameraIntensity = currentShakeIntensity * Mth.m_14031_((float)(progress * (float)Math.PI));
|
||||
float yawChange = (random.nextFloat() - 0.5f) * 2.0f * cameraIntensity;
|
||||
float pitchChange = (random.nextFloat() - 0.5f) * 1.0f * cameraIntensity;
|
||||
player.m_19884_((double)yawChange, (double)pitchChange);
|
||||
lastYawOffset = yawChange;
|
||||
lastPitchOffset = pitchChange;
|
||||
if (currentPushIntensity > 0.0f) {
|
||||
float pushFactor = currentPushIntensity * Mth.m_14031_((float)(progress * (float)Math.PI)) * 0.1f;
|
||||
player.m_5997_((random.nextDouble() - 0.5) * (double)pushFactor, 0.0, (random.nextDouble() - 0.5) * (double)pushFactor);
|
||||
}
|
||||
--shakeDurationTicks;
|
||||
} else {
|
||||
currentShakeIntensity = 0.0f;
|
||||
currentPushIntensity = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public static void triggerLineSparks(Vec3 position, float power) {
|
||||
if (!((Boolean)Config.CLIENT.enableLineSparks.get()).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
ClientLevel level = mc.f_91073_;
|
||||
if (level == null) {
|
||||
return;
|
||||
}
|
||||
double amountMultiplier = (Double)Config.CLIENT.lineSparkAmountMultiplier.get();
|
||||
if (amountMultiplier <= 0.0) {
|
||||
return;
|
||||
}
|
||||
int sparkCount = (int)((double)(power * 15.0f) * amountMultiplier);
|
||||
sparkCount = Mth.m_14045_((int)sparkCount, (int)15, (int)500);
|
||||
for (int i = 0; i < sparkCount; ++i) {
|
||||
Vec3 motion = new Vec3(random.nextDouble() - 0.5, random.nextDouble() - 0.5, random.nextDouble() - 0.5).m_82541_();
|
||||
float powerFraction = power / 100.0f;
|
||||
float force = random.nextFloat() < 0.25f ? Mth.m_14179_((float)powerFraction, (float)0.5f, (float)8.0f) * (0.9f + random.nextFloat() * 0.4f) : Mth.m_14179_((float)powerFraction, (float)0.3f, (float)4.5f) * (0.7f + random.nextFloat() * 0.4f);
|
||||
motion = motion.m_82490_((double)force);
|
||||
level.m_7106_((ParticleOptions)((SimpleParticleType)ModParticles.LINE_SPARK.get()), position.f_82479_, position.f_82480_, position.f_82481_, motion.f_82479_, motion.f_82480_, motion.f_82481_);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TrackedSound {
|
||||
final Vec3 explosionPos;
|
||||
final SoundEvent sound;
|
||||
final float volume;
|
||||
final float pitch;
|
||||
long delayTicks;
|
||||
PositionalSoundInstance soundInstance;
|
||||
boolean started = false;
|
||||
private int updateCooldown = 0;
|
||||
private final boolean isPlayerInHouse;
|
||||
|
||||
TrackedSound(Vec3 explosionPos, SoundEvent sound, float volume, float pitch, long delayTicks, boolean isPlayerInHouse) {
|
||||
this.explosionPos = explosionPos;
|
||||
this.sound = sound;
|
||||
this.volume = volume;
|
||||
this.pitch = pitch;
|
||||
this.delayTicks = delayTicks;
|
||||
this.isPlayerInHouse = isPlayerInHouse;
|
||||
}
|
||||
|
||||
public void tick(Player player, SoundManager soundManager, RandomSource random) {
|
||||
if (this.soundInstance != null && this.soundInstance.m_7801_()) {
|
||||
return;
|
||||
}
|
||||
if (!this.started) {
|
||||
--this.delayTicks;
|
||||
if (this.delayTicks <= 0L) {
|
||||
Vec3 soundPos = ClientEffects.calculateSoundPosition(player, this.explosionPos, this.isPlayerInHouse);
|
||||
this.soundInstance = new PositionalSoundInstance(this.sound, SoundSource.BLOCKS, this.volume, this.pitch, random, soundPos.f_82479_, soundPos.f_82480_, soundPos.f_82481_);
|
||||
soundManager.m_120367_((SoundInstance)this.soundInstance);
|
||||
this.started = true;
|
||||
}
|
||||
} else {
|
||||
--this.updateCooldown;
|
||||
if (this.updateCooldown <= 0) {
|
||||
this.updateCooldown = 10;
|
||||
Vec3 newSoundPos = ClientEffects.calculateSoundPosition(player, this.explosionPos, this.isPlayerInHouse);
|
||||
this.soundInstance.updatePosition(newSoundPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.soundInstance != null && this.soundInstance.m_7801_();
|
||||
}
|
||||
}
|
||||
|
||||
private static class PendingShake {
|
||||
int delayTicks;
|
||||
final float intensity;
|
||||
final int durationTicks;
|
||||
final float pushIntensity;
|
||||
|
||||
PendingShake(int delayTicks, float intensity, int durationTicks, float pushIntensity) {
|
||||
this.delayTicks = delayTicks;
|
||||
this.intensity = intensity;
|
||||
this.durationTicks = durationTicks;
|
||||
this.pushIntensity = pushIntensity;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FlashEffect {
|
||||
final Vec3 explosionPos;
|
||||
final float power;
|
||||
final long startTime;
|
||||
final float maxDurationTicks;
|
||||
final float maxOpacity;
|
||||
final float maxDistance;
|
||||
|
||||
FlashEffect(Vec3 explosionPos, float power) {
|
||||
this.explosionPos = explosionPos;
|
||||
this.power = power;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
this.maxDurationTicks = this.calculateDuration(power) * 20.0f;
|
||||
this.maxOpacity = this.calculateMaxOpacity(power);
|
||||
this.maxDistance = this.calculateMaxDistance(power);
|
||||
}
|
||||
|
||||
private float calculateDuration(float power) {
|
||||
if (power <= 1.0f) {
|
||||
return 0.5f;
|
||||
}
|
||||
if (power <= 5.0f) {
|
||||
return 1.0f;
|
||||
}
|
||||
if (power <= 10.0f) {
|
||||
return 2.5f;
|
||||
}
|
||||
if (power <= 25.0f) {
|
||||
return 3.5f;
|
||||
}
|
||||
return 5.5f;
|
||||
}
|
||||
|
||||
private float calculateMaxDistance(float power) {
|
||||
if (power <= 1.0f) {
|
||||
return 30.0f;
|
||||
}
|
||||
if (power <= 5.0f) {
|
||||
return 30.0f + (power - 1.0f) * 70.0f / 4.0f;
|
||||
}
|
||||
if (power <= 10.0f) {
|
||||
return 100.0f + (power - 5.0f) * 100.0f / 5.0f;
|
||||
}
|
||||
if (power <= 25.0f) {
|
||||
return 200.0f + (power - 10.0f) * 200.0f / 15.0f;
|
||||
}
|
||||
if (power <= 40.0f) {
|
||||
return 400.0f + (power - 25.0f) * 300.0f / 15.0f;
|
||||
}
|
||||
return 700.0f + (power - 40.0f) * 50.0f;
|
||||
}
|
||||
|
||||
private float calculateMaxOpacity(float power) {
|
||||
float baseOpacity = power <= 1.0f ? 0.5f : (power <= 5.0f ? 0.7f : (power <= 10.0f ? 0.9f : 1.0f));
|
||||
return baseOpacity * ((Double)Config.CLIENT.flashMaxOpacity.get()).floatValue();
|
||||
}
|
||||
|
||||
public float getCurrentOpacity(Player player) {
|
||||
long elapsed = System.currentTimeMillis() - this.startTime;
|
||||
float elapsedTicks = (float)elapsed / 50.0f;
|
||||
if (elapsedTicks > this.maxDurationTicks) {
|
||||
return 0.0f;
|
||||
}
|
||||
float progress = elapsedTicks / this.maxDurationTicks;
|
||||
float fadeOpacity = this.maxOpacity * (1.0f - progress * progress);
|
||||
double distance = player.m_146892_().m_82554_(this.explosionPos);
|
||||
float distanceFactor = Math.max(0.0f, 1.0f - (float)distance / this.maxDistance);
|
||||
Vec3 viewVec = player.m_20154_();
|
||||
Vec3 dirToExplosion = this.explosionPos.m_82546_(player.m_146892_()).m_82541_();
|
||||
float dot = (float)viewVec.m_82526_(dirToExplosion);
|
||||
float angleFactor = Math.max(0.0f, dot);
|
||||
if (!this.isVisible(player, this.explosionPos)) {
|
||||
return 0.0f;
|
||||
}
|
||||
return fadeOpacity * distanceFactor * angleFactor;
|
||||
}
|
||||
|
||||
private boolean isVisible(Player player, Vec3 explosionPos) {
|
||||
Vec3 start = player.m_146892_();
|
||||
Vec3 end = explosionPos;
|
||||
ClipContext context = new ClipContext(start, end, ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, (Entity)player);
|
||||
BlockHitResult hit = player.m_9236_().m_45547_(context);
|
||||
if (hit.m_6662_() == HitResult.Type.MISS) {
|
||||
return true;
|
||||
}
|
||||
if (this.power > 10.0f) {
|
||||
int numChecks = Math.max(1, (int)(this.power / 10.0f));
|
||||
for (int i = 1; i <= numChecks; ++i) {
|
||||
Vec3 elevatedStart = start.m_82520_(0.0, (double)(5 * i), 0.0);
|
||||
Vec3 elevatedEnd = end.m_82520_(0.0, (double)(5 * i), 0.0);
|
||||
ClipContext elevatedContext = new ClipContext(elevatedStart, elevatedEnd, ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, (Entity)player);
|
||||
BlockHitResult elevatedHit = player.m_9236_().m_45547_(elevatedContext);
|
||||
if (elevatedHit.m_6662_() != HitResult.Type.MISS) continue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
long elapsed = System.currentTimeMillis() - this.startTime;
|
||||
return (float)elapsed / 50.0f > this.maxDurationTicks;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,663 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.ModSounds;
|
||||
import com.vinlanx.explosionoverhaul.client.Blur;
|
||||
import com.vinlanx.explosionoverhaul.client.CameraShakeConcussionEffect;
|
||||
import com.vinlanx.explosionoverhaul.client.DeafnessConcussionEffect;
|
||||
import com.vinlanx.explosionoverhaul.client.LowPassConcussionEffect;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
|
||||
@Mod.EventBusSubscriber(modid="explosionoverhaul", value={Dist.CLIENT})
|
||||
public class ConcussionAudioEffect {
|
||||
public static boolean debugSendDebugMessage = false;
|
||||
public static boolean TestingHudHeart = true;
|
||||
public static float currentBPM = 23.3f;
|
||||
private static double heartbeatCycleTimer = 0.0;
|
||||
private static float heartbeatVisualPulse = 0.0f;
|
||||
private static float explosionBPMMod = 0.0f;
|
||||
private static float jumpBPMMod = 0.0f;
|
||||
private static boolean wasOnGround = true;
|
||||
private static int idleTicks = 0;
|
||||
private static boolean lubTriggered = false;
|
||||
private static boolean dubTriggered = false;
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase == TickEvent.Phase.END) {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.f_91074_ != null && !mc.f_91074_.m_6084_()) {
|
||||
ConcussionAudioEffect.stopAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopAll() {
|
||||
Blur.stop();
|
||||
DeafnessConcussionEffect.stop();
|
||||
LowPassConcussionEffect.stop();
|
||||
CameraShakeConcussionEffect.stop();
|
||||
}
|
||||
|
||||
public static void start(float power, double distance, boolean hasDirectLineOfSight, boolean explosionInCave) {
|
||||
LocalPlayer player;
|
||||
LocalPlayer player2;
|
||||
LocalPlayer player3;
|
||||
if (!FMLEnvironment.dist.isClient()) {
|
||||
return;
|
||||
}
|
||||
if (!((Boolean)Config.CLIENT.enableConcussion.get()).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc == null || mc.f_91073_ == null || mc.f_91074_ == null) {
|
||||
return;
|
||||
}
|
||||
double rawPercent = ConcussionAudioEffect.computePercent(power, distance, explosionInCave);
|
||||
if (explosionInCave) {
|
||||
rawPercent = Math.min(100.0, rawPercent * 1.5);
|
||||
}
|
||||
double effectivePercent = hasDirectLineOfSight ? rawPercent : ConcussionAudioEffect.applyOcclusion(rawPercent);
|
||||
double maxDistance = ConcussionAudioEffect.computeMaxDistance(power, explosionInCave);
|
||||
if (rawPercent <= 0.0) {
|
||||
LocalPlayer player4 = mc.f_91074_;
|
||||
if (player4 != null && debugSendDebugMessage) {
|
||||
double metersToExplosion = distance;
|
||||
double onePercentDistance = maxDistance * 0.99;
|
||||
String outMessage = String.format("\u041f\u043e\u0437\u0430 \u0437\u043e\u043d\u043e\u044e \u043f\u043e\u0440\u0430\u0437\u043a\u0438. \u0412\u0456\u0434\u0441\u0442\u0430\u043d\u044c \u0434\u043e \u0432\u0438\u0431\u0443\u0445\u0443: %.1f \u043c. 1%% \u043f\u043e\u0447\u0438\u043d\u0430\u0454\u0442\u044c\u0441\u044f \u0437: %.1f \u043c.", metersToExplosion, onePercentDistance);
|
||||
player4.m_5661_((Component)Component.m_237113_((String)outMessage).m_130940_(ChatFormatting.GRAY), false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
double normalized = Math.max(0.0, Math.min(1.0, effectivePercent / 100.0));
|
||||
float intensity = (float)normalized;
|
||||
if (intensity < 0.01f) {
|
||||
return;
|
||||
}
|
||||
double baseSilentSeconds = ConcussionAudioEffect.computeBaseSilentSeconds(effectivePercent, explosionInCave);
|
||||
double intensityPercent = ConcussionAudioEffect.computeBaseIntensityPercent(effectivePercent);
|
||||
double multiplier = ConcussionAudioEffect.computePowerMultiplier(power);
|
||||
double finalSilentSeconds = baseSilentSeconds * multiplier * (Double)Config.CLIENT.concussionDurationMultiplier.get();
|
||||
double lowpassChance = ConcussionAudioEffect.computeLowpassPowerChance(power, explosionInCave) * (Double)Config.CLIENT.concussionChanceMultiplier.get() * (Double)Config.CLIENT.lowPassChanceMultiplier.get();
|
||||
boolean lowpassRoll = ThreadLocalRandom.current().nextDouble() <= lowpassChance;
|
||||
double chance = ConcussionAudioEffect.computePowerChance(power, explosionInCave) * (Double)Config.CLIENT.concussionChanceMultiplier.get() * (Double)Config.CLIENT.deafnessChanceMultiplier.get();
|
||||
boolean roll = ThreadLocalRandom.current().nextDouble() <= chance;
|
||||
boolean anyAudioEffectActive = roll || lowpassRoll;
|
||||
double baseBlurSeconds = ConcussionAudioEffect.computeBaseBlurSilentSeconds(effectivePercent, explosionInCave);
|
||||
double blurMultiplier = ConcussionAudioEffect.computeBlurPowerMultiplier(power);
|
||||
double finalBlurSeconds = baseBlurSeconds * blurMultiplier * (Double)Config.CLIENT.concussionDurationMultiplier.get();
|
||||
boolean lowpassReduced = false;
|
||||
if (!lowpassRoll) {
|
||||
finalBlurSeconds = roll ? finalSilentSeconds : (finalBlurSeconds /= 3.0);
|
||||
lowpassReduced = true;
|
||||
}
|
||||
int blurSeconds = Math.max(1, (int)Math.round(finalBlurSeconds));
|
||||
double blurIntensityPercent = ConcussionAudioEffect.computeBaseBlurIntensityPercent(effectivePercent);
|
||||
float blurIntensity = (float)(blurIntensityPercent / 100.0);
|
||||
double swayIntensityPercent = ConcussionAudioEffect.computeBaseSwayIntensityPercent(effectivePercent) * (Double)Config.CLIENT.cameraSwayIntensity.get();
|
||||
float swayIntensity = (float)(swayIntensityPercent / 100.0);
|
||||
if (rawPercent > 0.0 && blurIntensity >= 0.01f && anyAudioEffectActive) {
|
||||
float addedBPM = 0.0f;
|
||||
if (rawPercent > 80.0) {
|
||||
addedBPM = 60.0f;
|
||||
} else if (rawPercent > 60.0) {
|
||||
addedBPM = 40.0f;
|
||||
} else if (rawPercent > 30.0) {
|
||||
addedBPM = 20.0f;
|
||||
}
|
||||
explosionBPMMod = Math.min(200.0f, explosionBPMMod + addedBPM);
|
||||
try {
|
||||
LocalPlayer player5;
|
||||
Blur.start(blurSeconds, blurIntensity);
|
||||
if (((Boolean)Config.CLIENT.enableCameraSway.get()).booleanValue()) {
|
||||
CameraShakeConcussionEffect.start(blurSeconds, swayIntensity);
|
||||
}
|
||||
if (debugSendDebugMessage && (player5 = mc.f_91074_) != null) {
|
||||
String reductionInfo = lowpassReduced ? " [LowPass reduced /3]" : "";
|
||||
String blurMsg = String.format("Blur & Sway %.1f m \u2014 activated (Blur: %.2f, Sway: %.2f, Time: %ds%s)", distance, Float.valueOf(blurIntensity), Float.valueOf(swayIntensity), blurSeconds, reductionInfo);
|
||||
player5.m_5661_((Component)Component.m_237113_((String)blurMsg).m_130940_(ChatFormatting.BLUE), false);
|
||||
}
|
||||
}
|
||||
catch (Throwable player5) {}
|
||||
} else if (debugSendDebugMessage && (player3 = mc.f_91074_) != null) {
|
||||
String reason = !anyAudioEffectActive ? "no audio effects" : "out of range";
|
||||
String blurMsg = String.format("Blur %.1f m \u2014 not activated (%s)", distance, reason);
|
||||
player3.m_5661_((Component)Component.m_237113_((String)blurMsg).m_130940_(ChatFormatting.GRAY), false);
|
||||
}
|
||||
int lowpassSeconds = blurSeconds;
|
||||
double lowpassIntensityPercent = ConcussionAudioEffect.computeBaseLowpassIntensityPercent(effectivePercent);
|
||||
float lowpassIntensity = (float)(lowpassIntensityPercent / 100.0);
|
||||
if (lowpassIntensity < 0.01f) {
|
||||
lowpassIntensity = 0.01f;
|
||||
}
|
||||
String lpVisibility = hasDirectLineOfSight ? "\u043f\u0440\u044f\u043c\u0430 \u0432\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c" : "\u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0430";
|
||||
int lowpassIntensityRound = (int)Math.round(lowpassIntensityPercent);
|
||||
if (((Boolean)Config.CLIENT.enableLowPass.get()).booleanValue() && rawPercent > 0.0 && lowpassIntensity >= 0.01f && (lowpassRoll || LowPassConcussionEffect.isActive())) {
|
||||
try {
|
||||
LocalPlayer player6;
|
||||
float finalLpIntensity = lowpassRoll ? lowpassIntensity : 0.0f;
|
||||
int finalLpRound = lowpassRoll ? lowpassIntensityRound : 0;
|
||||
LowPassConcussionEffect.start(lowpassSeconds, finalLpIntensity, effectivePercent, lpVisibility, finalLpRound);
|
||||
if (debugSendDebugMessage && (player6 = mc.f_91074_) != null) {
|
||||
String status = lowpassRoll ? "activated" : "refreshed";
|
||||
String lpMsg = String.format("Low pass %.1f m \u2014 %s (intensity=%.2f chance=%.1f%%)", distance, status, Float.valueOf(finalLpIntensity), lowpassChance * 100.0);
|
||||
player6.m_5661_((Component)Component.m_237113_((String)lpMsg).m_130940_(ChatFormatting.DARK_GREEN), false);
|
||||
}
|
||||
}
|
||||
catch (Throwable finalLpIntensity) {}
|
||||
} else if (debugSendDebugMessage && (player2 = mc.f_91074_) != null) {
|
||||
String reason = rawPercent <= 0.0 || lowpassIntensity < 0.01f ? "out of range" : "chance fail";
|
||||
String lpMsg = String.format("Low pass %.1f m \u2014 not activated (%s)", distance, reason);
|
||||
player2.m_5661_((Component)Component.m_237113_((String)lpMsg).m_130940_(ChatFormatting.GRAY), false);
|
||||
}
|
||||
if (debugSendDebugMessage) {
|
||||
ConcussionAudioEffect.sendDebugMessage(mc, effectivePercent, rawPercent, hasDirectLineOfSight, distance, maxDistance);
|
||||
}
|
||||
if (debugSendDebugMessage && (player = mc.f_91074_) != null) {
|
||||
Object visibility = hasDirectLineOfSight ? "\u043f\u0440\u044f\u043c\u0430 \u0432\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c" : "\u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0430";
|
||||
visibility = (String)visibility + (explosionInCave ? " | \u0432\u0438\u0431\u0443\u0445 \u0443 \u043f\u0435\u0447\u0435\u0440\u0456" : " | \u0432\u0438\u0431\u0443\u0445 \u043d\u0435 \u0432 \u043f\u0435\u0447\u0435\u0440\u0456");
|
||||
visibility = (String)visibility + String.format(" | \u0444\u0456\u043d\u0430\u043b\u044c\u043d\u0438\u0439 %%: %.1f%%", effectivePercent);
|
||||
player.m_5661_((Component)Component.m_237113_((String)visibility).m_130940_(ChatFormatting.GRAY), false);
|
||||
String chanceMsg = String.format("\u0428\u0430\u043d\u0441 \u043a\u043e\u043d\u0442\u0443\u0437\u0456\u0457: %.1f%%", chance * 100.0);
|
||||
player.m_5661_((Component)Component.m_237113_((String)chanceMsg).m_130940_(ChatFormatting.YELLOW), false);
|
||||
double maxDistanceNormal = ConcussionAudioEffect.computeMaxDistance(power, false);
|
||||
double maxDistanceUsed = ConcussionAudioEffect.computeMaxDistance(power, explosionInCave);
|
||||
String distMsg = String.format("\u041c\u0430\u043a\u0441 \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0456\u044f (\u0437\u0432\u0438\u0447\u0430\u0439\u043d\u0430): %.1f \u043c | (\u0432 \u043f\u0435\u0447\u0435\u0440\u0456): %.1f \u043c | \u0412\u0456\u0434\u0441\u0442\u0430\u043d\u044c \u0434\u043e \u0432\u0438\u0431\u0443\u0445\u0443: %.1f \u043c", maxDistanceNormal, maxDistanceUsed, distance);
|
||||
player.m_5661_((Component)Component.m_237113_((String)distMsg).m_130940_(ChatFormatting.GRAY), false);
|
||||
double baseSilentNormal = ConcussionAudioEffect.computeBaseSilentSeconds(effectivePercent, false);
|
||||
double baseSilentCave = ConcussionAudioEffect.computeBaseSilentSeconds(effectivePercent, true);
|
||||
String silentMsg = String.format("\u0427\u0430\u0441 \u0441\u043a\u0440\u0443\u0447\u0443\u0432\u0430\u043d\u043d\u044f (\u0437\u0432\u0438\u0447\u0430\u0439\u043d\u0438\u0439): %.1fs | (\u0432 \u043f\u0435\u0447\u0435\u0440\u0456): %.1fs | \u0412\u0418\u041a\u041e\u0420\u0418\u0421\u0422\u0410\u041d\u041e: %.1fs", baseSilentNormal, baseSilentCave, baseSilentSeconds * multiplier);
|
||||
player.m_5661_((Component)Component.m_237113_((String)silentMsg).m_130940_(ChatFormatting.GRAY), false);
|
||||
if (roll) {
|
||||
String deafnessMsg = String.format("Deafness %.1f m \u2014 activated (intensity=%.1f%% chance=%.1f%%)", distance, intensityPercent, chance * 100.0);
|
||||
player.m_5661_((Component)Component.m_237113_((String)deafnessMsg).m_130940_(ChatFormatting.RED), false);
|
||||
} else {
|
||||
String deafnessMsg = String.format("Deafness %.1f m \u2014 not activated (chance)", distance);
|
||||
player.m_5661_((Component)Component.m_237113_((String)deafnessMsg).m_130940_(ChatFormatting.GRAY), false);
|
||||
}
|
||||
}
|
||||
if (!roll) {
|
||||
return;
|
||||
}
|
||||
if (!((Boolean)Config.CLIENT.enableDeafness.get()).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
int intensityRound = (int)Math.round(intensityPercent);
|
||||
String visibility = hasDirectLineOfSight ? "\u043f\u0440\u044f\u043c\u0430 \u0432\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c" : "\u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0430";
|
||||
float intensityFromIntensityPercent = (float)(intensityPercent / 100.0);
|
||||
DeafnessConcussionEffect.start(intensityFromIntensityPercent, (float)finalSilentSeconds, effectivePercent, visibility, intensityRound);
|
||||
}
|
||||
|
||||
private static double computePercent(float power, double distance, boolean explosionInCave) {
|
||||
double maxDistance = ConcussionAudioEffect.computeMaxDistance(power, explosionInCave);
|
||||
if (maxDistance <= 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
double normalized = 1.0 - Math.max(0.0, distance) / maxDistance;
|
||||
return Math.max(0.0, Math.min(1.0, normalized)) * 100.0;
|
||||
}
|
||||
|
||||
private static double computeMaxDistance(float power, boolean explosionInCave) {
|
||||
double[][] points = explosionInCave ? new double[][]{{1.0, 5.0}, {3.0, 10.0}, {10.0, 50.0}, {25.0, 90.0}, {50.0, 150.0}, {80.0, 200.0}, {120.0, 200.0}} : new double[][]{{1.0, 2.0}, {3.0, 5.0}, {10.0, 30.0}, {25.0, 70.0}, {50.0, 100.0}, {80.0, 150.0}, {120.0, 200.0}};
|
||||
double clampedPower = Math.max(points[0][0], Math.min(points[points.length - 1][0], (double)power));
|
||||
for (int i = 1; i < points.length; ++i) {
|
||||
double lowerP = points[i - 1][0];
|
||||
double upperP = points[i][0];
|
||||
if (!(clampedPower <= upperP)) continue;
|
||||
double lowerD = points[i - 1][1];
|
||||
double upperD = points[i][1];
|
||||
double t = (clampedPower - lowerP) / (upperP - lowerP);
|
||||
return lowerD + (upperD - lowerD) * t;
|
||||
}
|
||||
return points[points.length - 1][1];
|
||||
}
|
||||
|
||||
private static double applyOcclusion(double percent) {
|
||||
if (percent >= 80.0) {
|
||||
return percent / 1.2;
|
||||
}
|
||||
if (percent >= 60.0) {
|
||||
return percent / 1.4;
|
||||
}
|
||||
if (percent >= 40.0) {
|
||||
return percent / 1.6;
|
||||
}
|
||||
if (percent >= 20.0) {
|
||||
return percent / 3.0;
|
||||
}
|
||||
if (percent >= 1.0) {
|
||||
return 0.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
private static void sendDebugMessage(Minecraft mc, double effectivePercent, double rawPercent, boolean hasDirectLineOfSight, double distance, double maxDistance) {
|
||||
LocalPlayer player = mc.f_91074_;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
double clamped = Math.max(0.0, Math.min(100.0, effectivePercent));
|
||||
if (rawPercent <= 0.0) {
|
||||
double metersToExplosion = distance;
|
||||
double onePercentDistance = maxDistance * 0.99;
|
||||
String outMessage = String.format("\u041f\u043e\u0437\u0430 \u0437\u043e\u043d\u043e\u044e \u043f\u043e\u0440\u0430\u0437\u043a\u0438. \u0412\u0456\u0434\u0441\u0442\u0430\u043d\u044c \u0434\u043e \u0432\u0438\u0431\u0443\u0445\u0443: %.1f \u043c. 1%% \u043f\u043e\u0447\u0438\u043d\u0430\u0454\u0442\u044c\u0441\u044f \u0437: %.1f \u043c.", metersToExplosion, onePercentDistance);
|
||||
player.m_5661_((Component)Component.m_237113_((String)outMessage).m_130940_(ChatFormatting.GRAY), false);
|
||||
return;
|
||||
}
|
||||
ChatFormatting color = ConcussionAudioEffect.pickColor(clamped);
|
||||
String visibility = hasDirectLineOfSight ? "\u043f\u0440\u044f\u043c\u0430 \u0432\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c" : "\u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0430";
|
||||
String message = String.format("\u041f\u043e\u0442\u0443\u0436\u043d\u0456\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0443\u0437\u0456\u0457 %.1f%% (%s)", clamped, visibility);
|
||||
player.m_5661_((Component)Component.m_237113_((String)message).m_130940_(color), false);
|
||||
if (!hasDirectLineOfSight && rawPercent > 0.0) {
|
||||
String rawMessage = String.format("(\u0434\u043e \u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0438: %.1f%%)", Math.max(0.0, Math.min(100.0, rawPercent)));
|
||||
player.m_5661_((Component)Component.m_237113_((String)rawMessage).m_130940_(ChatFormatting.GRAY), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static ChatFormatting pickColor(double percent) {
|
||||
if (percent >= 80.0) {
|
||||
return ChatFormatting.RED;
|
||||
}
|
||||
if (percent >= 60.0) {
|
||||
return ChatFormatting.GOLD;
|
||||
}
|
||||
if (percent >= 40.0) {
|
||||
return ChatFormatting.YELLOW;
|
||||
}
|
||||
if (percent >= 20.0) {
|
||||
return ChatFormatting.AQUA;
|
||||
}
|
||||
if (percent > 0.0) {
|
||||
return ChatFormatting.BLUE;
|
||||
}
|
||||
return ChatFormatting.GRAY;
|
||||
}
|
||||
|
||||
private static double computeBaseSilentSeconds(double effectivePercent, boolean explosionInCave) {
|
||||
if (!explosionInCave) {
|
||||
if (effectivePercent <= 40.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (effectivePercent > 80.0) {
|
||||
double t = (effectivePercent - 80.0) / 20.0;
|
||||
return 4.0 + 1.0 * t;
|
||||
}
|
||||
if (effectivePercent > 60.0) {
|
||||
double t = (effectivePercent - 60.0) / 20.0;
|
||||
return 2.0 + 2.0 * t;
|
||||
}
|
||||
double t = (effectivePercent - 40.0) / 20.0;
|
||||
return 1.0 + 1.0 * t;
|
||||
}
|
||||
if (effectivePercent <= 20.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (effectivePercent > 80.0) {
|
||||
double t = (effectivePercent - 80.0) / 20.0;
|
||||
return 7.0 + 3.0 * t;
|
||||
}
|
||||
if (effectivePercent > 60.0) {
|
||||
double t = (effectivePercent - 60.0) / 20.0;
|
||||
return 4.0 + 1.0 * t;
|
||||
}
|
||||
double t = (effectivePercent - 20.0) / 40.0;
|
||||
if (effectivePercent <= 40.0) {
|
||||
double tt = (effectivePercent - 20.0) / 20.0;
|
||||
return 2.0 + 1.0 * tt;
|
||||
}
|
||||
double tt = (effectivePercent - 40.0) / 20.0;
|
||||
return 2.0 + 1.0 * tt;
|
||||
}
|
||||
|
||||
private static double computeBaseIntensityPercent(double effectivePercent) {
|
||||
if (effectivePercent <= 60.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (effectivePercent <= 70.0) {
|
||||
double t = (effectivePercent - 60.0) / 10.0;
|
||||
return 0.0 + 60.0 * t;
|
||||
}
|
||||
if (effectivePercent <= 85.0) {
|
||||
double t = (effectivePercent - 70.0) / 15.0;
|
||||
return 60.0 + 20.0 * t;
|
||||
}
|
||||
if (effectivePercent <= 90.0) {
|
||||
double t = (effectivePercent - 85.0) / 5.0;
|
||||
return 80.0 + 20.0 * t;
|
||||
}
|
||||
return 100.0;
|
||||
}
|
||||
|
||||
private static double computePowerMultiplier(double power) {
|
||||
double[][] points = new double[][]{{2.0, 1.0}, {5.0, 1.2}, {6.0, 1.4}, {12.0, 1.8}, {13.0, 2.0}, {22.0, 2.3}, {23.0, 2.7}, {50.0, 3.0}, {51.0, 3.2}, {80.0, 5.0}, {120.0, 7.0}};
|
||||
double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power));
|
||||
for (int i = 1; i < points.length; ++i) {
|
||||
double lowerP = points[i - 1][0];
|
||||
double upperP = points[i][0];
|
||||
if (!(clamped <= upperP)) continue;
|
||||
double lowerM = points[i - 1][1];
|
||||
double upperM = points[i][1];
|
||||
double t = (clamped - lowerP) / (upperP - lowerP);
|
||||
return lowerM + (upperM - lowerM) * t;
|
||||
}
|
||||
return points[points.length - 1][1];
|
||||
}
|
||||
|
||||
private static double computePowerChance(double power, boolean explosionInCave) {
|
||||
double[][] points = explosionInCave ? new double[][]{{1.0, 0.25}, {2.0, 0.3}, {3.0, 0.35}, {5.0, 0.4}, {6.0, 0.5}, {10.0, 0.75}, {15.0, 0.9}, {20.0, 1.0}, {120.0, 1.0}} : new double[][]{{1.0, 0.15}, {2.0, 0.15}, {3.0, 0.175}, {5.0, 0.215}, {6.0, 0.225}, {10.0, 0.225}, {11.0, 0.35}, {25.0, 0.4}, {26.0, 0.5}, {34.0, 0.75}, {42.0, 0.9}, {50.0, 1.0}, {120.0, 1.0}};
|
||||
double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power));
|
||||
for (int i = 1; i < points.length; ++i) {
|
||||
double lowerP = points[i - 1][0];
|
||||
double upperP = points[i][0];
|
||||
if (!(clamped <= upperP)) continue;
|
||||
double lowerC = points[i - 1][1];
|
||||
double upperC = points[i][1];
|
||||
double t = (clamped - lowerP) / (upperP - lowerP);
|
||||
return lowerC + (upperC - lowerC) * t;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
private static double computeBaseBlurSilentSeconds(double effectivePercent, boolean explosionInCave) {
|
||||
if (!explosionInCave) {
|
||||
if (effectivePercent <= 40.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (effectivePercent > 80.0) {
|
||||
double t = (effectivePercent - 80.0) / 20.0;
|
||||
return 6.0 + 2.0 * t;
|
||||
}
|
||||
if (effectivePercent > 60.0) {
|
||||
double t = (effectivePercent - 60.0) / 20.0;
|
||||
return 2.0 + 4.0 * t;
|
||||
}
|
||||
double t = (effectivePercent - 40.0) / 20.0;
|
||||
return 0.0 + 2.0 * t;
|
||||
}
|
||||
if (effectivePercent <= 20.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (effectivePercent > 80.0) {
|
||||
double t = (effectivePercent - 80.0) / 20.0;
|
||||
return 12.0 + 6.0 * t;
|
||||
}
|
||||
if (effectivePercent > 60.0) {
|
||||
double t = (effectivePercent - 60.0) / 20.0;
|
||||
return 6.0 + 2.0 * t;
|
||||
}
|
||||
if (effectivePercent <= 40.0) {
|
||||
double tt = (effectivePercent - 20.0) / 20.0;
|
||||
return 2.0 + 2.0 * Math.max(0.0, Math.min(1.0, tt));
|
||||
}
|
||||
double tt = (effectivePercent - 40.0) / 20.0;
|
||||
return 2.0 + 2.0 * Math.max(0.0, Math.min(1.0, tt));
|
||||
}
|
||||
|
||||
private static double computeBaseBlurIntensityPercent(double effectivePercent) {
|
||||
if (effectivePercent < 60.0) {
|
||||
return 0.0;
|
||||
}
|
||||
double t = (effectivePercent - 60.0) / 40.0;
|
||||
return 1.0 + 49.0 * t;
|
||||
}
|
||||
|
||||
private static double computeBaseSwayIntensityPercent(double effectivePercent) {
|
||||
if (effectivePercent < 50.0) {
|
||||
return 0.0;
|
||||
}
|
||||
double t = (effectivePercent - 50.0) / 50.0;
|
||||
return 100.0 * t;
|
||||
}
|
||||
|
||||
private static double computeBlurPowerMultiplier(double power) {
|
||||
double[][] points = new double[][]{{2.0, 1.0}, {5.0, 1.2}, {6.0, 1.4}, {12.0, 1.8}, {13.0, 2.0}, {22.0, 2.3}, {23.0, 2.7}, {50.0, 3.0}, {51.0, 3.2}, {80.0, 5.0}, {120.0, 7.0}};
|
||||
double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power));
|
||||
for (int i = 1; i < points.length; ++i) {
|
||||
double lowerP = points[i - 1][0];
|
||||
double upperP = points[i][0];
|
||||
if (!(clamped <= upperP)) continue;
|
||||
double lowerM = points[i - 1][1];
|
||||
double upperM = points[i][1];
|
||||
double t = (clamped - lowerP) / (upperP - lowerP);
|
||||
return lowerM + (upperM - lowerM) * t;
|
||||
}
|
||||
return points[points.length - 1][1];
|
||||
}
|
||||
|
||||
public static void renderHeartbeatHUD(GuiGraphics ctx) {
|
||||
if (!((Boolean)Config.CLIENT.showHeartbeatHUD.get()).booleanValue() || !Blur.isActive()) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.f_91074_ == null) {
|
||||
return;
|
||||
}
|
||||
float bps = currentBPM / 60.0f;
|
||||
String text = String.format("%.2f bps (%.1f BPM)", Float.valueOf(bps), Float.valueOf(currentBPM));
|
||||
int x = ctx.m_280182_() - 10;
|
||||
int y = 10;
|
||||
int color = -65536;
|
||||
if (currentBPM < 30.0f) {
|
||||
color = -11141291;
|
||||
} else if (currentBPM < 50.0f) {
|
||||
color = -171;
|
||||
}
|
||||
ctx.m_280056_(mc.f_91062_, text, x - mc.f_91062_.m_92895_(text), y, color, false);
|
||||
}
|
||||
|
||||
public static float getCurrentHeartbeatVisual() {
|
||||
return heartbeatVisualPulse;
|
||||
}
|
||||
|
||||
public static void updateHeartbeat(LocalPlayer player, float blurIntensity) {
|
||||
float healthPercent;
|
||||
boolean isMoving;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
if (!Blur.isActive()) {
|
||||
explosionBPMMod *= 0.98f;
|
||||
jumpBPMMod *= 0.98f;
|
||||
if ((currentBPM += (23.3f - currentBPM) * 0.05f) < 24.0f && explosionBPMMod < 0.1f && jumpBPMMod < 0.1f) {
|
||||
currentBPM = 23.3f;
|
||||
explosionBPMMod = 0.0f;
|
||||
jumpBPMMod = 0.0f;
|
||||
heartbeatVisualPulse = 0.0f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
float baseBPM = 23.3f;
|
||||
boolean bl = isMoving = player.m_20184_().m_165925_() > 0.001;
|
||||
if (isMoving) {
|
||||
if (player.m_20142_()) {
|
||||
baseBPM = 50.0f;
|
||||
if (!player.m_20096_()) {
|
||||
baseBPM = 60.0f;
|
||||
}
|
||||
} else {
|
||||
baseBPM = 35.0f;
|
||||
}
|
||||
}
|
||||
if ((healthPercent = player.m_21223_() / player.m_21233_()) < 0.1f) {
|
||||
baseBPM += 63.3f;
|
||||
} else if (healthPercent < 0.3f) {
|
||||
baseBPM += 43.3f;
|
||||
}
|
||||
if (!player.m_20096_() && wasOnGround && isMoving) {
|
||||
jumpBPMMod = Math.min(13.3f, jumpBPMMod + 3.3f);
|
||||
}
|
||||
wasOnGround = player.m_20096_();
|
||||
jumpBPMMod *= 0.99f;
|
||||
explosionBPMMod *= 0.995f;
|
||||
if (player.f_19789_ > 3.0f) {
|
||||
baseBPM += Math.min(16.6f, player.f_19789_ * 1.6f);
|
||||
}
|
||||
if (player.m_20146_() <= 0) {
|
||||
baseBPM += 5.0f;
|
||||
}
|
||||
if (player.m_6047_()) {
|
||||
baseBPM -= 3.3f;
|
||||
}
|
||||
if (!isMoving) {
|
||||
if (++idleTicks >= 60) {
|
||||
baseBPM -= 1.6f;
|
||||
idleTicks = 0;
|
||||
}
|
||||
} else {
|
||||
idleTicks = 0;
|
||||
}
|
||||
float finalTarget = baseBPM + jumpBPMMod + explosionBPMMod;
|
||||
if ((finalTarget = Math.max(20.0f, Math.min(130.0f, finalTarget))) > currentBPM) {
|
||||
float rampSpeed = explosionBPMMod > 5.0f || Blur.isActive() ? 0.4f : 0.15f;
|
||||
currentBPM += (finalTarget - currentBPM) * rampSpeed;
|
||||
} else {
|
||||
currentBPM += (finalTarget - currentBPM) * 0.04f;
|
||||
}
|
||||
double cycleSeconds = 60.0 / (double)Math.max(5.0f, currentBPM);
|
||||
heartbeatCycleTimer += 0.05;
|
||||
if (heartbeatCycleTimer >= cycleSeconds) {
|
||||
heartbeatCycleTimer -= cycleSeconds;
|
||||
lubTriggered = false;
|
||||
dubTriggered = false;
|
||||
}
|
||||
double t = heartbeatCycleTimer;
|
||||
float pulse = 0.0f;
|
||||
double lubEnd = cycleSeconds * 0.35;
|
||||
double pause1End = cycleSeconds * 0.45;
|
||||
double dubEnd = cycleSeconds * 0.7;
|
||||
if (t < lubEnd) {
|
||||
s = (float)Math.sin(t / lubEnd * Math.PI);
|
||||
pulse = (float)Math.pow(s, 1.2);
|
||||
if (!lubTriggered) {
|
||||
lubTriggered = true;
|
||||
if (blurIntensity >= 0.1f && ((Boolean)Config.CLIENT.enableHeartbeatPulse.get()).booleanValue()) {
|
||||
try {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc != null) {
|
||||
mc.m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.HEART_LAB.get()), (float)1.0f, (float)100.0f));
|
||||
}
|
||||
}
|
||||
catch (Throwable mc) {}
|
||||
}
|
||||
}
|
||||
} else if (t > pause1End && t < dubEnd) {
|
||||
s = (float)Math.sin((t - pause1End) / (dubEnd - pause1End) * Math.PI);
|
||||
pulse = (float)Math.pow(s, 1.2) * 0.7f;
|
||||
if (!dubTriggered) {
|
||||
dubTriggered = true;
|
||||
if (blurIntensity >= 0.1f && ((Boolean)Config.CLIENT.enableHeartbeatPulse.get()).booleanValue()) {
|
||||
try {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc != null) {
|
||||
mc.m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.HEART_DAB.get()), (float)1.0f, (float)100.0f));
|
||||
}
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
// empty catch block
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((healthPercent < 0.05f || explosionBPMMod > 80.0f && t < 2.0) && ThreadLocalRandom.current().nextDouble() < 0.03) {
|
||||
heartbeatCycleTimer += 0.08;
|
||||
}
|
||||
float pulseScale = 0.3f + blurIntensity * 1.5f;
|
||||
heartbeatVisualPulse = pulse * pulseScale;
|
||||
}
|
||||
|
||||
private static double computeBaseLowpassSilentSeconds(double effectivePercent, boolean explosionInCave) {
|
||||
if (!explosionInCave) {
|
||||
if (effectivePercent <= 40.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (effectivePercent > 80.0) {
|
||||
double t = (effectivePercent - 80.0) / 20.0;
|
||||
return 8.0 + 2.0 * t;
|
||||
}
|
||||
if (effectivePercent > 60.0) {
|
||||
double t = (effectivePercent - 60.0) / 20.0;
|
||||
return 4.0 + 4.0 * t;
|
||||
}
|
||||
double t = (effectivePercent - 40.0) / 20.0;
|
||||
return 2.0 + 2.0 * t;
|
||||
}
|
||||
if (effectivePercent <= 20.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (effectivePercent > 80.0) {
|
||||
double t = (effectivePercent - 80.0) / 20.0;
|
||||
return 14.0 + 6.0 * t;
|
||||
}
|
||||
if (effectivePercent > 60.0) {
|
||||
double t = (effectivePercent - 60.0) / 20.0;
|
||||
return 8.0 + 2.0 * t;
|
||||
}
|
||||
if (effectivePercent <= 40.0) {
|
||||
double tt = (effectivePercent - 20.0) / 20.0;
|
||||
return 4.0 + 2.0 * Math.max(0.0, Math.min(1.0, tt));
|
||||
}
|
||||
double tt = (effectivePercent - 40.0) / 20.0;
|
||||
return 4.0 + 2.0 * Math.max(0.0, Math.min(1.0, tt));
|
||||
}
|
||||
|
||||
private static double computeBaseLowpassIntensityPercent(double effectivePercent) {
|
||||
if (effectivePercent <= 40.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (effectivePercent <= 50.0) {
|
||||
double t = (effectivePercent - 40.0) / 10.0;
|
||||
return 0.0 + 70.0 * t;
|
||||
}
|
||||
if (effectivePercent <= 70.0) {
|
||||
double t = (effectivePercent - 50.0) / 20.0;
|
||||
return 70.0 + 30.0 * t;
|
||||
}
|
||||
return 100.0;
|
||||
}
|
||||
|
||||
private static double computeLowpassPowerMultiplier(double power) {
|
||||
double[][] points = new double[][]{{2.0, 1.0}, {5.0, 1.2}, {6.0, 1.4}, {12.0, 1.8}, {13.0, 2.0}, {22.0, 2.3}, {23.0, 2.7}, {50.0, 3.0}, {51.0, 3.2}, {80.0, 5.0}, {120.0, 7.0}};
|
||||
double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power));
|
||||
for (int i = 1; i < points.length; ++i) {
|
||||
double lowerP = points[i - 1][0];
|
||||
double upperP = points[i][0];
|
||||
if (!(clamped <= upperP)) continue;
|
||||
double lowerM = points[i - 1][1];
|
||||
double upperM = points[i][1];
|
||||
double t = (clamped - lowerP) / (upperP - lowerP);
|
||||
return lowerM + (upperM - lowerM) * t;
|
||||
}
|
||||
return points[points.length - 1][1];
|
||||
}
|
||||
|
||||
private static double computeLowpassPowerChance(double power, boolean explosionInCave) {
|
||||
double[][] points = explosionInCave ? new double[][]{{1.0, 0.5}, {2.0, 0.6}, {3.0, 0.7}, {5.0, 0.8}, {6.0, 0.95}, {120.0, 1.0}} : new double[][]{{1.0, 0.3}, {2.0, 0.3}, {3.0, 0.35}, {5.0, 0.43}, {6.0, 0.45}, {10.0, 0.45}, {11.0, 0.7}, {25.0, 0.8}, {26.0, 1.0}, {120.0, 1.0}};
|
||||
double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power));
|
||||
for (int i = 1; i < points.length; ++i) {
|
||||
double lowerP = points[i - 1][0];
|
||||
double upperP = points[i][0];
|
||||
if (!(clamped <= upperP)) continue;
|
||||
double lowerC = points[i - 1][1];
|
||||
double upperC = points[i][1];
|
||||
double t = (clamped - lowerP) / (upperP - lowerP);
|
||||
return lowerC + (upperC - lowerC) * t;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.ModSounds;
|
||||
import com.vinlanx.explosionoverhaul.client.Blur;
|
||||
import com.vinlanx.explosionoverhaul.client.DeafnessConcussionEffect;
|
||||
import com.vinlanx.explosionoverhaul.client.FadingMusicInstance;
|
||||
import com.vinlanx.explosionoverhaul.client.LowPassConcussionEffect;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
|
||||
@OnlyIn(value=Dist.CLIENT)
|
||||
@Mod.EventBusSubscriber(modid="explosionoverhaul", value={Dist.CLIENT})
|
||||
public class ConcussionSoundManager {
|
||||
private static FadingMusicInstance currentLowSound = null;
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase != TickEvent.Phase.END) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.f_91073_ == null || mc.f_91074_ == null) {
|
||||
if (currentLowSound != null) {
|
||||
mc.m_91106_().m_120399_((SoundInstance)currentLowSound);
|
||||
currentLowSound = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mc.m_91104_()) {
|
||||
return;
|
||||
}
|
||||
boolean deafness = DeafnessConcussionEffect.isActive();
|
||||
boolean lowpass = LowPassConcussionEffect.isActive();
|
||||
boolean blur = Blur.isActive();
|
||||
float targetVolume = 0.0f;
|
||||
if (blur) {
|
||||
if (deafness) {
|
||||
targetVolume = 1.0f;
|
||||
} else if (lowpass) {
|
||||
targetVolume = 0.4f;
|
||||
}
|
||||
}
|
||||
if (targetVolume > 0.0f) {
|
||||
if (currentLowSound == null || !mc.m_91106_().m_120403_((SoundInstance)currentLowSound)) {
|
||||
currentLowSound = new FadingMusicInstance((SoundEvent)ModSounds.LOW_SOUND.get(), 0.01f, SoundSource.MASTER);
|
||||
currentLowSound.fadeTo(targetVolume, 1.0f);
|
||||
mc.m_91106_().m_120367_((SoundInstance)currentLowSound);
|
||||
} else if (Math.abs(currentLowSound.getCurrentVolume() - targetVolume) > 0.01f && !currentLowSound.hasFinishedFading()) {
|
||||
currentLowSound.fadeTo(targetVolume, 0.5f);
|
||||
}
|
||||
} else if (currentLowSound != null && mc.m_91106_().m_120403_((SoundInstance)currentLowSound) && !currentLowSound.hasFinishedFading()) {
|
||||
currentLowSound.fadeOutAndStop(1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.CustomGlowParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionTextureManager;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionWindController;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.ParticleRenderType;
|
||||
import net.minecraft.client.particle.TextureSheetParticle;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Quaternionfc;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class CustomGlowParticle
|
||||
extends TextureSheetParticle {
|
||||
private final float power;
|
||||
private final float initialQuadSize;
|
||||
private final int animationDuration;
|
||||
private final int animationType;
|
||||
private final float centerY;
|
||||
private final float maxRadius;
|
||||
private float currentHeightPercent;
|
||||
private final int peakFireEndTick;
|
||||
private final int fireTransitionEndTick;
|
||||
private final int smokeStartTick;
|
||||
private static final int GLOW_FRAME_COUNT = 239;
|
||||
private static final int SGLOW_FRAME_COUNT = 224;
|
||||
private static final int FRAMES_PER_SHEET = 64;
|
||||
private static final int FRAMES_PER_ROW = 8;
|
||||
private int baseSheetIndex;
|
||||
private int baseFrameOnSheet;
|
||||
private int emissiveSheetIndex;
|
||||
private int emissiveFrameOnSheet;
|
||||
|
||||
public CustomGlowParticle(ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed, CustomGlowParticleOptions options) {
|
||||
super(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed);
|
||||
int fadeOutDurationTicks;
|
||||
this.f_172258_ = 0.98f;
|
||||
this.f_107226_ = 0.0f;
|
||||
this.f_107215_ = pXSpeed;
|
||||
this.f_107216_ = pYSpeed;
|
||||
this.f_107217_ = pZSpeed;
|
||||
this.power = options.getPower();
|
||||
this.initialQuadSize = options.getScale();
|
||||
this.animationType = options.getAnimationType();
|
||||
this.f_107663_ = this.initialQuadSize;
|
||||
this.centerY = options.getCenterY();
|
||||
this.maxRadius = options.getMaxRadius();
|
||||
this.currentHeightPercent = options.getHeightPercent();
|
||||
if (this.power <= 1.0f) {
|
||||
this.animationDuration = 40;
|
||||
fadeOutDurationTicks = 40;
|
||||
} else if (this.power <= 10.0f) {
|
||||
this.animationDuration = this.interpolate(this.power, 1.0f, 40.0f, 10.0f, 100.0f);
|
||||
fadeOutDurationTicks = this.interpolate(this.power, 1.0f, 40.0f, 10.0f, 60.0f);
|
||||
} else if (this.power <= 60.0f) {
|
||||
this.animationDuration = this.interpolate(this.power, 10.0f, 100.0f, 60.0f, 140.0f);
|
||||
fadeOutDurationTicks = this.interpolate(this.power, 10.0f, 60.0f, 60.0f, 80.0f);
|
||||
} else if (this.power <= 100.0f) {
|
||||
this.animationDuration = this.interpolate(this.power, 60.0f, 140.0f, 100.0f, 200.0f);
|
||||
fadeOutDurationTicks = this.interpolate(this.power, 60.0f, 80.0f, 100.0f, 120.0f);
|
||||
} else {
|
||||
this.animationDuration = 200;
|
||||
fadeOutDurationTicks = 120;
|
||||
}
|
||||
this.f_107225_ = this.animationDuration + fadeOutDurationTicks;
|
||||
float powerFraction = Mth.m_14036_((float)(this.power / 100.0f), (float)0.0f, (float)1.0f);
|
||||
float totalFirePercent = Mth.m_14179_((float)powerFraction, (float)0.02f, (float)0.2f);
|
||||
float cooldownToSmokePercent = Mth.m_14179_((float)powerFraction, (float)0.04f, (float)0.08f);
|
||||
int totalFireDuration = (int)((float)this.f_107225_ * totalFirePercent);
|
||||
this.peakFireEndTick = (int)((float)totalFireDuration * 0.9f);
|
||||
this.fireTransitionEndTick = totalFireDuration;
|
||||
int cooldownDuration = (int)((float)this.f_107225_ * cooldownToSmokePercent);
|
||||
this.smokeStartTick = this.fireTransitionEndTick + cooldownDuration;
|
||||
if (Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.VANILA) {
|
||||
this.f_107230_ = 1.0f;
|
||||
this.f_107227_ = 1.0f;
|
||||
this.f_107228_ = 0.85f;
|
||||
this.f_107229_ = 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
public void m_5989_() {
|
||||
double targetSpeed;
|
||||
this.f_107209_ = this.f_107212_;
|
||||
this.f_107210_ = this.f_107213_;
|
||||
this.f_107211_ = this.f_107214_;
|
||||
if (this.f_107224_++ >= this.f_107225_) {
|
||||
this.m_107274_();
|
||||
return;
|
||||
}
|
||||
if (Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.VANILA) {
|
||||
this.tickVanila();
|
||||
} else if (Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.REALISTIC_2) {
|
||||
this.tickRealistic2();
|
||||
} else {
|
||||
this.tickRealistic();
|
||||
}
|
||||
this.m_6257_(this.f_107215_, this.f_107216_, this.f_107217_);
|
||||
this.f_107215_ *= (double)this.f_172258_;
|
||||
this.f_107216_ *= (double)this.f_172258_;
|
||||
this.f_107217_ *= (double)this.f_172258_;
|
||||
float heightPercent = this.updateHeightPercent();
|
||||
Vec3 direction = ExplosionWindController.getWindDirection();
|
||||
if (direction != Vec3.f_82478_ && (targetSpeed = ExplosionWindController.computeGlowSpeed(heightPercent)) > 0.0) {
|
||||
double targetX = direction.f_82479_ * targetSpeed;
|
||||
double targetZ = direction.f_82481_ * targetSpeed;
|
||||
this.f_107215_ += (targetX - this.f_107215_) * 0.1;
|
||||
this.f_107217_ += (targetZ - this.f_107217_) * 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
private void tickVanila() {
|
||||
this.baseSheetIndex = 0;
|
||||
this.f_107663_ = this.initialQuadSize;
|
||||
if (this.f_107224_ < this.peakFireEndTick) {
|
||||
this.f_107230_ = 1.0f;
|
||||
this.f_107227_ = 1.0f;
|
||||
this.f_107228_ = 0.85f;
|
||||
this.f_107229_ = 0.5f;
|
||||
} else if (this.f_107224_ < this.fireTransitionEndTick) {
|
||||
float progress = (float)(this.f_107224_ - this.peakFireEndTick) / (float)(this.fireTransitionEndTick - this.peakFireEndTick);
|
||||
this.f_107230_ = 1.0f;
|
||||
this.f_107227_ = 1.0f;
|
||||
this.f_107228_ = Mth.m_14179_((float)progress, (float)0.85f, (float)0.5f);
|
||||
this.f_107229_ = Mth.m_14179_((float)progress, (float)0.5f, (float)0.1f);
|
||||
} else if (this.f_107224_ < this.smokeStartTick) {
|
||||
float progress = (float)(this.f_107224_ - this.fireTransitionEndTick) / (float)(this.smokeStartTick - this.fireTransitionEndTick);
|
||||
float smokeCol = 0.15f;
|
||||
this.f_107227_ = Mth.m_14179_((float)progress, (float)1.0f, (float)(smokeCol + 0.1f));
|
||||
this.f_107228_ = Mth.m_14179_((float)progress, (float)0.5f, (float)smokeCol);
|
||||
this.f_107229_ = Mth.m_14179_((float)progress, (float)0.1f, (float)smokeCol);
|
||||
this.f_107230_ = Mth.m_14179_((float)progress, (float)1.0f, (float)0.9f);
|
||||
} else {
|
||||
float progress = (float)(this.f_107224_ - this.smokeStartTick) / (float)(this.f_107225_ - this.smokeStartTick);
|
||||
float finalSmokeCol = 0.05f;
|
||||
this.f_107228_ = this.f_107229_ = Mth.m_14179_((float)progress, (float)0.15f, (float)finalSmokeCol);
|
||||
this.f_107227_ = this.f_107229_;
|
||||
this.f_107230_ = 0.9f * (1.0f - progress * progress * progress);
|
||||
}
|
||||
}
|
||||
|
||||
private void tickRealistic2() {
|
||||
int frameIndex;
|
||||
int emissiveSheetStart;
|
||||
int baseSheetStart;
|
||||
int frameCountForAnim;
|
||||
this.f_107663_ = this.initialQuadSize * 2.0f;
|
||||
if (this.animationType == 2) {
|
||||
frameCountForAnim = 224;
|
||||
baseSheetStart = 18;
|
||||
emissiveSheetStart = 22;
|
||||
} else if (this.animationType == 1) {
|
||||
frameCountForAnim = 239;
|
||||
baseSheetStart = 10;
|
||||
emissiveSheetStart = 14;
|
||||
} else {
|
||||
frameCountForAnim = 239;
|
||||
baseSheetStart = 2;
|
||||
emissiveSheetStart = 6;
|
||||
}
|
||||
if (this.f_107224_ < this.animationDuration) {
|
||||
float animProgress = (float)this.f_107224_ / (float)this.animationDuration;
|
||||
float easedProgress = 1.0f - (float)Math.pow(1.0f - animProgress, 3.0);
|
||||
frameIndex = (int)(easedProgress * (float)(frameCountForAnim - 1));
|
||||
this.f_107230_ = 1.0f;
|
||||
} else {
|
||||
frameIndex = frameCountForAnim - 1;
|
||||
int fadeDuration = this.f_107225_ - this.animationDuration;
|
||||
int ageInFade = this.f_107224_ - this.animationDuration;
|
||||
this.f_107230_ = 1.0f - (float)ageInFade / (float)fadeDuration;
|
||||
}
|
||||
frameIndex = Mth.m_14045_((int)frameIndex, (int)0, (int)(frameCountForAnim - 1));
|
||||
this.baseSheetIndex = baseSheetStart + frameIndex / 64;
|
||||
this.baseFrameOnSheet = frameIndex % 64;
|
||||
this.emissiveSheetIndex = emissiveSheetStart + frameIndex / 64;
|
||||
this.emissiveFrameOnSheet = frameIndex % 64;
|
||||
}
|
||||
|
||||
private void tickRealistic() {
|
||||
int frameIndex;
|
||||
int emissiveSheetStart;
|
||||
int baseSheetStart;
|
||||
int frameCountForAnim;
|
||||
if (this.animationType == 2) {
|
||||
frameCountForAnim = 224;
|
||||
baseSheetStart = 18;
|
||||
emissiveSheetStart = 22;
|
||||
} else if (this.animationType == 1) {
|
||||
frameCountForAnim = 239;
|
||||
baseSheetStart = 10;
|
||||
emissiveSheetStart = 14;
|
||||
} else {
|
||||
frameCountForAnim = 239;
|
||||
baseSheetStart = 2;
|
||||
emissiveSheetStart = 6;
|
||||
}
|
||||
if (this.f_107224_ < this.animationDuration) {
|
||||
float animProgress = (float)this.f_107224_ / (float)this.animationDuration;
|
||||
float easedProgress = 1.0f - (float)Math.pow(1.0f - animProgress, 3.0);
|
||||
frameIndex = (int)(easedProgress * (float)(frameCountForAnim - 1));
|
||||
this.f_107230_ = 1.0f;
|
||||
} else {
|
||||
frameIndex = frameCountForAnim - 1;
|
||||
int fadeDuration = this.f_107225_ - this.animationDuration;
|
||||
int ageInFade = this.f_107224_ - this.animationDuration;
|
||||
this.f_107230_ = 1.0f - (float)ageInFade / (float)fadeDuration;
|
||||
}
|
||||
frameIndex = Mth.m_14045_((int)frameIndex, (int)0, (int)(frameCountForAnim - 1));
|
||||
this.baseSheetIndex = baseSheetStart + frameIndex / 64;
|
||||
this.baseFrameOnSheet = frameIndex % 64;
|
||||
this.emissiveSheetIndex = emissiveSheetStart + frameIndex / 64;
|
||||
this.emissiveFrameOnSheet = frameIndex % 64;
|
||||
}
|
||||
|
||||
public void m_5744_(VertexConsumer pBuffer, Camera pRenderInfo, float pPartialTicks) {
|
||||
Vector3f[] avector3f;
|
||||
Vec3 vec3 = pRenderInfo.m_90583_();
|
||||
float f = (float)(Mth.m_14139_((double)pPartialTicks, (double)this.f_107209_, (double)this.f_107212_) - vec3.m_7096_());
|
||||
float f1 = (float)(Mth.m_14139_((double)pPartialTicks, (double)this.f_107210_, (double)this.f_107213_) - vec3.m_7098_());
|
||||
float f2 = (float)(Mth.m_14139_((double)pPartialTicks, (double)this.f_107211_, (double)this.f_107214_) - vec3.m_7094_());
|
||||
Quaternionf quaternion = new Quaternionf((Quaternionfc)pRenderInfo.m_253121_());
|
||||
if (this.f_107231_ != 0.0f) {
|
||||
float f3 = Mth.m_14179_((float)pPartialTicks, (float)this.f_107204_, (float)this.f_107231_);
|
||||
quaternion.rotateZ(f3);
|
||||
}
|
||||
if (this.animationType == 2) {
|
||||
float aspectRatio = 0.5629139f;
|
||||
avector3f = new Vector3f[]{new Vector3f(-0.5629139f, -1.0f, 0.0f), new Vector3f(-0.5629139f, 1.0f, 0.0f), new Vector3f(0.5629139f, 1.0f, 0.0f), new Vector3f(0.5629139f, -1.0f, 0.0f)};
|
||||
} else {
|
||||
avector3f = new Vector3f[]{new Vector3f(-1.0f, -1.0f, 0.0f), new Vector3f(-1.0f, 1.0f, 0.0f), new Vector3f(1.0f, 1.0f, 0.0f), new Vector3f(1.0f, -1.0f, 0.0f)};
|
||||
}
|
||||
float f4 = this.m_5902_(pPartialTicks);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Vector3f vector3f = avector3f[i];
|
||||
vector3f.rotate((Quaternionfc)quaternion);
|
||||
vector3f.mul(f4);
|
||||
vector3f.add(f, f1, f2);
|
||||
}
|
||||
int worldLight = this.m_6355_(pPartialTicks);
|
||||
int frameToRender = Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.VANILA ? 0 : this.baseFrameOnSheet;
|
||||
ResourceLocation baseTexture = ExplosionTextureManager.getInstance().getTexture(this.baseSheetIndex);
|
||||
this.renderFrame(avector3f, baseTexture, frameToRender, this.f_107227_, this.f_107228_, this.f_107229_, this.f_107230_, worldLight);
|
||||
if (Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.REALISTIC || Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.REALISTIC_2) {
|
||||
ResourceLocation emissiveTexture = ExplosionTextureManager.getInstance().getTexture(this.emissiveSheetIndex);
|
||||
int fullBright = 240;
|
||||
this.renderFrame(avector3f, emissiveTexture, this.emissiveFrameOnSheet, this.f_107227_, this.f_107228_, this.f_107229_, this.f_107230_, fullBright);
|
||||
} else if (this.f_107224_ < this.smokeStartTick) {
|
||||
ResourceLocation emissiveTexture = ExplosionTextureManager.getInstance().getTexture(1);
|
||||
int fullBright = 240;
|
||||
this.renderFrame(avector3f, emissiveTexture, 0, this.f_107227_, this.f_107228_, this.f_107229_, this.f_107230_ * 0.8f, fullBright);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderFrame(Vector3f[] vertices, ResourceLocation texture, int frame, float r, float g, float b, float a, int light) {
|
||||
float v1;
|
||||
float u1;
|
||||
float v0;
|
||||
float u0;
|
||||
if (texture == null) {
|
||||
return;
|
||||
}
|
||||
RenderSystem.setShader(GameRenderer::m_172829_);
|
||||
RenderSystem.setShaderTexture((int)0, (ResourceLocation)texture);
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.depthMask((boolean)true);
|
||||
Tesselator tesselator = Tesselator.m_85913_();
|
||||
BufferBuilder buffer = tesselator.m_85915_();
|
||||
buffer.m_166779_(VertexFormat.Mode.QUADS, DefaultVertexFormat.f_85813_);
|
||||
if (frame == 0 && Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.VANILA) {
|
||||
u0 = 0.0f;
|
||||
v0 = 0.0f;
|
||||
u1 = 1.0f;
|
||||
v1 = 1.0f;
|
||||
} else {
|
||||
float frameUWidth = 0.125f;
|
||||
float frameVHeight = 0.125f;
|
||||
int col = frame % 8;
|
||||
int row = frame / 8;
|
||||
u0 = (float)col * frameUWidth;
|
||||
v0 = (float)row * frameVHeight;
|
||||
u1 = u0 + frameUWidth;
|
||||
v1 = v0 + frameVHeight;
|
||||
}
|
||||
buffer.m_5483_((double)vertices[0].x(), (double)vertices[0].y(), (double)vertices[0].z()).m_7421_(u0, v1).m_85950_(r, g, b, a).m_85969_(light).m_5752_();
|
||||
buffer.m_5483_((double)vertices[1].x(), (double)vertices[1].y(), (double)vertices[1].z()).m_7421_(u0, v0).m_85950_(r, g, b, a).m_85969_(light).m_5752_();
|
||||
buffer.m_5483_((double)vertices[2].x(), (double)vertices[2].y(), (double)vertices[2].z()).m_7421_(u1, v0).m_85950_(r, g, b, a).m_85969_(light).m_5752_();
|
||||
buffer.m_5483_((double)vertices[3].x(), (double)vertices[3].y(), (double)vertices[3].z()).m_7421_(u1, v1).m_85950_(r, g, b, a).m_85969_(light).m_5752_();
|
||||
tesselator.m_85914_();
|
||||
}
|
||||
|
||||
public ParticleRenderType m_7556_() {
|
||||
return ParticleRenderType.f_107433_;
|
||||
}
|
||||
|
||||
private int interpolate(float power, float p1, float v1, float p2, float v2) {
|
||||
if (p2 == p1) {
|
||||
return (int)v1;
|
||||
}
|
||||
float fraction = (power - p1) / (p2 - p1);
|
||||
return (int)(v1 + fraction * (v2 - v1));
|
||||
}
|
||||
|
||||
private float updateHeightPercent() {
|
||||
if (this.maxRadius <= 0.0f) {
|
||||
return 0.5f;
|
||||
}
|
||||
return Math.max(0.25f, this.currentHeightPercent);
|
||||
}
|
||||
|
||||
public int m_6355_(float pPartialTick) {
|
||||
if (Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.VANILA) {
|
||||
float currentAge = (float)this.f_107224_ + pPartialTick;
|
||||
if (currentAge < (float)this.fireTransitionEndTick) {
|
||||
return 240;
|
||||
}
|
||||
if (currentAge > (float)this.smokeStartTick) {
|
||||
return super.m_6355_(pPartialTick);
|
||||
}
|
||||
float progress = (currentAge - (float)this.fireTransitionEndTick) / (float)(this.smokeStartTick - this.fireTransitionEndTick);
|
||||
int packedAmbient = super.m_6355_(pPartialTick);
|
||||
int skyLightAmbient = packedAmbient >> 20 & 0xF;
|
||||
int blockLightAmbient = packedAmbient >> 4 & 0xF;
|
||||
int skyLightCurrent = (int)Mth.m_14179_((float)progress, (float)15.0f, (float)skyLightAmbient);
|
||||
int blockLightCurrent = (int)Mth.m_14179_((float)progress, (float)15.0f, (float)blockLightAmbient);
|
||||
return skyLightCurrent << 20 | blockLightCurrent << 4;
|
||||
}
|
||||
return super.m_6355_(pPartialTick);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.CustomGlowParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.client.CustomGlowParticle;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.ParticleProvider;
|
||||
import net.minecraft.client.particle.SpriteSet;
|
||||
|
||||
public class CustomGlowParticleProvider
|
||||
implements ParticleProvider<CustomGlowParticleOptions> {
|
||||
public CustomGlowParticleProvider(SpriteSet pSprites) {
|
||||
}
|
||||
|
||||
public Particle createParticle(CustomGlowParticleOptions options, ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
return new CustomGlowParticle(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.client.LowPassConcussionEffect;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Options;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
|
||||
@OnlyIn(value=Dist.CLIENT)
|
||||
@Mod.EventBusSubscriber(modid="explosionoverhaul", value={Dist.CLIENT})
|
||||
public class DeafnessConcussionEffect {
|
||||
public static int DELAY_TICKS = 3;
|
||||
public static int FADE_TO_SILENT_TICKS = 5;
|
||||
public static int FADE_FROM_SILENT_TICKS = 100;
|
||||
private static Phase phase = Phase.NONE;
|
||||
private static int ticksInPhase = 0;
|
||||
private static int phaseTicksTotal = 0;
|
||||
private static int silentTicks = 0;
|
||||
private static double baseMasterVolume = 1.0;
|
||||
private static float currentIntensity = 0.0f;
|
||||
private static float lastIntensity = 0.0f;
|
||||
public static boolean debugShowChat = false;
|
||||
public static volatile boolean enabled = true;
|
||||
|
||||
public static boolean start(float intensity, double silentSeconds, double effectivePercent, String visibility, int intensityPercent) {
|
||||
LocalPlayer player;
|
||||
float effectiveIntensity;
|
||||
if (!FMLEnvironment.dist.isClient()) {
|
||||
return false;
|
||||
}
|
||||
if (!enabled) {
|
||||
return false;
|
||||
}
|
||||
float f = effectiveIntensity = (Boolean)Config.CLIENT.enableDeafness.get() != false ? intensity : 0.001f;
|
||||
if (effectiveIntensity < 1.0E-4f) {
|
||||
return false;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc == null || mc.f_91073_ == null || mc.f_91074_ == null) {
|
||||
return false;
|
||||
}
|
||||
Options options = mc.f_91066_;
|
||||
if (options == null) {
|
||||
return false;
|
||||
}
|
||||
baseMasterVolume = (Double)options.m_246669_(SoundSource.MASTER).m_231551_();
|
||||
if (phase != Phase.NONE) {
|
||||
currentIntensity = Math.min(1.0f, currentIntensity + effectiveIntensity);
|
||||
silentTicks = Math.min(2000, silentTicks + (int)Math.round(silentSeconds * 20.0));
|
||||
if (phase != Phase.SILENT) {
|
||||
phase = Phase.FADE_IN;
|
||||
ticksInPhase = 0;
|
||||
phaseTicksTotal = FADE_TO_SILENT_TICKS;
|
||||
}
|
||||
} else {
|
||||
currentIntensity = effectiveIntensity;
|
||||
silentTicks = Math.max(0, (int)Math.round(silentSeconds * 20.0));
|
||||
phase = Phase.DELAY;
|
||||
ticksInPhase = 0;
|
||||
phaseTicksTotal = DELAY_TICKS;
|
||||
}
|
||||
lastIntensity = currentIntensity;
|
||||
if (debugShowChat && (player = mc.f_91074_) != null) {
|
||||
String msg = String.format("\u041f\u043e\u0442\u0443\u0436\u043d\u0456\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0443\u0437\u0456\u0457 %.1f%% (%s) \u2014 \u0421\u0438\u043b\u0430 \u0441\u043a\u0440\u0443\u0447\u0443\u0432\u0430\u043d\u043d\u044f %d%%, \u0427\u0430\u0441 \u0441\u043a\u0440\u0443\u0447\u0443\u0432\u0430\u043d\u043d\u044f %.1f \u0441\u0435\u043a", effectivePercent, visibility, intensityPercent, silentSeconds);
|
||||
player.m_5661_((Component)Component.m_237113_((String)msg).m_130940_(ChatFormatting.WHITE), false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase != TickEvent.Phase.END) {
|
||||
return;
|
||||
}
|
||||
if (phase == Phase.NONE) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc == null || mc.f_91066_ == null) {
|
||||
DeafnessConcussionEffect.resetVolume();
|
||||
return;
|
||||
}
|
||||
if (mc.m_91104_()) {
|
||||
return;
|
||||
}
|
||||
double t = Math.min(1.0, (double)(++ticksInPhase) / (double)phaseTicksTotal);
|
||||
switch (phase) {
|
||||
case DELAY: {
|
||||
if (ticksInPhase < phaseTicksTotal) break;
|
||||
DeafnessConcussionEffect.nextPhase(Phase.FADE_IN, FADE_TO_SILENT_TICKS);
|
||||
break;
|
||||
}
|
||||
case FADE_IN: {
|
||||
double minGain = baseMasterVolume * (1.0 - (double)currentIntensity);
|
||||
double gain = DeafnessConcussionEffect.lerp(baseMasterVolume, minGain, DeafnessConcussionEffect.easeOutQuad(t));
|
||||
DeafnessConcussionEffect.applyMasterVolume(mc, gain);
|
||||
if (ticksInPhase < phaseTicksTotal) break;
|
||||
DeafnessConcussionEffect.nextPhase(Phase.SILENT, silentTicks);
|
||||
break;
|
||||
}
|
||||
case SILENT: {
|
||||
double minGain = baseMasterVolume * (1.0 - (double)currentIntensity);
|
||||
DeafnessConcussionEffect.applyMasterVolume(mc, minGain);
|
||||
if (ticksInPhase < phaseTicksTotal) break;
|
||||
DeafnessConcussionEffect.nextPhase(Phase.FADE_OUT, FADE_FROM_SILENT_TICKS);
|
||||
break;
|
||||
}
|
||||
case FADE_OUT: {
|
||||
double minGain = baseMasterVolume * (1.0 - (double)currentIntensity);
|
||||
double gain = DeafnessConcussionEffect.lerp(minGain, baseMasterVolume, DeafnessConcussionEffect.easeInOutQuad(t));
|
||||
DeafnessConcussionEffect.applyMasterVolume(mc, gain);
|
||||
if (ticksInPhase < phaseTicksTotal) break;
|
||||
DeafnessConcussionEffect.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void nextPhase(Phase next, int durationTicks) {
|
||||
phase = next;
|
||||
ticksInPhase = 0;
|
||||
phaseTicksTotal = durationTicks;
|
||||
}
|
||||
|
||||
public static void stop() {
|
||||
DeafnessConcussionEffect.resetVolume();
|
||||
phase = Phase.NONE;
|
||||
ticksInPhase = 0;
|
||||
phaseTicksTotal = 0;
|
||||
lastIntensity = 0.0f;
|
||||
}
|
||||
|
||||
public static boolean isActive() {
|
||||
return phase != Phase.NONE;
|
||||
}
|
||||
|
||||
private static void resetVolume() {
|
||||
LowPassConcussionEffect.setDeafnessGain(1.0f);
|
||||
}
|
||||
|
||||
private static void applyMasterVolume(Minecraft mc, double volume) {
|
||||
float clamped = (float)Math.max(0.0, Math.min(1.0, volume));
|
||||
LowPassConcussionEffect.setDeafnessGain(clamped);
|
||||
}
|
||||
|
||||
private static double lerp(double a, double b, double t) {
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
private static double easeOutQuad(double t) {
|
||||
return 1.0 - (1.0 - t) * (1.0 - t);
|
||||
}
|
||||
|
||||
private static double easeInOutQuad(double t) {
|
||||
return t < 0.5 ? 2.0 * t * t : 1.0 - Math.pow(-2.0 * t + 2.0, 2.0) / 2.0;
|
||||
}
|
||||
|
||||
private static enum Phase {
|
||||
NONE,
|
||||
DELAY,
|
||||
FADE_IN,
|
||||
SILENT,
|
||||
FADE_OUT;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
|
||||
public class ExplosionTextureManager {
|
||||
private static final LogUtils LOGGER_WRAPPER = null;
|
||||
private static final ExplosionTextureManager INSTANCE = new ExplosionTextureManager();
|
||||
private final Map<Integer, DynamicTexture> textures = new HashMap<Integer, DynamicTexture>();
|
||||
private final Map<Integer, ResourceLocation> resourceLocations = new HashMap<Integer, ResourceLocation>();
|
||||
public static final int INDEX_SOFT_GLOW = 0;
|
||||
public static final int INDEX_SOFT_GLOW_E = 1;
|
||||
public static final int GLOW_BASE_START = 2;
|
||||
public static final int GLOW_EMISSIVE_START = 6;
|
||||
public static final int GLOW2_BASE_START = 10;
|
||||
public static final int GLOW2_EMISSIVE_START = 14;
|
||||
public static final int SGLOW_BASE_START = 18;
|
||||
public static final int SGLOW_EMISSIVE_START = 22;
|
||||
private static final String BASE_PATH = "explosions/";
|
||||
|
||||
public static ExplosionTextureManager getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private ExplosionTextureManager() {
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
this.clear();
|
||||
if (Minecraft.m_91087_().m_91098_() == null) {
|
||||
return;
|
||||
}
|
||||
ExplosionOverhaul.LOGGER.info("Reloading Explosion Texture Manager...");
|
||||
this.loadTexture(0, "soft_glow.png");
|
||||
this.loadTexture(1, "soft_glow_e.png");
|
||||
Config.Client.ParticleRenderMode mode = (Config.Client.ParticleRenderMode)((Object)Config.CLIENT.particleRenderMode.get());
|
||||
if (mode == Config.Client.ParticleRenderMode.VANILA) {
|
||||
ExplosionOverhaul.LOGGER.info("Vanilla mode active - skipping high-res sheet loading to save VRAM.");
|
||||
return;
|
||||
}
|
||||
Config.Client.GlowTextureQuality quality = (Config.Client.GlowTextureQuality)((Object)Config.CLIENT.glowTextureQuality.get());
|
||||
boolean is64 = quality == Config.Client.GlowTextureQuality.QUALITY_64;
|
||||
this.loadSheetGroup(2, "glow/glow_sheet_", is64);
|
||||
this.loadSheetGroup(6, "glow/glow_e_sheet_", is64);
|
||||
this.loadSheetGroup(10, "glow_2/glow_2_sheet_", is64);
|
||||
this.loadSheetGroup(14, "glow_2/glow_2_e_sheet_", is64);
|
||||
this.loadSheetGroup(18, "sglow/sglow_sheet_", is64);
|
||||
this.loadSheetGroup(22, "sglow/sglow_e_sheet_", is64);
|
||||
ExplosionOverhaul.LOGGER.info("Explosion sheets loaded successfully (Quality: {}).", (Object)(is64 ? "64" : "256"));
|
||||
}
|
||||
|
||||
private void loadSheetGroup(int startIndex, String prefix, boolean is64) {
|
||||
String pathPrefix = is64 ? prefix.replace("/", "/64/") : prefix;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
this.loadTexture(startIndex + i, pathPrefix + (i + 1) + ".png");
|
||||
}
|
||||
}
|
||||
|
||||
private void loadTexture(int index, String path) {
|
||||
ResourceLocation fullPath = new ResourceLocation("explosionoverhaul", BASE_PATH + path);
|
||||
try {
|
||||
InputStream is = ((Resource)Minecraft.m_91087_().m_91098_().m_213713_(fullPath).get()).m_215507_();
|
||||
NativeImage image = NativeImage.m_85058_((InputStream)is);
|
||||
DynamicTexture texture = new DynamicTexture(image);
|
||||
ResourceLocation loc = Minecraft.m_91087_().m_91097_().m_118490_("explosion_sheet_" + index, texture);
|
||||
this.textures.put(index, texture);
|
||||
this.resourceLocations.put(index, loc);
|
||||
}
|
||||
catch (Exception e) {
|
||||
ExplosionOverhaul.LOGGER.error("Failed to load explosion sheet from {}: {}", (Object)fullPath, (Object)e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public ResourceLocation getTexture(int index) {
|
||||
ResourceLocation loc = this.resourceLocations.get(index);
|
||||
if (loc == null) {
|
||||
loc = this.resourceLocations.get(0);
|
||||
}
|
||||
if (loc == null) {
|
||||
return new ResourceLocation("minecraft", "textures/particle/generic_0.png");
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.textures.values().forEach(DynamicTexture::close);
|
||||
this.textures.clear();
|
||||
this.resourceLocations.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ExplosionWindController {
|
||||
private static final double BASE_SPEED = 0.05;
|
||||
private static final double MAX_SPEED = 0.06;
|
||||
private static final double LERP_FACTOR = 0.03;
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final double[] HEIGHT_STOPS = new double[]{0.0, 0.25, 0.5, 0.75, 1.0};
|
||||
private static final double[] DUST_SPEEDS = new double[]{0.02, 0.02, 0.02, 0.02, 0.02};
|
||||
private static final double[] GLOW_SPEEDS = new double[]{0.0, 0.02, 0.04, 0.06, 0.08};
|
||||
private static Vec3 currentWind = Vec3.f_82478_;
|
||||
private static Vec3 targetDirection = Vec3.f_82478_;
|
||||
private static int ticksUntilDirectionShift = 0;
|
||||
|
||||
private ExplosionWindController() {
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
Vec3 desiredWind;
|
||||
if (ticksUntilDirectionShift-- <= 0) {
|
||||
targetDirection = ExplosionWindController.randomHorizontalDirection();
|
||||
ticksUntilDirectionShift = 80 + RANDOM.nextInt(120);
|
||||
}
|
||||
if ((currentWind = ExplosionWindController.lerp(currentWind, desiredWind = targetDirection.m_82490_(0.05), 0.03)).m_82553_() > 0.06) {
|
||||
currentWind = currentWind.m_82541_().m_82490_(0.06);
|
||||
}
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
currentWind = Vec3.f_82478_;
|
||||
targetDirection = Vec3.f_82478_;
|
||||
ticksUntilDirectionShift = 0;
|
||||
}
|
||||
|
||||
public static Vec3 getWind() {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return Vec3.f_82478_;
|
||||
}
|
||||
double multiplier = (Double)Config.CLIENT.windSpeedMultiplier.get();
|
||||
return currentWind.m_82490_(multiplier);
|
||||
}
|
||||
|
||||
public static Vec3 getScaledWind(double scale) {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return Vec3.f_82478_;
|
||||
}
|
||||
double multiplier = (Double)Config.CLIENT.windSpeedMultiplier.get();
|
||||
return currentWind.m_82490_(scale * multiplier);
|
||||
}
|
||||
|
||||
public static Vec3 getWindDirection() {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return Vec3.f_82478_;
|
||||
}
|
||||
double length = Math.sqrt(ExplosionWindController.currentWind.f_82479_ * ExplosionWindController.currentWind.f_82479_ + ExplosionWindController.currentWind.f_82481_ * ExplosionWindController.currentWind.f_82481_);
|
||||
if (length < 1.0E-4) {
|
||||
return Vec3.f_82478_;
|
||||
}
|
||||
return new Vec3(ExplosionWindController.currentWind.f_82479_ / length, 0.0, ExplosionWindController.currentWind.f_82481_ / length);
|
||||
}
|
||||
|
||||
private static double getWeatherMultiplier() {
|
||||
Minecraft minecraft = Minecraft.m_91087_();
|
||||
if (minecraft.f_91073_ != null && minecraft.f_91074_ != null) {
|
||||
Biome.Precipitation precipitation = ((Biome)minecraft.f_91073_.m_204166_(minecraft.f_91074_.m_20183_()).m_203334_()).m_264600_(minecraft.f_91074_.m_20183_());
|
||||
if (minecraft.f_91073_.m_46471_() || minecraft.f_91073_.m_46470_()) {
|
||||
return 1.5;
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public static double computeDustSpeed(double heightPercent) {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return 0.0;
|
||||
}
|
||||
double baseSpeed = ExplosionWindController.sampleProfile(heightPercent, DUST_SPEEDS);
|
||||
double weatherMultiplier = ExplosionWindController.getWeatherMultiplier();
|
||||
return baseSpeed * (Double)Config.CLIENT.windSpeedMultiplier.get() * weatherMultiplier;
|
||||
}
|
||||
|
||||
public static double computeGlowSpeed(double heightPercent) {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return 0.0;
|
||||
}
|
||||
double baseSpeed = ExplosionWindController.sampleProfile(heightPercent, GLOW_SPEEDS);
|
||||
double weatherMultiplier = ExplosionWindController.getWeatherMultiplier();
|
||||
return baseSpeed * (Double)Config.CLIENT.windSpeedMultiplier.get() * weatherMultiplier;
|
||||
}
|
||||
|
||||
public static Vec3 getDustWindVector(double heightPercent) {
|
||||
Vec3 direction = ExplosionWindController.getWindDirection();
|
||||
if (direction == Vec3.f_82478_) {
|
||||
return direction;
|
||||
}
|
||||
return direction.m_82490_(ExplosionWindController.computeDustSpeed(heightPercent));
|
||||
}
|
||||
|
||||
public static Vec3 getGlowWindVector(double heightPercent) {
|
||||
Vec3 direction = ExplosionWindController.getWindDirection();
|
||||
if (direction == Vec3.f_82478_) {
|
||||
return direction;
|
||||
}
|
||||
return direction.m_82490_(ExplosionWindController.computeGlowSpeed(heightPercent));
|
||||
}
|
||||
|
||||
private static double sampleProfile(double heightPercent, double[] speeds) {
|
||||
double clamped = Math.max(0.0, Math.min(1.0, heightPercent));
|
||||
for (int i = 1; i < HEIGHT_STOPS.length; ++i) {
|
||||
double prevStop = HEIGHT_STOPS[i - 1];
|
||||
double stop = HEIGHT_STOPS[i];
|
||||
if (!(clamped <= stop)) continue;
|
||||
double t = stop <= prevStop ? 0.0 : (clamped - prevStop) / (stop - prevStop);
|
||||
double prevValue = speeds[i - 1];
|
||||
double value = speeds[i];
|
||||
return prevValue + (value - prevValue) * t;
|
||||
}
|
||||
return speeds[speeds.length - 1];
|
||||
}
|
||||
|
||||
private static Vec3 lerp(Vec3 from, Vec3 to, double factor) {
|
||||
double clamped = Math.max(0.0, Math.min(1.0, factor));
|
||||
double x = from.f_82479_ + (to.f_82479_ - from.f_82479_) * clamped;
|
||||
double y = from.f_82480_ + (to.f_82480_ - from.f_82480_) * clamped;
|
||||
double z = from.f_82481_ + (to.f_82481_ - from.f_82481_) * clamped;
|
||||
return new Vec3(x, y, z);
|
||||
}
|
||||
|
||||
private static Vec3 randomHorizontalDirection() {
|
||||
double angle = RANDOM.nextDouble() * Math.PI * 2.0;
|
||||
double x = Math.cos(angle);
|
||||
double z = Math.sin(angle);
|
||||
return new Vec3(x, 0.0, z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
public class FadingMusicInstance
|
||||
extends AbstractTickableSoundInstance {
|
||||
private float targetVolume = 1.0f;
|
||||
private float fadeSpeed = 0.0f;
|
||||
private boolean shouldStop = false;
|
||||
|
||||
public FadingMusicInstance(SoundEvent sound, float volume, SoundSource source) {
|
||||
super(sound, source, RandomSource.m_216327_());
|
||||
this.f_119578_ = true;
|
||||
this.f_119579_ = 0;
|
||||
this.f_119573_ = volume;
|
||||
this.f_119574_ = 1.0f;
|
||||
this.f_119575_ = 0.0;
|
||||
this.f_119576_ = 0.0;
|
||||
this.f_119577_ = 0.0;
|
||||
this.f_119582_ = true;
|
||||
this.f_119580_ = SoundInstance.Attenuation.NONE;
|
||||
this.targetVolume = volume;
|
||||
}
|
||||
|
||||
public void m_7788_() {
|
||||
if (Math.abs(this.f_119573_ - this.targetVolume) > 0.001f) {
|
||||
if (this.fadeSpeed != 0.0f) {
|
||||
this.f_119573_ += this.fadeSpeed;
|
||||
if (this.fadeSpeed > 0.0f && this.f_119573_ >= this.targetVolume) {
|
||||
this.f_119573_ = this.targetVolume;
|
||||
} else if (this.fadeSpeed < 0.0f && this.f_119573_ <= this.targetVolume) {
|
||||
this.f_119573_ = this.targetVolume;
|
||||
}
|
||||
this.f_119573_ = Math.max(0.0f, Math.min(1.0f, this.f_119573_));
|
||||
} else {
|
||||
this.f_119573_ = this.targetVolume;
|
||||
}
|
||||
}
|
||||
if (this.shouldStop && this.f_119573_ <= 0.001f) {
|
||||
this.m_119609_();
|
||||
}
|
||||
}
|
||||
|
||||
public void fadeTo(float targetVolume, float durationSeconds) {
|
||||
this.targetVolume = Math.max(0.0f, Math.min(1.0f, targetVolume));
|
||||
float totalTicks = durationSeconds * 20.0f;
|
||||
float volumeDifference = this.targetVolume - this.f_119573_;
|
||||
this.fadeSpeed = volumeDifference / totalTicks;
|
||||
}
|
||||
|
||||
public void fadeOutAndStop(float durationSeconds) {
|
||||
this.fadeTo(0.0f, durationSeconds);
|
||||
this.shouldStop = true;
|
||||
}
|
||||
|
||||
public float getCurrentVolume() {
|
||||
return this.f_119573_;
|
||||
}
|
||||
|
||||
public boolean hasFinishedFading() {
|
||||
return this.shouldStop && this.f_119573_ <= 0.001f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,751 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
|
||||
import com.vinlanx.explosionoverhaul.ModSounds;
|
||||
import com.vinlanx.explosionoverhaul.client.BackgroundParticle;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionTextureManager;
|
||||
import com.vinlanx.explosionoverhaul.client.IntroMusicManager;
|
||||
import com.vinlanx.explosionoverhaul.client.SpriteSheetAnimator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
public class FirstTimeScreen
|
||||
extends Screen {
|
||||
private static final ResourceLocation SPRITE_REALISTIC = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)"intro_gui/gui_screen_1.png");
|
||||
private static final ResourceLocation SPRITE_VANILLA = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)"intro_gui/gui_screen_2.png");
|
||||
private static final ResourceLocation SPRITE_REALISTIC_2 = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)"intro_gui/gui_screen_3.png");
|
||||
private static final ResourceLocation SPRITE_STYLE_256 = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)"intro_gui/gui_screen_1.png");
|
||||
private static final ResourceLocation SPRITE_STYLE_64 = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)"intro_gui/gui_screen_4.png");
|
||||
private static final int FRAME_WIDTH = 854;
|
||||
private static final int FRAME_HEIGHT = 480;
|
||||
private static final int COLUMNS = 10;
|
||||
private static final int ROWS = 10;
|
||||
private static final int TOTAL_FRAMES = 61;
|
||||
private static final int FPS = 15;
|
||||
private static final int COLOR_BG = -15921907;
|
||||
private static final int COLOR_ACCENT_ORANGE = -881908;
|
||||
private static final int COLOR_ACCENT_RED = -4250588;
|
||||
private static final int COLOR_ACCENT_ROSE = -2529701;
|
||||
private static final int COLOR_ACCENT_DARK_RED = -10939115;
|
||||
private ScreenState currentState = ScreenState.CHOOSING_MODE;
|
||||
private Config.Client.ParticleRenderMode selectedRenderMode = null;
|
||||
private SpriteSheetAnimator realisticAnimator;
|
||||
private SpriteSheetAnimator vanillaAnimator;
|
||||
private SpriteSheetAnimator realistic2Animator;
|
||||
private SpriteSheetAnimator style256Animator;
|
||||
private SpriteSheetAnimator style64Animator;
|
||||
private boolean shouldSwitchState = false;
|
||||
private ScreenState nextState = ScreenState.CHOOSING_MODE;
|
||||
private int leftBoxX;
|
||||
private int leftBoxY;
|
||||
private int leftBoxW;
|
||||
private int leftBoxH;
|
||||
private int rightBoxX;
|
||||
private int rightBoxY;
|
||||
private int rightBoxW;
|
||||
private int rightBoxH;
|
||||
private int bottomBoxX;
|
||||
private int bottomBoxY;
|
||||
private int bottomBoxW;
|
||||
private int bottomBoxH;
|
||||
private int backButtonX;
|
||||
private int backButtonY;
|
||||
private int backButtonW;
|
||||
private int backButtonH;
|
||||
private boolean backButtonHovered = false;
|
||||
private float backButtonScale = 1.0f;
|
||||
private float leftHoverScale = 1.0f;
|
||||
private float rightHoverScale = 1.0f;
|
||||
private float bottomHoverScale = 1.0f;
|
||||
private static final float HOVER_SCALE_TARGET = 1.05f;
|
||||
private static final float SCALE_SPEED = 0.15f;
|
||||
private boolean leftHovered = false;
|
||||
private boolean rightHovered = false;
|
||||
private boolean bottomHovered = false;
|
||||
private long lastFrameTime = System.currentTimeMillis();
|
||||
private float transitionAlpha = 1.0f;
|
||||
private boolean isTransitioning = false;
|
||||
private static final float TRANSITION_DURATION = 0.8f;
|
||||
private float transitionTime = 0.0f;
|
||||
private List<BackgroundParticle> particles = new ArrayList<BackgroundParticle>();
|
||||
private RandomSource random = RandomSource.m_216327_();
|
||||
private float backgroundTime = 0.0f;
|
||||
private IntroMusicManager musicManager;
|
||||
private static final float FADE_IN_DURATION = 5.0f;
|
||||
private static final float FADE_OUT_DURATION = 3.0f;
|
||||
private float fadeTime = 0.0f;
|
||||
private boolean fadingIn = true;
|
||||
private boolean fadingOut = false;
|
||||
private float screenAlpha = 0.0f;
|
||||
private float fadeOutStartAlpha = 1.0f;
|
||||
private long fadeOutStartMillis = -1L;
|
||||
private static final long FORCE_CLOSE_BUFFER_MS = 2000L;
|
||||
|
||||
public FirstTimeScreen() {
|
||||
super((Component)Component.m_237113_((String)"First Time Setup"));
|
||||
}
|
||||
|
||||
protected void m_7856_() {
|
||||
int i;
|
||||
int displayHeight;
|
||||
int displayWidth;
|
||||
super.m_7856_();
|
||||
this.fadingIn = true;
|
||||
this.fadingOut = false;
|
||||
this.fadeTime = 0.0f;
|
||||
this.screenAlpha = 0.0f;
|
||||
this.lastFrameTime = System.currentTimeMillis();
|
||||
this.leftHovered = false;
|
||||
this.rightHovered = false;
|
||||
this.bottomHovered = false;
|
||||
this.backButtonHovered = false;
|
||||
this.backButtonScale = 1.0f;
|
||||
this.musicManager = IntroMusicManager.getInstance();
|
||||
if (this.currentState == ScreenState.CHOOSING_MODE) {
|
||||
this.realisticAnimator = new SpriteSheetAnimator(SPRITE_REALISTIC, 854, 480, 10, 10, 61, 15);
|
||||
this.vanillaAnimator = new SpriteSheetAnimator(SPRITE_VANILLA, 854, 480, 10, 10, 61, 15);
|
||||
this.realistic2Animator = new SpriteSheetAnimator(SPRITE_REALISTIC_2, 854, 480, 10, 10, 61, 15);
|
||||
this.realisticAnimator.load();
|
||||
this.vanillaAnimator.load();
|
||||
this.realistic2Animator.load();
|
||||
} else if (this.currentState == ScreenState.CHOOSING_STYLE) {
|
||||
this.style256Animator = new SpriteSheetAnimator(SPRITE_STYLE_256, 854, 480, 10, 10, 61, 15);
|
||||
this.style64Animator = new SpriteSheetAnimator(SPRITE_STYLE_64, 854, 480, 10, 10, 61, 15);
|
||||
this.style256Animator.load();
|
||||
this.style64Animator.load();
|
||||
ExplosionOverhaul.LOGGER.warn("Style selection screen loaded. Ensure gui_screen_4.png and gui_screen_5.png exist in intro_gui folder for proper animations.");
|
||||
}
|
||||
int maxWidth = (int)((float)this.f_96543_ * 0.3f);
|
||||
int maxHeight = (int)((float)this.f_96544_ * 0.44f);
|
||||
float aspectRatio = 1.7777778f;
|
||||
if ((float)maxWidth / aspectRatio <= (float)maxHeight) {
|
||||
displayWidth = maxWidth;
|
||||
displayHeight = (int)((float)maxWidth / aspectRatio);
|
||||
} else {
|
||||
displayHeight = maxHeight;
|
||||
displayWidth = (int)((float)maxHeight * aspectRatio);
|
||||
}
|
||||
if (this.currentState == ScreenState.CHOOSING_MODE) {
|
||||
gap = (int)((float)this.f_96543_ * 0.03f);
|
||||
totalWidth = displayWidth * 2 + gap;
|
||||
startX = (this.f_96543_ - totalWidth) / 2;
|
||||
startY = (this.f_96544_ - displayHeight) / 2 - (int)((float)this.f_96544_ * 0.15f);
|
||||
this.leftBoxX = startX;
|
||||
this.leftBoxY = startY;
|
||||
this.leftBoxW = displayWidth;
|
||||
this.leftBoxH = displayHeight;
|
||||
this.rightBoxX = startX + displayWidth + gap;
|
||||
this.rightBoxY = startY;
|
||||
this.rightBoxW = displayWidth;
|
||||
this.rightBoxH = displayHeight;
|
||||
this.bottomBoxX = (this.f_96543_ - displayWidth) / 2;
|
||||
this.bottomBoxY = startY + displayHeight + (int)((float)this.f_96544_ * 0.08f);
|
||||
this.bottomBoxW = displayWidth;
|
||||
this.bottomBoxH = displayHeight;
|
||||
} else if (this.currentState == ScreenState.CHOOSING_STYLE) {
|
||||
gap = (int)((float)this.f_96543_ * 0.03f);
|
||||
totalWidth = displayWidth * 2 + gap;
|
||||
startX = (this.f_96543_ - totalWidth) / 2;
|
||||
startY = (this.f_96544_ - displayHeight) / 2;
|
||||
this.leftBoxX = startX;
|
||||
this.leftBoxY = startY;
|
||||
this.leftBoxW = displayWidth;
|
||||
this.leftBoxH = displayHeight;
|
||||
this.rightBoxX = startX + displayWidth + gap;
|
||||
this.rightBoxY = startY;
|
||||
this.rightBoxW = displayWidth;
|
||||
this.rightBoxH = displayHeight;
|
||||
this.bottomBoxX = 0;
|
||||
this.bottomBoxY = 0;
|
||||
this.bottomBoxW = 0;
|
||||
this.bottomBoxH = 0;
|
||||
this.backButtonW = (int)((float)this.f_96543_ * 0.1f);
|
||||
this.backButtonH = (int)((float)this.f_96544_ * 0.08f);
|
||||
this.backButtonX = (int)((float)this.f_96543_ * 0.02f);
|
||||
this.backButtonY = this.f_96544_ - this.backButtonH - (int)((float)this.f_96544_ * 0.02f);
|
||||
}
|
||||
for (i = 0; i < 40; ++i) {
|
||||
this.particles.add(BackgroundParticle.createSpark(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
for (i = 0; i < 15; ++i) {
|
||||
this.particles.add(BackgroundParticle.createEmber(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
for (i = 0; i < 8; ++i) {
|
||||
this.particles.add(BackgroundParticle.createSmoke(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
}
|
||||
|
||||
public void m_86600_() {
|
||||
float progress;
|
||||
super.m_86600_();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
float rawDeltaTime = (float)(currentTime - this.lastFrameTime) / 1000.0f;
|
||||
this.lastFrameTime = currentTime;
|
||||
float deltaTime = Math.min(rawDeltaTime, 0.1f);
|
||||
this.backgroundTime += deltaTime;
|
||||
if (this.isTransitioning) {
|
||||
this.transitionTime += deltaTime;
|
||||
progress = Math.min(1.0f, this.transitionTime / 0.8f);
|
||||
if (this.transitionTime < 0.4f) {
|
||||
this.transitionAlpha = 1.0f - progress * 2.0f;
|
||||
} else {
|
||||
this.transitionAlpha = (progress - 0.5f) * 2.0f;
|
||||
if (this.transitionTime >= 0.4f && !this.shouldSwitchState) {
|
||||
this.shouldSwitchState = true;
|
||||
if (this.currentState == ScreenState.CHOOSING_MODE) {
|
||||
if (this.realisticAnimator != null) {
|
||||
this.realisticAnimator.close();
|
||||
}
|
||||
if (this.vanillaAnimator != null) {
|
||||
this.vanillaAnimator.close();
|
||||
}
|
||||
if (this.realistic2Animator != null) {
|
||||
this.realistic2Animator.close();
|
||||
}
|
||||
this.nextState = ScreenState.CHOOSING_STYLE;
|
||||
} else if (this.currentState == ScreenState.CHOOSING_STYLE) {
|
||||
if (this.style256Animator != null) {
|
||||
this.style256Animator.close();
|
||||
}
|
||||
if (this.style64Animator != null) {
|
||||
this.style64Animator.close();
|
||||
}
|
||||
this.nextState = ScreenState.CHOOSING_MODE;
|
||||
}
|
||||
this.currentState = this.nextState;
|
||||
this.m_7856_();
|
||||
}
|
||||
}
|
||||
if (this.transitionTime >= 0.8f) {
|
||||
this.isTransitioning = false;
|
||||
this.transitionAlpha = 1.0f;
|
||||
this.transitionTime = 0.0f;
|
||||
this.shouldSwitchState = false;
|
||||
}
|
||||
}
|
||||
if (this.fadingIn) {
|
||||
this.fadeTime += deltaTime;
|
||||
progress = Math.min(1.0f, this.fadeTime / 5.0f);
|
||||
this.screenAlpha = this.easeOutCubic(progress);
|
||||
if (this.fadeTime >= 5.0f) {
|
||||
this.fadingIn = false;
|
||||
this.screenAlpha = 1.0f;
|
||||
}
|
||||
} else if (this.fadingOut) {
|
||||
long threshold;
|
||||
long elapsed;
|
||||
this.fadeTime += deltaTime;
|
||||
progress = Math.min(1.0f, this.fadeTime / 3.0f);
|
||||
this.screenAlpha = this.fadeOutStartAlpha * (1.0f - this.easeInCubic(progress));
|
||||
if (this.fadeTime >= 3.0f) {
|
||||
boolean musicStillFading;
|
||||
boolean bl = musicStillFading = this.musicManager != null && this.musicManager.isFadingOut();
|
||||
if (!musicStillFading) {
|
||||
ExplosionOverhaul.LOGGER.info("Screen and music fade out complete. Opening TitleScreen.");
|
||||
this.cleanupAnimators();
|
||||
Minecraft.m_91087_().m_91152_((Screen)new TitleScreen());
|
||||
} else {
|
||||
ExplosionOverhaul.LOGGER.info("Waiting for music to finish fading...");
|
||||
}
|
||||
}
|
||||
if (this.fadeOutStartMillis > 0L && (elapsed = System.currentTimeMillis() - this.fadeOutStartMillis) > (threshold = 5000L)) {
|
||||
ExplosionOverhaul.LOGGER.warn("Fade out timeout exceeded ({} ms). Forcing close and opening TitleScreen.", (Object)elapsed);
|
||||
if (this.musicManager != null) {
|
||||
this.musicManager.stop();
|
||||
}
|
||||
this.cleanupAnimators();
|
||||
this.fadingOut = false;
|
||||
this.fadeOutStartMillis = -1L;
|
||||
Minecraft.m_91087_().m_91152_((Screen)new TitleScreen());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.musicManager != null) {
|
||||
this.musicManager.tick(deltaTime);
|
||||
}
|
||||
if (this.currentState == ScreenState.CHOOSING_MODE) {
|
||||
if (this.realisticAnimator != null) {
|
||||
this.realisticAnimator.tick(deltaTime);
|
||||
}
|
||||
if (this.vanillaAnimator != null) {
|
||||
this.vanillaAnimator.tick(deltaTime);
|
||||
}
|
||||
if (this.realistic2Animator != null) {
|
||||
this.realistic2Animator.tick(deltaTime);
|
||||
}
|
||||
} else if (this.currentState == ScreenState.CHOOSING_STYLE) {
|
||||
if (this.style256Animator != null) {
|
||||
this.style256Animator.tick(deltaTime);
|
||||
}
|
||||
if (this.style64Animator != null) {
|
||||
this.style64Animator.tick(deltaTime);
|
||||
}
|
||||
}
|
||||
this.leftHoverScale = Mth.m_14179_((float)0.15f, (float)this.leftHoverScale, (float)(this.leftHovered ? 1.05f : 1.0f));
|
||||
this.rightHoverScale = Mth.m_14179_((float)0.15f, (float)this.rightHoverScale, (float)(this.rightHovered ? 1.05f : 1.0f));
|
||||
this.bottomHoverScale = Mth.m_14179_((float)0.15f, (float)this.bottomHoverScale, (float)(this.bottomHovered ? 1.05f : 1.0f));
|
||||
this.particles.removeIf(p -> {
|
||||
p.tick(deltaTime);
|
||||
return p.isDead() || p.x < -50.0f || p.x > (float)(this.f_96543_ + 50) || p.y < -50.0f || p.y > (float)(this.f_96544_ + 50);
|
||||
});
|
||||
if (this.random.m_188501_() < 0.15f) {
|
||||
this.particles.add(BackgroundParticle.createSpark(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
if (this.random.m_188501_() < 0.05f) {
|
||||
this.particles.add(BackgroundParticle.createEmber(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
if (this.random.m_188501_() < 0.02f) {
|
||||
this.particles.add(BackgroundParticle.createSmoke(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
if (this.random.m_188501_() < 0.01f) {
|
||||
this.particles.add(BackgroundParticle.createFlash(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanupAnimators() {
|
||||
if (this.realisticAnimator != null) {
|
||||
this.realisticAnimator.close();
|
||||
}
|
||||
if (this.vanillaAnimator != null) {
|
||||
this.vanillaAnimator.close();
|
||||
}
|
||||
if (this.realistic2Animator != null) {
|
||||
this.realistic2Animator.close();
|
||||
}
|
||||
if (this.style256Animator != null) {
|
||||
this.style256Animator.close();
|
||||
}
|
||||
if (this.style64Animator != null) {
|
||||
this.style64Animator.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void m_88315_(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
|
||||
graphics.m_280509_(0, 0, this.f_96543_, this.f_96544_, -16777216);
|
||||
if (this.screenAlpha < 0.01f) {
|
||||
return;
|
||||
}
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
float renderAlpha = this.screenAlpha * this.transitionAlpha;
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)renderAlpha);
|
||||
graphics.m_280168_().m_85836_();
|
||||
this.renderCinematicBackground(graphics, partialTick, renderAlpha);
|
||||
if (this.currentState == ScreenState.CHOOSING_MODE) {
|
||||
this.renderModeSelection(graphics, mouseX, mouseY, renderAlpha);
|
||||
} else if (this.currentState == ScreenState.CHOOSING_STYLE) {
|
||||
this.renderStyleSelection(graphics, mouseX, mouseY, renderAlpha);
|
||||
}
|
||||
graphics.m_280168_().m_85849_();
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f);
|
||||
super.m_88315_(graphics, mouseX, mouseY, partialTick);
|
||||
}
|
||||
|
||||
private void renderModeSelection(GuiGraphics graphics, int mouseX, int mouseY, float renderAlpha) {
|
||||
String title = "Choose Your Explosion Style";
|
||||
int titleWidth = this.f_96547_.m_92895_(title);
|
||||
int titleX = (this.f_96543_ - titleWidth) / 2;
|
||||
int titleY = this.leftBoxY - 40;
|
||||
int titleAlpha = (int)(renderAlpha * 255.0f) << 24;
|
||||
graphics.m_280056_(this.f_96547_, title, titleX + 2, titleY + 2, 0xF28B0C | (int)(64.0f * renderAlpha) << 24, false);
|
||||
graphics.m_280056_(this.f_96547_, title, titleX + 1, titleY + 1, 0xF28B0C | (int)(128.0f * renderAlpha) << 24, false);
|
||||
graphics.m_280056_(this.f_96547_, title, titleX, titleY, 0xF28B0C | titleAlpha, true);
|
||||
String subtitle = "You can change this anytime in the config";
|
||||
int subtitleWidth = this.f_96547_.m_92895_(subtitle);
|
||||
graphics.m_280056_(this.f_96547_, subtitle, (this.f_96543_ - subtitleWidth) / 2, titleY + 15, 0xCCCCCC | titleAlpha, false);
|
||||
String psNote = "P.S. Colors in the game may differ from the animations because compression has altered the colors";
|
||||
int psWidth = this.f_96547_.m_92895_(psNote);
|
||||
int psColor = 0x999999 | titleAlpha;
|
||||
graphics.m_280056_(this.f_96547_, psNote, (this.f_96543_ - psWidth) / 2, titleY + 30, psColor, false);
|
||||
if (!this.isTransitioning) {
|
||||
boolean wasLeftHovered = this.leftHovered;
|
||||
boolean wasRightHovered = this.rightHovered;
|
||||
boolean wasBottomHovered = this.bottomHovered;
|
||||
this.leftHovered = this.isMouseOver(mouseX, mouseY, this.leftBoxX, this.leftBoxY, this.leftBoxW, this.leftBoxH);
|
||||
this.rightHovered = this.isMouseOver(mouseX, mouseY, this.rightBoxX, this.rightBoxY, this.rightBoxW, this.rightBoxH);
|
||||
this.bottomHovered = this.isMouseOver(mouseX, mouseY, this.bottomBoxX, this.bottomBoxY, this.bottomBoxW, this.bottomBoxH);
|
||||
if (this.leftHovered && !wasLeftHovered) {
|
||||
this.realisticAnimator.reset();
|
||||
this.realisticAnimator.play();
|
||||
} else if (!this.leftHovered && wasLeftHovered) {
|
||||
this.realisticAnimator.reset();
|
||||
}
|
||||
if (this.rightHovered && !wasRightHovered) {
|
||||
this.vanillaAnimator.reset();
|
||||
this.vanillaAnimator.play();
|
||||
} else if (!this.rightHovered && wasRightHovered) {
|
||||
this.vanillaAnimator.reset();
|
||||
}
|
||||
if (this.bottomHovered && !wasBottomHovered) {
|
||||
this.realistic2Animator.reset();
|
||||
this.realistic2Animator.play();
|
||||
} else if (!this.bottomHovered && wasBottomHovered) {
|
||||
this.realistic2Animator.reset();
|
||||
}
|
||||
}
|
||||
this.renderBox(graphics, this.leftBoxX, this.leftBoxY, this.leftBoxW, this.leftBoxH, this.leftHoverScale, this.realisticAnimator, "REALISTIC", this.leftHovered, -881908, renderAlpha);
|
||||
this.renderBox(graphics, this.rightBoxX, this.rightBoxY, this.rightBoxW, this.rightBoxH, this.rightHoverScale, this.vanillaAnimator, "VANILLA-LIKE", this.rightHovered, -4250588, renderAlpha);
|
||||
this.renderBox(graphics, this.bottomBoxX, this.bottomBoxY, this.bottomBoxW, this.bottomBoxH, this.bottomHoverScale, this.realistic2Animator, "REALISTIC 2", this.bottomHovered, -2529701, renderAlpha);
|
||||
}
|
||||
|
||||
private void renderStyleSelection(GuiGraphics graphics, int mouseX, int mouseY, float renderAlpha) {
|
||||
String title = "Choose Render Style";
|
||||
int titleWidth = this.f_96547_.m_92895_(title);
|
||||
int titleX = (this.f_96543_ - titleWidth) / 2;
|
||||
int titleY = this.leftBoxY - 40;
|
||||
int titleAlpha = (int)(renderAlpha * 255.0f) << 24;
|
||||
graphics.m_280056_(this.f_96547_, title, titleX + 2, titleY + 2, 0xF28B0C | (int)(64.0f * renderAlpha) << 24, false);
|
||||
graphics.m_280056_(this.f_96547_, title, titleX + 1, titleY + 1, 0xF28B0C | (int)(128.0f * renderAlpha) << 24, false);
|
||||
graphics.m_280056_(this.f_96547_, title, titleX, titleY, 0xF28B0C | titleAlpha, true);
|
||||
String subtitle = "Higher quality requires more VRAM";
|
||||
int subtitleWidth = this.f_96547_.m_92895_(subtitle);
|
||||
graphics.m_280056_(this.f_96547_, subtitle, (this.f_96543_ - subtitleWidth) / 2, titleY + 15, 0xCCCCCC | titleAlpha, false);
|
||||
if (!this.isTransitioning) {
|
||||
boolean wasLeftHovered = this.leftHovered;
|
||||
boolean wasRightHovered = this.rightHovered;
|
||||
boolean wasBackHovered = this.backButtonHovered;
|
||||
this.leftHovered = this.isMouseOver(mouseX, mouseY, this.leftBoxX, this.leftBoxY, this.leftBoxW, this.leftBoxH);
|
||||
this.rightHovered = this.isMouseOver(mouseX, mouseY, this.rightBoxX, this.rightBoxY, this.rightBoxW, this.rightBoxH);
|
||||
this.backButtonHovered = this.isMouseOver(mouseX, mouseY, this.backButtonX, this.backButtonY, this.backButtonW, this.backButtonH);
|
||||
this.bottomHovered = false;
|
||||
if (this.leftHovered && !wasLeftHovered) {
|
||||
this.style256Animator.reset();
|
||||
this.style256Animator.play();
|
||||
} else if (!this.leftHovered && wasLeftHovered) {
|
||||
this.style256Animator.reset();
|
||||
}
|
||||
if (this.rightHovered && !wasRightHovered) {
|
||||
this.style64Animator.reset();
|
||||
this.style64Animator.play();
|
||||
} else if (!this.rightHovered && wasRightHovered) {
|
||||
this.style64Animator.reset();
|
||||
}
|
||||
if (this.backButtonHovered && !wasBackHovered || this.backButtonHovered || wasBackHovered) {
|
||||
// empty if block
|
||||
}
|
||||
}
|
||||
this.backButtonScale = Mth.m_14179_((float)0.15f, (float)this.backButtonScale, (float)(this.backButtonHovered ? 1.05f : 1.0f));
|
||||
this.renderBox(graphics, this.leftBoxX, this.leftBoxY, this.leftBoxW, this.leftBoxH, this.leftHoverScale, this.style256Animator, "256 PIXELS", this.leftHovered, -881908, renderAlpha);
|
||||
this.renderBox(graphics, this.rightBoxX, this.rightBoxY, this.rightBoxW, this.rightBoxH, this.rightHoverScale, this.style64Animator, "64 PIXELS", this.rightHovered, -4250588, renderAlpha);
|
||||
this.renderBackButton(graphics, renderAlpha);
|
||||
}
|
||||
|
||||
private void renderBox(GuiGraphics graphics, int x, int y, int width, int height, float scale, SpriteSheetAnimator animator, String label, boolean hovered, int accentColor, float alpha) {
|
||||
graphics.m_280168_().m_85836_();
|
||||
int centerX = x + width / 2;
|
||||
int centerY = y + height / 2;
|
||||
graphics.m_280168_().m_252880_((float)centerX, (float)centerY, 0.0f);
|
||||
graphics.m_280168_().m_85841_(scale, scale, 1.0f);
|
||||
graphics.m_280168_().m_252880_((float)(-width / 2), (float)(-height / 2), 0.0f);
|
||||
if (hovered) {
|
||||
int glowSize = 4;
|
||||
int glowAlpha = (int)(128.0f * alpha) << 24;
|
||||
graphics.m_280509_(-glowSize, -glowSize, width + glowSize, height + glowSize, accentColor & 0xFFFFFF | glowAlpha);
|
||||
}
|
||||
int bgAlpha = (int)(255.0f * alpha) << 24;
|
||||
graphics.m_280509_(0, 0, width, height, 0x591515 | bgAlpha);
|
||||
if (animator != null && animator.getTextureLocation() != null) {
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)alpha);
|
||||
RenderSystem.setShaderTexture((int)0, (ResourceLocation)animator.getTextureLocation());
|
||||
graphics.m_280163_(animator.getTextureLocation(), 0, 0, 0.0f, 0.0f, width, height, width, height);
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f);
|
||||
} else {
|
||||
int placeholderTextColor = (int)(150.0f * alpha) << 24 | 0xFFFFFFFF;
|
||||
String placeholder = "[Image not found]";
|
||||
int placeholderWidth = this.f_96547_.m_92895_(placeholder);
|
||||
graphics.m_280056_(this.f_96547_, placeholder, (width - placeholderWidth) / 2, height / 2 - 5, placeholderTextColor, false);
|
||||
}
|
||||
int borderColor = hovered ? accentColor : -2529701;
|
||||
int borderAlpha = (int)(255.0f * alpha) << 24;
|
||||
int fadedBorderColor = borderColor & 0xFFFFFF | borderAlpha;
|
||||
graphics.m_280509_(0, 0, width, 2, fadedBorderColor);
|
||||
graphics.m_280509_(0, height - 2, width, height, fadedBorderColor);
|
||||
graphics.m_280509_(0, 0, 2, height, fadedBorderColor);
|
||||
graphics.m_280509_(width - 2, 0, width, height, fadedBorderColor);
|
||||
graphics.m_280168_().m_85849_();
|
||||
int labelAlpha = (int)(255.0f * alpha) << 24;
|
||||
int labelColor = hovered ? accentColor : -1;
|
||||
int fadedLabelColor = labelColor & 0xFFFFFF | labelAlpha;
|
||||
int labelWidth = this.f_96547_.m_92895_(label);
|
||||
graphics.m_280056_(this.f_96547_, label, x + (width - labelWidth) / 2, y + height + 10, fadedLabelColor, true);
|
||||
}
|
||||
|
||||
public boolean m_6375_(double mouseX, double mouseY, int button) {
|
||||
if (this.fadingOut || this.isTransitioning) {
|
||||
return true;
|
||||
}
|
||||
if (button == 0) {
|
||||
if (this.currentState == ScreenState.CHOOSING_MODE) {
|
||||
if (this.isMouseOver((int)mouseX, (int)mouseY, this.leftBoxX, this.leftBoxY, this.leftBoxW, this.leftBoxH)) {
|
||||
this.selectRealisticMode();
|
||||
return true;
|
||||
}
|
||||
if (this.isMouseOver((int)mouseX, (int)mouseY, this.rightBoxX, this.rightBoxY, this.rightBoxW, this.rightBoxH)) {
|
||||
this.selectVanillaLike();
|
||||
return true;
|
||||
}
|
||||
if (this.isMouseOver((int)mouseX, (int)mouseY, this.bottomBoxX, this.bottomBoxY, this.bottomBoxW, this.bottomBoxH)) {
|
||||
this.selectRealistic2Mode();
|
||||
return true;
|
||||
}
|
||||
} else if (this.currentState == ScreenState.CHOOSING_STYLE) {
|
||||
if (this.isMouseOver((int)mouseX, (int)mouseY, this.leftBoxX, this.leftBoxY, this.leftBoxW, this.leftBoxH)) {
|
||||
this.selectStyle256();
|
||||
return true;
|
||||
}
|
||||
if (this.isMouseOver((int)mouseX, (int)mouseY, this.rightBoxX, this.rightBoxY, this.rightBoxW, this.rightBoxH)) {
|
||||
this.selectStyle64();
|
||||
return true;
|
||||
}
|
||||
if (this.isMouseOver((int)mouseX, (int)mouseY, this.backButtonX, this.backButtonY, this.backButtonW, this.backButtonH)) {
|
||||
this.goBack();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.m_6375_(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
private void selectRealisticMode() {
|
||||
this.playButtonSound();
|
||||
this.selectedRenderMode = Config.Client.ParticleRenderMode.REALISTIC;
|
||||
this.isTransitioning = true;
|
||||
this.transitionTime = 0.0f;
|
||||
this.transitionAlpha = 1.0f;
|
||||
}
|
||||
|
||||
private void selectRealistic2Mode() {
|
||||
this.playButtonSound();
|
||||
this.selectedRenderMode = Config.Client.ParticleRenderMode.REALISTIC_2;
|
||||
this.isTransitioning = true;
|
||||
this.transitionTime = 0.0f;
|
||||
this.transitionAlpha = 1.0f;
|
||||
}
|
||||
|
||||
private void selectStyle256() {
|
||||
this.playButtonSound();
|
||||
Config.CLIENT.glowTextureQuality.set((Object)Config.Client.GlowTextureQuality.QUALITY_256);
|
||||
Config.CLIENT.particleRenderMode.set((Object)this.selectedRenderMode);
|
||||
this.saveAndClose();
|
||||
}
|
||||
|
||||
private void selectStyle64() {
|
||||
this.playButtonSound();
|
||||
Config.CLIENT.glowTextureQuality.set((Object)Config.Client.GlowTextureQuality.QUALITY_64);
|
||||
Config.CLIENT.particleRenderMode.set((Object)this.selectedRenderMode);
|
||||
this.saveAndClose();
|
||||
}
|
||||
|
||||
private boolean isMouseOver(int mouseX, int mouseY, int x, int y, int width, int height) {
|
||||
return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
|
||||
}
|
||||
|
||||
private void selectVanillaLike() {
|
||||
this.playButtonSound();
|
||||
Config.CLIENT.particleRenderMode.set((Object)Config.Client.ParticleRenderMode.VANILA);
|
||||
this.saveAndClose();
|
||||
}
|
||||
|
||||
private void goBack() {
|
||||
this.playButtonSound();
|
||||
this.isTransitioning = true;
|
||||
this.transitionTime = 0.0f;
|
||||
this.transitionAlpha = 1.0f;
|
||||
this.selectedRenderMode = null;
|
||||
}
|
||||
|
||||
private void saveAndClose() {
|
||||
Config.CLIENT.firstLaunchComplete.set((Object)true);
|
||||
Config.CLIENT_SPEC.save();
|
||||
ExplosionTextureManager.getInstance().reload();
|
||||
if (this.musicManager != null && this.musicManager.isPlaying()) {
|
||||
ExplosionOverhaul.LOGGER.info("Starting music and screen fade out (duration: {} seconds)", (Object)Float.valueOf(3.0f));
|
||||
this.musicManager.startFadeOut();
|
||||
}
|
||||
if (this.fadingIn) {
|
||||
this.fadingIn = false;
|
||||
ExplosionOverhaul.LOGGER.info("Interrupting fade in (was at {:.1f}%) to start fade out from current alpha", (Object)Float.valueOf(this.screenAlpha * 100.0f));
|
||||
}
|
||||
this.fadeOutStartAlpha = this.screenAlpha;
|
||||
this.fadingOut = true;
|
||||
this.fadeTime = 0.0f;
|
||||
this.fadeOutStartMillis = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void renderCinematicBackground(GuiGraphics graphics, float partialTick, float globalAlpha) {
|
||||
int i;
|
||||
int bgAlpha1;
|
||||
int bgColor1 = bgAlpha1 = (int)(255.0f * globalAlpha) << 24;
|
||||
int bgColor2 = 0xD0D0D | bgAlpha1;
|
||||
graphics.m_280024_(0, 0, this.f_96543_, this.f_96544_ / 2, bgColor1, bgColor2);
|
||||
graphics.m_280024_(0, this.f_96544_ / 2, this.f_96543_, this.f_96544_, bgColor2, bgColor1);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
for (BackgroundParticle p : this.particles) {
|
||||
float particleAlpha = p.getAlpha();
|
||||
float finalAlpha = particleAlpha * globalAlpha;
|
||||
int colorWithAlpha = p.color & 0xFFFFFF | (int)(finalAlpha * 255.0f) << 24;
|
||||
switch (p.type) {
|
||||
case SPARK: {
|
||||
float sparkLen = p.size * 3.0f;
|
||||
float sparkAngle = (float)Math.atan2(p.vy, p.vx);
|
||||
int ex = (int)((double)p.x + Math.cos(sparkAngle) * (double)sparkLen);
|
||||
int ey = (int)((double)p.y + Math.sin(sparkAngle) * (double)sparkLen);
|
||||
this.drawLine(graphics, (int)p.x, (int)p.y, ex, ey, colorWithAlpha);
|
||||
break;
|
||||
}
|
||||
case EMBER: {
|
||||
int emberSize = (int)p.size;
|
||||
graphics.m_280509_((int)p.x - emberSize, (int)p.y - emberSize, (int)p.x + emberSize, (int)p.y + emberSize, colorWithAlpha);
|
||||
break;
|
||||
}
|
||||
case FLASH: {
|
||||
int flashSize = (int)(p.size * 0.7f);
|
||||
int flashColor = colorWithAlpha & 0xFFFFFF | (int)(finalAlpha * 180.0f) << 24;
|
||||
graphics.m_280509_((int)p.x - flashSize, (int)p.y - flashSize, (int)p.x + flashSize, (int)p.y + flashSize, flashColor);
|
||||
break;
|
||||
}
|
||||
case SMOKE: {
|
||||
int smokeSize = (int)p.size;
|
||||
int smokeColor = colorWithAlpha & 0xFFFFFF | (int)(finalAlpha * 60.0f) << 24;
|
||||
graphics.m_280509_((int)p.x - smokeSize, (int)p.y - smokeSize, (int)p.x + smokeSize, (int)p.y + smokeSize, smokeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
int vignetteSteps = 15;
|
||||
for (i = 0; i < vignetteSteps; ++i) {
|
||||
float ratio = (float)i / (float)vignetteSteps;
|
||||
int vignetteAlpha = (int)(ratio * ratio * 180.0f * globalAlpha);
|
||||
int vignetteColor = vignetteAlpha << 24;
|
||||
int thickness = 4;
|
||||
graphics.m_280509_(0, i * thickness, this.f_96543_, (i + 1) * thickness, vignetteColor);
|
||||
graphics.m_280509_(0, this.f_96544_ - (i + 1) * thickness, this.f_96543_, this.f_96544_ - i * thickness, vignetteColor);
|
||||
graphics.m_280509_(i * thickness, 0, (i + 1) * thickness, this.f_96544_, vignetteColor);
|
||||
graphics.m_280509_(this.f_96543_ - (i + 1) * thickness, 0, this.f_96543_ - i * thickness, this.f_96544_, vignetteColor);
|
||||
}
|
||||
for (i = 0; i < 150; ++i) {
|
||||
int gx = this.random.m_188503_(this.f_96543_);
|
||||
int gy = this.random.m_188503_(this.f_96544_);
|
||||
int grainAlpha = (int)((float)(20 + this.random.m_188503_(30)) * globalAlpha);
|
||||
int grainColor = grainAlpha << 24 | 0xFFFFFF;
|
||||
graphics.m_280509_(gx, gy, gx + 1, gy + 1, grainColor);
|
||||
}
|
||||
for (int y = 0; y < this.f_96544_; y += 4) {
|
||||
graphics.m_280509_(0, y, this.f_96543_, y + 1, 0x8000000);
|
||||
}
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
private void drawLine(GuiGraphics graphics, int x1, int y1, int x2, int y2, int color) {
|
||||
int dx = Math.abs(x2 - x1);
|
||||
int dy = Math.abs(y2 - y1);
|
||||
int sx = x1 < x2 ? 1 : -1;
|
||||
int sy = y1 < y2 ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
for (int steps = 0; steps < 200; ++steps) {
|
||||
graphics.m_280509_(x1, y1, x1 + 1, y1 + 1, color);
|
||||
if (x1 == x2 && y1 == y2) break;
|
||||
int e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err -= dy;
|
||||
x1 += sx;
|
||||
}
|
||||
if (e2 >= dx) continue;
|
||||
err += dx;
|
||||
y1 += sy;
|
||||
}
|
||||
}
|
||||
|
||||
public void m_7379_() {
|
||||
if (!this.fadingOut) {
|
||||
this.cleanupAnimators();
|
||||
super.m_7379_();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean m_7933_(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == 256) {
|
||||
return true;
|
||||
}
|
||||
return super.m_7933_(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public boolean m_7043_() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private float easeOutCubic(float x) {
|
||||
return 1.0f - (float)Math.pow(1.0f - x, 3.0);
|
||||
}
|
||||
|
||||
private float easeInCubic(float x) {
|
||||
return x * x * x;
|
||||
}
|
||||
|
||||
private void renderBackButton(GuiGraphics graphics, float alpha) {
|
||||
graphics.m_280168_().m_85836_();
|
||||
int centerX = this.backButtonX + this.backButtonW / 2;
|
||||
int centerY = this.backButtonY + this.backButtonH / 2;
|
||||
graphics.m_280168_().m_252880_((float)centerX, (float)centerY, 0.0f);
|
||||
graphics.m_280168_().m_85841_(this.backButtonScale, this.backButtonScale, 1.0f);
|
||||
graphics.m_280168_().m_252880_((float)(-this.backButtonW / 2), (float)(-this.backButtonH / 2), 0.0f);
|
||||
if (this.backButtonHovered) {
|
||||
int glowSize = 3;
|
||||
int glowAlpha = (int)(128.0f * alpha) << 24;
|
||||
graphics.m_280509_(-glowSize, -glowSize, this.backButtonW + glowSize, this.backButtonH + glowSize, 0xF28B0C | glowAlpha);
|
||||
}
|
||||
int bgAlpha = (int)(255.0f * alpha) << 24;
|
||||
graphics.m_280509_(0, 0, this.backButtonW, this.backButtonH, 0x591515 | bgAlpha);
|
||||
int borderColor = this.backButtonHovered ? -881908 : -2529701;
|
||||
int borderAlpha = (int)(255.0f * alpha) << 24;
|
||||
int fadedBorderColor = borderColor & 0xFFFFFF | borderAlpha;
|
||||
graphics.m_280509_(0, 0, this.backButtonW, 2, fadedBorderColor);
|
||||
graphics.m_280509_(0, this.backButtonH - 2, this.backButtonW, this.backButtonH, fadedBorderColor);
|
||||
graphics.m_280509_(0, 0, 2, this.backButtonH, fadedBorderColor);
|
||||
graphics.m_280509_(this.backButtonW - 2, 0, this.backButtonW, this.backButtonH, fadedBorderColor);
|
||||
graphics.m_280168_().m_85849_();
|
||||
String buttonText = "BACK";
|
||||
int textWidth = this.f_96547_.m_92895_(buttonText);
|
||||
int textColor = this.backButtonHovered ? -881908 : -1;
|
||||
int textAlpha = (int)(255.0f * alpha) << 24;
|
||||
int fadedTextColor = textColor & 0xFFFFFF | textAlpha;
|
||||
graphics.m_280056_(this.f_96547_, buttonText, this.backButtonX + (this.backButtonW - textWidth) / 2, this.backButtonY + (this.backButtonH - 8) / 2, fadedTextColor, true);
|
||||
}
|
||||
|
||||
private void playButtonSound() {
|
||||
try {
|
||||
Minecraft minecraft = Minecraft.m_91087_();
|
||||
if (minecraft.m_91106_() != null) {
|
||||
minecraft.m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.BUTTON_SOUND.get()), (float)1.0f, (float)1.0f));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
ExplosionOverhaul.LOGGER.warn("Failed to play button sound", (Throwable)e);
|
||||
}
|
||||
}
|
||||
|
||||
private static enum ScreenState {
|
||||
CHOOSING_MODE,
|
||||
CHOOSING_STYLE,
|
||||
FADING_OUT;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
|
||||
import com.vinlanx.explosionoverhaul.client.IntroSplashScreen;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber(modid="explosionoverhaul", bus=Mod.EventBusSubscriber.Bus.FORGE, value={Dist.CLIENT})
|
||||
public class FirstTimeSetupHandler {
|
||||
private static boolean hasChecked = false;
|
||||
private static boolean pendingShowIntro = false;
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase != TickEvent.Phase.END) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (!hasChecked && mc.f_91080_ instanceof TitleScreen) {
|
||||
hasChecked = true;
|
||||
ExplosionOverhaul.LOGGER.info("Detected TitleScreen on client, hasChecked=true");
|
||||
if (Config.isFirstLaunch()) {
|
||||
pendingShowIntro = true;
|
||||
}
|
||||
}
|
||||
if (!pendingShowIntro) {
|
||||
return;
|
||||
}
|
||||
if (mc.f_91080_ instanceof TitleScreen) {
|
||||
pendingShowIntro = false;
|
||||
ExplosionOverhaul.LOGGER.info("Showing IntroSplashScreen (first launch)");
|
||||
mc.m_91152_((Screen)new IntroSplashScreen());
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
ExplosionOverhaul.LOGGER.info("FirstTimeSetupHandler class loaded (waiting for TitleScreen)");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.SmokeParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionWindController;
|
||||
import java.awt.Color;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.MapColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class GroundDustEffect {
|
||||
private final ClientLevel level;
|
||||
private final Vec3 initialPosition;
|
||||
private final float power;
|
||||
private final Random random = new Random();
|
||||
private int age = 0;
|
||||
private final int maxAge;
|
||||
private final float maxRadius;
|
||||
private final float particleBaseSize;
|
||||
private final int particlesPerTick;
|
||||
private Color currentDustColor = new Color(128, 128, 128);
|
||||
private boolean finished = false;
|
||||
private final int raycastFrequency;
|
||||
|
||||
public GroundDustEffect(Vec3 position, float power) {
|
||||
this.level = Minecraft.m_91087_().f_91073_;
|
||||
this.initialPosition = position;
|
||||
this.power = power;
|
||||
double qualityMultiplier = (Double)Config.CLIENT.groundDustQuality.get();
|
||||
this.raycastFrequency = (Integer)Config.CLIENT.groundDustRaycastFrequency.get();
|
||||
float powerFraction = Mth.m_14036_((float)(power / 100.0f), (float)0.0f, (float)1.0f);
|
||||
int calculatedParticles = (int)((double)Mth.m_14179_((float)powerFraction, (float)40.0f, (float)200.0f) * qualityMultiplier);
|
||||
int calculatedMaxAge = (int)((double)Mth.m_14179_((float)powerFraction, (float)30.0f, (float)70.0f) * qualityMultiplier);
|
||||
if (qualityMultiplier > 0.0) {
|
||||
if (calculatedParticles == 0) {
|
||||
calculatedParticles = 1;
|
||||
}
|
||||
if (calculatedMaxAge == 0) {
|
||||
calculatedMaxAge = 1;
|
||||
}
|
||||
}
|
||||
this.particlesPerTick = calculatedParticles;
|
||||
this.maxAge = calculatedMaxAge;
|
||||
this.maxRadius = power * this.calculateRadiusMultiplier(power);
|
||||
this.particleBaseSize = Mth.m_14179_((float)powerFraction, (float)1.0f, (float)12.0f);
|
||||
}
|
||||
|
||||
private float calculateRadiusMultiplier(float power) {
|
||||
if (power <= 5.0f) {
|
||||
return 2.0f;
|
||||
}
|
||||
if (power <= 40.0f) {
|
||||
return Mth.m_14179_((float)((power - 5.0f) / 35.0f), (float)2.0f, (float)4.0f);
|
||||
}
|
||||
if (power <= 80.0f) {
|
||||
return Mth.m_14179_((float)((power - 40.0f) / 40.0f), (float)4.0f, (float)5.0f);
|
||||
}
|
||||
if (power <= 100.0f) {
|
||||
return Mth.m_14179_((float)((power - 80.0f) / 20.0f), (float)5.0f, (float)7.0f);
|
||||
}
|
||||
return 7.0f;
|
||||
}
|
||||
|
||||
private Color getDustColorForState(BlockState state) {
|
||||
if (state.m_204336_(BlockTags.f_13035_) || state.m_284242_((BlockGetter)this.level, BlockPos.f_121853_) == MapColor.f_283808_) {
|
||||
return null;
|
||||
}
|
||||
if (state.m_60713_(Blocks.f_50440_)) {
|
||||
return new Color(Blocks.f_50493_.m_49966_().m_284242_((BlockGetter)this.level, (BlockPos)BlockPos.f_121853_).f_283871_);
|
||||
}
|
||||
if (state.m_60713_(Blocks.f_50125_) || state.m_60713_(Blocks.f_50127_)) {
|
||||
return new Color(Blocks.f_50127_.m_49966_().m_284242_((BlockGetter)this.level, (BlockPos)BlockPos.f_121853_).f_283871_);
|
||||
}
|
||||
return new Color(state.m_284242_((BlockGetter)this.level, (BlockPos)BlockPos.f_121853_).f_283871_);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
BlockPos blockPos;
|
||||
BlockState blockState;
|
||||
Color newColor;
|
||||
double checkZ;
|
||||
double checkAngle;
|
||||
double checkX;
|
||||
BlockHitResult hitResult;
|
||||
if (this.finished || this.level == null) {
|
||||
return;
|
||||
}
|
||||
++this.age;
|
||||
if (this.age > this.maxAge) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
float progress = (float)this.age / (float)this.maxAge;
|
||||
float easedProgress = 1.0f - (float)Math.pow(1.0f - progress, 3.0);
|
||||
float currentRadius = this.maxRadius * easedProgress;
|
||||
if (this.age % 10 == 0 && (hitResult = this.level.m_45547_(new ClipContext(new Vec3(checkX = this.initialPosition.f_82479_ + Math.cos(checkAngle = this.random.nextDouble() * 2.0 * Math.PI) * (double)currentRadius, this.initialPosition.f_82480_ + 15.0, checkZ = this.initialPosition.f_82481_ + Math.sin(checkAngle) * (double)currentRadius), new Vec3(checkX, this.initialPosition.f_82480_ - 15.0, checkZ), ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null))).m_6662_() == HitResult.Type.BLOCK && (newColor = this.getDustColorForState(blockState = this.level.m_8055_(blockPos = hitResult.m_82425_()))) != null) {
|
||||
this.currentDustColor = newColor;
|
||||
}
|
||||
double cachedY = this.initialPosition.f_82480_;
|
||||
for (int i = 0; i < this.particlesPerTick; ++i) {
|
||||
float scale;
|
||||
float a;
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
double angle = (double)i / (double)this.particlesPerTick * 2.0 * Math.PI + (this.random.nextDouble() - 0.5) * 0.1;
|
||||
double radiusFrac = this.random.nextDouble();
|
||||
double spawnRadius = (double)currentRadius * (0.6 + radiusFrac * 0.4);
|
||||
double spawnX = this.initialPosition.f_82479_ + Math.cos(angle) * spawnRadius;
|
||||
double spawnZ = this.initialPosition.f_82481_ + Math.sin(angle) * spawnRadius;
|
||||
if (i % this.raycastFrequency == 0) {
|
||||
BlockHitResult hitResult2 = this.level.m_45547_(new ClipContext(new Vec3(spawnX, this.initialPosition.f_82480_ + 15.0, spawnZ), new Vec3(spawnX, this.initialPosition.f_82480_ - 15.0, spawnZ), ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null));
|
||||
if (hitResult2.m_6662_() != HitResult.Type.BLOCK) continue;
|
||||
cachedY = hitResult2.m_82450_().f_82480_;
|
||||
}
|
||||
double spawnY = cachedY;
|
||||
Vec3 direction = new Vec3(spawnX - this.initialPosition.f_82479_, 0.0, spawnZ - this.initialPosition.f_82481_).m_82541_();
|
||||
double motionStrength = Mth.m_14179_((float)(1.0f - progress), (float)0.05f, (float)0.45f);
|
||||
double motionX = direction.f_82479_ * motionStrength + (this.random.nextDouble() - 0.5) * 0.05;
|
||||
double motionZ = direction.f_82481_ * motionStrength + (this.random.nextDouble() - 0.5) * 0.05;
|
||||
double motionY = (this.random.nextDouble() - 0.5) * 0.02;
|
||||
double heightPercent = 0.0;
|
||||
Vec3 windDirection = ExplosionWindController.getWindDirection();
|
||||
double windSpeed = ExplosionWindController.computeDustSpeed(0.0);
|
||||
double initialBoostFactor = 0.65;
|
||||
if (windDirection != Vec3.f_82478_ && windSpeed > 0.0) {
|
||||
motionX += windDirection.f_82479_ * windSpeed * initialBoostFactor;
|
||||
motionZ += windDirection.f_82481_ * windSpeed * initialBoostFactor;
|
||||
}
|
||||
int lifetime = 100 + this.random.nextInt(60);
|
||||
if (radiusFrac <= 0.2) {
|
||||
b = 0.2f;
|
||||
g = 0.2f;
|
||||
r = 0.2f;
|
||||
a = 0.9f;
|
||||
scale = this.particleBaseSize * 0.5f;
|
||||
} else if (radiusFrac <= 0.65) {
|
||||
b = 0.4f;
|
||||
g = 0.4f;
|
||||
r = 0.4f;
|
||||
a = 0.6f;
|
||||
scale = this.particleBaseSize * 0.75f;
|
||||
} else {
|
||||
r = (float)this.currentDustColor.getRed() / 255.0f;
|
||||
g = (float)this.currentDustColor.getGreen() / 255.0f;
|
||||
b = (float)this.currentDustColor.getBlue() / 255.0f;
|
||||
a = 0.35f;
|
||||
scale = this.particleBaseSize;
|
||||
}
|
||||
SmokeParticleOptions options = new SmokeParticleOptions(scale * (0.8f + this.random.nextFloat() * 0.4f), lifetime, r, g, b, a, false, (float)windSpeed, (float)heightPercent, null);
|
||||
this.level.m_6493_((ParticleOptions)options, true, spawnX, spawnY + 0.2, spawnZ, motionX, motionY, motionZ);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.SmokeParticleOptions;
|
||||
import java.awt.Color;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class GroundMistEffect {
|
||||
private final ClientLevel level;
|
||||
private final Vec3 initialPosition;
|
||||
private final float power;
|
||||
private final Random random = new Random();
|
||||
private int age = 0;
|
||||
private final int maxAge;
|
||||
private final float maxRadius;
|
||||
private final float particleBaseSize;
|
||||
private final int particlesPerTick;
|
||||
private Color currentMistColor = new Color(255, 255, 255);
|
||||
private boolean finished = false;
|
||||
private final int raycastFrequency;
|
||||
|
||||
public GroundMistEffect(Vec3 position, float power) {
|
||||
this.level = Minecraft.m_91087_().f_91073_;
|
||||
this.initialPosition = position;
|
||||
this.power = power;
|
||||
double qualityMultiplier = (Double)Config.CLIENT.groundMistQuality.get();
|
||||
this.raycastFrequency = (Integer)Config.CLIENT.groundMistRaycastFrequency.get();
|
||||
float powerFraction = Mth.m_14036_((float)(power / 100.0f), (float)0.0f, (float)1.0f);
|
||||
int calculatedParticles = (int)((double)Mth.m_14179_((float)powerFraction, (float)40.0f, (float)200.0f) * qualityMultiplier * 1.5);
|
||||
int calculatedMaxAge = (int)((double)Mth.m_14179_((float)powerFraction, (float)30.0f, (float)70.0f) * qualityMultiplier / 3.0);
|
||||
if (qualityMultiplier > 0.0) {
|
||||
if (calculatedParticles == 0) {
|
||||
calculatedParticles = 1;
|
||||
}
|
||||
if (calculatedMaxAge == 0) {
|
||||
calculatedMaxAge = 1;
|
||||
}
|
||||
}
|
||||
this.particlesPerTick = calculatedParticles;
|
||||
this.maxAge = calculatedMaxAge;
|
||||
this.maxRadius = power * this.calculateRadiusMultiplier(power) * 3.0f;
|
||||
this.particleBaseSize = Mth.m_14179_((float)powerFraction, (float)1.0f, (float)12.0f);
|
||||
}
|
||||
|
||||
private float calculateRadiusMultiplier(float power) {
|
||||
if (power <= 5.0f) {
|
||||
return 2.0f;
|
||||
}
|
||||
if (power <= 40.0f) {
|
||||
return Mth.m_14179_((float)((power - 5.0f) / 35.0f), (float)2.0f, (float)4.0f);
|
||||
}
|
||||
if (power <= 80.0f) {
|
||||
return Mth.m_14179_((float)((power - 40.0f) / 40.0f), (float)4.0f, (float)5.0f);
|
||||
}
|
||||
if (power <= 100.0f) {
|
||||
return Mth.m_14179_((float)((power - 80.0f) / 20.0f), (float)5.0f, (float)7.0f);
|
||||
}
|
||||
return 7.0f;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
double checkZ;
|
||||
double checkAngle;
|
||||
double checkX;
|
||||
BlockHitResult hitResult;
|
||||
if (this.finished || this.level == null) {
|
||||
return;
|
||||
}
|
||||
++this.age;
|
||||
if (this.age > this.maxAge) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
float progress = (float)this.age / (float)this.maxAge;
|
||||
float easedProgress = 1.0f - (float)Math.pow(1.0f - progress, 3.0);
|
||||
float currentRadius = this.maxRadius * easedProgress;
|
||||
if (this.age % 10 == 0 && (hitResult = this.level.m_45547_(new ClipContext(new Vec3(checkX = this.initialPosition.f_82479_ + Math.cos(checkAngle = this.random.nextDouble() * 2.0 * Math.PI) * (double)currentRadius, this.initialPosition.f_82480_ + 15.0, checkZ = this.initialPosition.f_82481_ + Math.sin(checkAngle) * (double)currentRadius), new Vec3(checkX, this.initialPosition.f_82480_ - 15.0, checkZ), ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null))).m_6662_() == HitResult.Type.BLOCK) {
|
||||
BlockPos blockPos = hitResult.m_82425_();
|
||||
BlockState blockState = this.level.m_8055_(blockPos);
|
||||
}
|
||||
double cachedY = this.initialPosition.f_82480_;
|
||||
for (int i = 0; i < this.particlesPerTick; ++i) {
|
||||
float scale;
|
||||
float a;
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
double angle = (double)i / (double)this.particlesPerTick * 2.0 * Math.PI + (this.random.nextDouble() - 0.5) * 0.1;
|
||||
double radiusFrac = this.random.nextDouble();
|
||||
double spawnRadius = (double)currentRadius * (0.6 + radiusFrac * 0.4);
|
||||
double spawnX = this.initialPosition.f_82479_ + Math.cos(angle) * spawnRadius;
|
||||
double spawnZ = this.initialPosition.f_82481_ + Math.sin(angle) * spawnRadius;
|
||||
if (i % this.raycastFrequency == 0) {
|
||||
BlockHitResult hitResult2 = this.level.m_45547_(new ClipContext(new Vec3(spawnX, this.initialPosition.f_82480_ + 15.0, spawnZ), new Vec3(spawnX, this.initialPosition.f_82480_ - 15.0, spawnZ), ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null));
|
||||
if (hitResult2.m_6662_() != HitResult.Type.BLOCK) continue;
|
||||
cachedY = hitResult2.m_82450_().f_82480_;
|
||||
}
|
||||
double spawnY = cachedY;
|
||||
Vec3 direction = new Vec3(spawnX - this.initialPosition.f_82479_, 0.0, spawnZ - this.initialPosition.f_82481_).m_82541_();
|
||||
double motionStrength = Mth.m_14179_((float)(1.0f - progress), (float)0.02f, (float)0.15f);
|
||||
double motionX = direction.f_82479_ * motionStrength + (this.random.nextDouble() - 0.5) * 0.02;
|
||||
double motionZ = direction.f_82481_ * motionStrength + (this.random.nextDouble() - 0.5) * 0.02;
|
||||
double motionY = -0.01 - this.random.nextDouble() * 0.02;
|
||||
int lifetime = 100 + this.random.nextInt(60);
|
||||
if (radiusFrac <= 0.2) {
|
||||
b = 0.8f;
|
||||
g = 0.8f;
|
||||
r = 0.8f;
|
||||
a = 0.3f;
|
||||
scale = this.particleBaseSize * 0.1667f;
|
||||
} else if (radiusFrac <= 0.65) {
|
||||
b = 0.9f;
|
||||
g = 0.9f;
|
||||
r = 0.9f;
|
||||
a = 0.2f;
|
||||
scale = this.particleBaseSize * 0.25f;
|
||||
} else {
|
||||
r = (float)this.currentMistColor.getRed() / 255.0f;
|
||||
g = (float)this.currentMistColor.getGreen() / 255.0f;
|
||||
b = (float)this.currentMistColor.getBlue() / 255.0f;
|
||||
a = 0.15f;
|
||||
scale = this.particleBaseSize * 0.333f;
|
||||
}
|
||||
SmokeParticleOptions options = new SmokeParticleOptions(scale * (0.8f + this.random.nextFloat() * 0.4f), lifetime, r, g, b, a, false, 0.0f, 0.0f, null);
|
||||
this.level.m_6493_((ParticleOptions)options, true, spawnX, spawnY + 0.05, spawnZ, motionX, motionY, motionZ);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
|
||||
import com.vinlanx.explosionoverhaul.ModSounds;
|
||||
import com.vinlanx.explosionoverhaul.client.AnimationSoundManager;
|
||||
import com.vinlanx.explosionoverhaul.client.BackgroundParticle;
|
||||
import com.vinlanx.explosionoverhaul.client.FirstTimeScreen;
|
||||
import com.vinlanx.explosionoverhaul.client.IntroMusicManager;
|
||||
import com.vinlanx.explosionoverhaul.client.SpriteSheetAnimator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
public class GuideSlidesScreen
|
||||
extends Screen {
|
||||
private static final SlideData[] SLIDES = new SlideData[]{new SlideData("claster_slide.png", 177, "Cluster TNT \u2013 If you place more than two TNT blocks next to each other, the explosion will be much stronger!"), new SlideData("cave_slide.png", 121, "Caves \u2013 If an explosion happens on the surface while you're underground, you'll hear a terrifying rumble, and the ground and dripstones will start to crumble!"), new SlideData("glass_slide.png", 98, "Glass Shattering \u2013 Explosions create shockwaves! Be careful when working with explosives near settlements."), new SlideData("lamp_slide.png", 154, "Lamp Flickering \u2013 If an explosion happens near lamps, the lights will start to flicker."), new SlideData("speed_of_sound_slide.png", 140, "Speed of Sound \u2013 Explosions travel at the speed of sound. You can also enable \"Epic Mode\" in the settings!")};
|
||||
private static final int FRAME_WIDTH = 854;
|
||||
private static final int FRAME_HEIGHT = 480;
|
||||
private static final int COLUMNS = 14;
|
||||
private static final int ROWS = 14;
|
||||
private static final int FPS = 24;
|
||||
private static final int COLOR_BG = -15921907;
|
||||
private static final int COLOR_ACCENT_ORANGE = -881908;
|
||||
private static final int COLOR_ACCENT_RED = -4250588;
|
||||
private static final int COLOR_ACCENT_ROSE = -2529701;
|
||||
private static final int COLOR_ACCENT_DARK_RED = -10939115;
|
||||
private static final int COLOR_TEXT = -1;
|
||||
private static final int COLOR_PROGRESS_BG = Integer.MIN_VALUE;
|
||||
private static final int COLOR_PROGRESS_FILL = -881908;
|
||||
private static final float FADE_IN_DURATION = 1.5f;
|
||||
private static final float SLIDE_TRANSITION_DURATION = 1.0f;
|
||||
private static final float AUTO_ADVANCE_DELAY = 0.5f;
|
||||
private int currentSlideIndex = 0;
|
||||
private SpriteSheetAnimator currentAnimator;
|
||||
private float fadeAlpha = 0.0f;
|
||||
private boolean fadingIn = true;
|
||||
private float fadeTime = 0.0f;
|
||||
private boolean isTransitioning = false;
|
||||
private float transitionTime = 0.0f;
|
||||
private int transitionToIndex = -1;
|
||||
private float transitionAlpha = 0.0f;
|
||||
private SpriteSheetAnimator nextAnimator;
|
||||
private float autoAdvanceTimer = 0.0f;
|
||||
private boolean waitingForAutoAdvance = false;
|
||||
private Queue<Integer> transitionQueue = new LinkedList<Integer>();
|
||||
private int animationX;
|
||||
private int animationY;
|
||||
private int animationWidth;
|
||||
private int animationHeight;
|
||||
private int progressBarX;
|
||||
private int progressBarY;
|
||||
private int progressBarWidth;
|
||||
private int progressBarHeight;
|
||||
private int leftArrowX;
|
||||
private int leftArrowY;
|
||||
private int arrowSize;
|
||||
private int rightArrowX;
|
||||
private int rightArrowY;
|
||||
private boolean leftArrowHovered = false;
|
||||
private boolean rightArrowHovered = false;
|
||||
private float leftArrowScale = 1.0f;
|
||||
private float rightArrowScale = 1.0f;
|
||||
private int continueButtonX;
|
||||
private int continueButtonY;
|
||||
private int continueButtonWidth;
|
||||
private int continueButtonHeight;
|
||||
private boolean continueButtonHovered = false;
|
||||
private float continueButtonScale = 1.0f;
|
||||
private List<BackgroundParticle> particles = new ArrayList<BackgroundParticle>();
|
||||
private RandomSource random = RandomSource.m_216327_();
|
||||
private long lastFrameTime = System.currentTimeMillis();
|
||||
private IntroMusicManager musicManager;
|
||||
|
||||
public GuideSlidesScreen() {
|
||||
super((Component)Component.m_237113_((String)"Guide Slides"));
|
||||
}
|
||||
|
||||
protected void m_7856_() {
|
||||
int i;
|
||||
super.m_7856_();
|
||||
this.fadingIn = true;
|
||||
this.fadeTime = 0.0f;
|
||||
this.fadeAlpha = 0.0f;
|
||||
this.isTransitioning = false;
|
||||
this.waitingForAutoAdvance = false;
|
||||
this.autoAdvanceTimer = 0.0f;
|
||||
this.lastFrameTime = System.currentTimeMillis();
|
||||
this.musicManager = IntroMusicManager.getInstance();
|
||||
this.loadSlide(this.currentSlideIndex);
|
||||
int maxWidth = (int)((float)this.f_96543_ * 0.76f);
|
||||
int maxHeight = (int)((float)this.f_96544_ * 0.65f);
|
||||
float aspectRatio = 1.7791667f;
|
||||
if ((float)maxWidth / aspectRatio <= (float)maxHeight) {
|
||||
this.animationWidth = maxWidth;
|
||||
this.animationHeight = (int)((float)maxWidth / aspectRatio);
|
||||
} else {
|
||||
this.animationHeight = maxHeight;
|
||||
this.animationWidth = (int)((float)maxHeight * aspectRatio);
|
||||
}
|
||||
this.animationX = (this.f_96543_ - this.animationWidth) / 2;
|
||||
this.animationY = (int)((float)this.f_96544_ * 0.12f);
|
||||
this.progressBarWidth = this.animationWidth;
|
||||
this.progressBarHeight = (int)((float)this.f_96544_ * 0.025f);
|
||||
this.progressBarX = this.animationX;
|
||||
this.progressBarY = this.animationY + this.animationHeight + (int)((float)this.f_96544_ * 0.03f);
|
||||
this.arrowSize = (int)((float)this.f_96544_ * 0.08f);
|
||||
int arrowGap = (int)((float)this.f_96543_ * 0.02f);
|
||||
this.leftArrowX = this.animationX - this.arrowSize - arrowGap;
|
||||
this.leftArrowY = this.animationY + (this.animationHeight - this.arrowSize) / 2;
|
||||
this.rightArrowX = this.animationX + this.animationWidth + arrowGap;
|
||||
this.rightArrowY = this.animationY + (this.animationHeight - this.arrowSize) / 2;
|
||||
this.continueButtonWidth = (int)((float)this.f_96543_ * 0.15f);
|
||||
this.continueButtonHeight = (int)((float)this.f_96544_ * 0.06f);
|
||||
this.continueButtonX = (this.f_96543_ - this.continueButtonWidth) / 2;
|
||||
this.continueButtonY = (int)((float)this.f_96544_ * 0.88f);
|
||||
for (i = 0; i < 30; ++i) {
|
||||
this.particles.add(BackgroundParticle.createSpark(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
for (i = 0; i < 10; ++i) {
|
||||
this.particles.add(BackgroundParticle.createEmber(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
for (i = 0; i < 5; ++i) {
|
||||
this.particles.add(BackgroundParticle.createSmoke(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSlide(int index) {
|
||||
if (index < 0 || index >= SLIDES.length) {
|
||||
return;
|
||||
}
|
||||
if (this.currentAnimator != null) {
|
||||
this.currentAnimator.close();
|
||||
}
|
||||
SlideData slide = SLIDES[index];
|
||||
this.currentAnimator = new SpriteSheetAnimator(slide.spriteSheet, 854, 480, 14, 14, slide.totalFrames, 24);
|
||||
this.currentAnimator.load();
|
||||
this.registerSoundCallbacks(index, this.currentAnimator);
|
||||
this.currentAnimator.play();
|
||||
ExplosionOverhaul.LOGGER.info("Loaded guide slide {} - texture created fresh", (Object)index);
|
||||
}
|
||||
|
||||
private void registerSoundCallbacks(int slideIndex, SpriteSheetAnimator animator) {
|
||||
switch (slideIndex) {
|
||||
case 0: {
|
||||
animator.registerFrameCallback(43, AnimationSoundManager::playRandomFarPower2Sound);
|
||||
animator.registerFrameCallback(132, AnimationSoundManager::playRandomSuperfar4Sound);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
animator.registerFrameCallback(43, AnimationSoundManager::playRandomMediumCavePower4Sound);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
animator.registerFrameCallback(30, AnimationSoundManager::playRandomFarPower3Sound);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
animator.registerFrameCallback(34, AnimationSoundManager::playRandomFarPower2Sound);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
animator.registerFrameCallback(30, AnimationSoundManager::playRandomFarPower2Sound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void m_86600_() {
|
||||
float progress;
|
||||
super.m_86600_();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
float deltaTime = Math.min((float)(currentTime - this.lastFrameTime) / 1000.0f, 0.1f);
|
||||
this.lastFrameTime = currentTime;
|
||||
if (this.fadingIn) {
|
||||
this.fadeTime += deltaTime;
|
||||
progress = Math.min(1.0f, this.fadeTime / 1.5f);
|
||||
this.fadeAlpha = this.easeOutCubic(progress);
|
||||
if (this.fadeTime >= 1.5f) {
|
||||
this.fadingIn = false;
|
||||
this.fadeAlpha = 1.0f;
|
||||
}
|
||||
}
|
||||
if (this.isTransitioning) {
|
||||
this.transitionTime += deltaTime;
|
||||
progress = Math.min(1.0f, this.transitionTime / 1.0f);
|
||||
this.transitionAlpha = this.easeInOutCubic(progress);
|
||||
if (this.transitionTime >= 1.0f) {
|
||||
this.isTransitioning = false;
|
||||
this.currentSlideIndex = this.transitionToIndex;
|
||||
if (this.currentAnimator != null) {
|
||||
this.currentAnimator.close();
|
||||
}
|
||||
this.currentAnimator = this.nextAnimator;
|
||||
this.nextAnimator = null;
|
||||
this.transitionToIndex = -1;
|
||||
this.waitingForAutoAdvance = false;
|
||||
this.autoAdvanceTimer = 0.0f;
|
||||
ExplosionOverhaul.LOGGER.info("Transition complete to slide {}", (Object)this.currentSlideIndex);
|
||||
if (!this.transitionQueue.isEmpty()) {
|
||||
int nextIndex = this.transitionQueue.poll();
|
||||
ExplosionOverhaul.LOGGER.info("Processing queued transition to slide {}", (Object)nextIndex);
|
||||
this.startTransition(nextIndex);
|
||||
}
|
||||
} else if (this.transitionAlpha >= 0.5f && this.nextAnimator == null && this.transitionToIndex >= 0 && this.transitionToIndex < SLIDES.length) {
|
||||
SlideData slide = SLIDES[this.transitionToIndex];
|
||||
this.nextAnimator = new SpriteSheetAnimator(slide.spriteSheet, 854, 480, 14, 14, slide.totalFrames, 24);
|
||||
this.nextAnimator.load();
|
||||
this.registerSoundCallbacks(this.transitionToIndex, this.nextAnimator);
|
||||
this.nextAnimator.play();
|
||||
ExplosionOverhaul.LOGGER.info("Created next slide {} animator at transition midpoint", (Object)this.transitionToIndex);
|
||||
}
|
||||
}
|
||||
if (this.currentAnimator != null && !this.isTransitioning) {
|
||||
this.currentAnimator.tick(deltaTime);
|
||||
}
|
||||
float scaleSpeed = 0.2f;
|
||||
float targetScale = 1.1f;
|
||||
this.leftArrowScale = Mth.m_14179_((float)scaleSpeed, (float)this.leftArrowScale, (float)(this.leftArrowHovered ? targetScale : 1.0f));
|
||||
this.rightArrowScale = Mth.m_14179_((float)scaleSpeed, (float)this.rightArrowScale, (float)(this.rightArrowHovered ? targetScale : 1.0f));
|
||||
this.continueButtonScale = Mth.m_14179_((float)scaleSpeed, (float)this.continueButtonScale, (float)(this.continueButtonHovered ? targetScale : 1.0f));
|
||||
this.particles.removeIf(p -> {
|
||||
p.tick(deltaTime);
|
||||
return p.isDead() || p.x < -50.0f || p.x > (float)(this.f_96543_ + 50) || p.y < -50.0f || p.y > (float)(this.f_96544_ + 50);
|
||||
});
|
||||
if (this.random.m_188501_() < 0.1f) {
|
||||
this.particles.add(BackgroundParticle.createSpark(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
if (this.random.m_188501_() < 0.03f) {
|
||||
this.particles.add(BackgroundParticle.createEmber(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
if (this.random.m_188501_() < 0.01f) {
|
||||
this.particles.add(BackgroundParticle.createSmoke(this.random, this.f_96543_, this.f_96544_));
|
||||
}
|
||||
if (this.musicManager != null) {
|
||||
this.musicManager.tick(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void startTransition(int toIndex) {
|
||||
if (toIndex < 0 || toIndex >= SLIDES.length || this.isTransitioning) {
|
||||
return;
|
||||
}
|
||||
this.isTransitioning = true;
|
||||
this.transitionTime = 0.0f;
|
||||
this.transitionAlpha = 0.0f;
|
||||
this.transitionToIndex = toIndex;
|
||||
this.waitingForAutoAdvance = false;
|
||||
this.autoAdvanceTimer = 0.0f;
|
||||
ExplosionOverhaul.LOGGER.info("Starting transition from slide {} to {}", (Object)this.currentSlideIndex, (Object)toIndex);
|
||||
}
|
||||
|
||||
public void m_88315_(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
|
||||
graphics.m_280509_(0, 0, this.f_96543_, this.f_96544_, -15921907);
|
||||
if (this.fadeAlpha < 0.01f) {
|
||||
return;
|
||||
}
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
this.renderBackgroundParticles(graphics, this.fadeAlpha * 0.6f);
|
||||
if (this.isTransitioning) {
|
||||
float currentAlpha = 1.0f - this.transitionAlpha;
|
||||
float nextAlpha = this.transitionAlpha;
|
||||
if (this.currentAnimator != null && currentAlpha > 0.01f) {
|
||||
this.renderAnimation(graphics, this.currentAnimator, this.fadeAlpha * currentAlpha);
|
||||
}
|
||||
if (this.nextAnimator != null && nextAlpha > 0.01f) {
|
||||
this.renderAnimation(graphics, this.nextAnimator, this.fadeAlpha * nextAlpha);
|
||||
}
|
||||
} else if (this.currentAnimator != null) {
|
||||
this.renderAnimation(graphics, this.currentAnimator, this.fadeAlpha);
|
||||
}
|
||||
this.renderGuideText(graphics, this.fadeAlpha);
|
||||
this.renderArrows(graphics, mouseX, mouseY, this.fadeAlpha);
|
||||
this.renderContinueButton(graphics, mouseX, mouseY, this.fadeAlpha);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
private void renderBackgroundParticles(GuiGraphics graphics, float alpha) {
|
||||
for (BackgroundParticle p : this.particles) {
|
||||
float particleAlpha = p.getAlpha();
|
||||
float finalAlpha = particleAlpha * alpha;
|
||||
int colorWithAlpha = p.color & 0xFFFFFF | (int)(finalAlpha * 255.0f) << 24;
|
||||
switch (p.type) {
|
||||
case SPARK: {
|
||||
float sparkLen = p.size * 3.0f;
|
||||
float sparkAngle = (float)Math.atan2(p.vy, p.vx);
|
||||
int ex = (int)((double)p.x + Math.cos(sparkAngle) * (double)sparkLen);
|
||||
int ey = (int)((double)p.y + Math.sin(sparkAngle) * (double)sparkLen);
|
||||
this.drawLine(graphics, (int)p.x, (int)p.y, ex, ey, colorWithAlpha);
|
||||
break;
|
||||
}
|
||||
case EMBER: {
|
||||
int emberSize = (int)p.size;
|
||||
graphics.m_280509_((int)p.x - emberSize, (int)p.y - emberSize, (int)p.x + emberSize, (int)p.y + emberSize, colorWithAlpha);
|
||||
break;
|
||||
}
|
||||
case FLASH: {
|
||||
int flashSize = (int)(p.size * 0.7f);
|
||||
int flashColor = colorWithAlpha & 0xFFFFFF | (int)(finalAlpha * 180.0f) << 24;
|
||||
graphics.m_280509_((int)p.x - flashSize, (int)p.y - flashSize, (int)p.x + flashSize, (int)p.y + flashSize, flashColor);
|
||||
break;
|
||||
}
|
||||
case SMOKE: {
|
||||
int smokeSize = (int)p.size;
|
||||
int smokeColor = colorWithAlpha & 0xFFFFFF | (int)(finalAlpha * 60.0f) << 24;
|
||||
graphics.m_280509_((int)p.x - smokeSize, (int)p.y - smokeSize, (int)p.x + smokeSize, (int)p.y + smokeSize, smokeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderAnimation(GuiGraphics graphics, SpriteSheetAnimator animator, float alpha) {
|
||||
ResourceLocation texture = animator.getTextureLocation();
|
||||
if (texture == null) {
|
||||
return;
|
||||
}
|
||||
RenderSystem.setShader(GameRenderer::m_172817_);
|
||||
RenderSystem.setShaderTexture((int)0, (ResourceLocation)texture);
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)alpha);
|
||||
graphics.m_280411_(texture, this.animationX, this.animationY, this.animationWidth, this.animationHeight, 0.0f, 0.0f, 854, 480, 854, 480);
|
||||
int glowColor = (int)(alpha * 32.0f) << 24 | 0xF28B0C;
|
||||
int borderThickness = 2;
|
||||
graphics.m_280509_(this.animationX - borderThickness, this.animationY - borderThickness, this.animationX + this.animationWidth + borderThickness, this.animationY, glowColor);
|
||||
graphics.m_280509_(this.animationX - borderThickness, this.animationY + this.animationHeight, this.animationX + this.animationWidth + borderThickness, this.animationY + this.animationHeight + borderThickness, glowColor);
|
||||
graphics.m_280509_(this.animationX - borderThickness, this.animationY, this.animationX, this.animationY + this.animationHeight, glowColor);
|
||||
graphics.m_280509_(this.animationX + this.animationWidth, this.animationY, this.animationX + this.animationWidth + borderThickness, this.animationY + this.animationHeight, glowColor);
|
||||
}
|
||||
|
||||
private void renderProgressBar(GuiGraphics graphics, float alpha) {
|
||||
if (this.currentAnimator == null) {
|
||||
return;
|
||||
}
|
||||
int currentFrame = this.currentAnimator.getCurrentFrame();
|
||||
int totalFrames = GuideSlidesScreen.SLIDES[this.currentSlideIndex].totalFrames;
|
||||
float progress = (float)currentFrame / (float)totalFrames;
|
||||
int bgColor = (int)(alpha * 128.0f) << 24 | 0;
|
||||
graphics.m_280509_(this.progressBarX, this.progressBarY, this.progressBarX + this.progressBarWidth, this.progressBarY + this.progressBarHeight, bgColor);
|
||||
int fillWidth = (int)((float)this.progressBarWidth * progress);
|
||||
int fillColor = (int)(alpha * 255.0f) << 24 | 0xF28B0C;
|
||||
graphics.m_280509_(this.progressBarX, this.progressBarY, this.progressBarX + fillWidth, this.progressBarY + this.progressBarHeight, fillColor);
|
||||
if (fillWidth > 0) {
|
||||
int glowColor = (int)(alpha * 64.0f) << 24 | 0xF28B0C;
|
||||
graphics.m_280509_(this.progressBarX + fillWidth - 4, this.progressBarY - 1, this.progressBarX + fillWidth, this.progressBarY + this.progressBarHeight + 1, glowColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderGuideText(GuiGraphics graphics, float alpha) {
|
||||
String text = GuideSlidesScreen.SLIDES[this.currentSlideIndex].guideText;
|
||||
int textColor = (int)(alpha * 255.0f) << 24 | 0xFFFFFF;
|
||||
int textY = this.animationY + this.animationHeight + (int)((float)this.f_96544_ * 0.04f);
|
||||
int maxLineWidth = this.animationWidth;
|
||||
List<String> lines = this.wrapText(text, maxLineWidth);
|
||||
Objects.requireNonNull(this.f_96547_);
|
||||
int lineHeight = 9 + 4;
|
||||
int totalTextHeight = lines.size() * lineHeight;
|
||||
int startY = textY;
|
||||
for (int i = 0; i < lines.size(); ++i) {
|
||||
String line = lines.get(i);
|
||||
int lineWidth = this.f_96547_.m_92895_(line);
|
||||
int x = this.animationX + (this.animationWidth - lineWidth) / 2;
|
||||
graphics.m_280056_(this.f_96547_, line, x, startY + i * lineHeight, textColor, true);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> wrapText(String text, int maxWidth) {
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
String[] words = text.split(" ");
|
||||
StringBuilder currentLine = new StringBuilder();
|
||||
for (String word : words) {
|
||||
Object testLine = currentLine.length() > 0 ? currentLine + " " + word : word;
|
||||
int width = this.f_96547_.m_92895_((String)testLine);
|
||||
if (width > maxWidth && currentLine.length() > 0) {
|
||||
lines.add(currentLine.toString());
|
||||
currentLine = new StringBuilder(word);
|
||||
continue;
|
||||
}
|
||||
if (currentLine.length() > 0) {
|
||||
currentLine.append(" ");
|
||||
}
|
||||
currentLine.append(word);
|
||||
}
|
||||
if (currentLine.length() > 0) {
|
||||
lines.add(currentLine.toString());
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
private void renderArrows(GuiGraphics graphics, int mouseX, int mouseY, float alpha) {
|
||||
this.leftArrowHovered = this.isPointInArrow(mouseX, mouseY, this.leftArrowX, this.leftArrowY, this.arrowSize);
|
||||
this.rightArrowHovered = this.isPointInArrow(mouseX, mouseY, this.rightArrowX, this.rightArrowY, this.arrowSize);
|
||||
if (this.currentSlideIndex > 0) {
|
||||
this.renderArrow(graphics, this.leftArrowX, this.leftArrowY, this.arrowSize, true, this.leftArrowScale, this.leftArrowHovered, alpha);
|
||||
}
|
||||
if (this.currentSlideIndex < SLIDES.length - 1) {
|
||||
this.renderArrow(graphics, this.rightArrowX, this.rightArrowY, this.arrowSize, false, this.rightArrowScale, this.rightArrowHovered, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderArrow(GuiGraphics graphics, int x, int y, int size, boolean pointLeft, float scale, boolean hovered, float alpha) {
|
||||
int scaledSize = (int)((float)size * scale);
|
||||
int offset = (scaledSize - size) / 2;
|
||||
int drawX = x - offset;
|
||||
int drawY = y - offset;
|
||||
int bgColor = hovered ? (int)(alpha * 192.0f) << 24 | 0xF28B0C : (int)(alpha * 128.0f) << 24 | 0x591515;
|
||||
this.fillCircle(graphics, drawX + scaledSize / 2, drawY + scaledSize / 2, scaledSize / 2, bgColor);
|
||||
int arrowColor = (int)(alpha * 255.0f) << 24 | 0xFFFFFF;
|
||||
int centerX = drawX + scaledSize / 2;
|
||||
int centerY = drawY + scaledSize / 2;
|
||||
int arrowWidth = scaledSize / 3;
|
||||
int arrowHeight = scaledSize / 4;
|
||||
if (pointLeft) {
|
||||
this.fillTriangle(graphics, centerX + arrowWidth / 2, centerY - arrowHeight, centerX + arrowWidth / 2, centerY + arrowHeight, centerX - arrowWidth / 2, centerY, arrowColor);
|
||||
} else {
|
||||
this.fillTriangle(graphics, centerX - arrowWidth / 2, centerY - arrowHeight, centerX - arrowWidth / 2, centerY + arrowHeight, centerX + arrowWidth / 2, centerY, arrowColor);
|
||||
}
|
||||
if (hovered) {
|
||||
int glowColor = (int)(alpha * 64.0f) << 24 | 0xF28B0C;
|
||||
this.fillCircle(graphics, drawX + scaledSize / 2, drawY + scaledSize / 2, scaledSize / 2 + 4, glowColor);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPointInArrow(int px, int py, int arrowX, int arrowY, int size) {
|
||||
int centerX = arrowX + size / 2;
|
||||
int dx = px - centerX;
|
||||
int centerY = arrowY + size / 2;
|
||||
int dy = py - centerY;
|
||||
int radius = size / 2;
|
||||
return dx * dx + dy * dy <= radius * radius;
|
||||
}
|
||||
|
||||
private void fillCircle(GuiGraphics graphics, int centerX, int centerY, int radius, int color) {
|
||||
for (int y = -radius; y <= radius; ++y) {
|
||||
for (int x = -radius; x <= radius; ++x) {
|
||||
if (x * x + y * y > radius * radius) continue;
|
||||
graphics.m_280509_(centerX + x, centerY + y, centerX + x + 1, centerY + y + 1, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillTriangle(GuiGraphics graphics, int x1, int y1, int x2, int y2, int x3, int y3, int color) {
|
||||
int minY = Math.min(y1, Math.min(y2, y3));
|
||||
int maxY = Math.max(y1, Math.max(y2, y3));
|
||||
for (int y = minY; y <= maxY; ++y) {
|
||||
int x;
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
if (this.checkIntersection(y, y1, y2, x1, x2)) {
|
||||
x = this.interpolate(y, y1, y2, x1, x2);
|
||||
minX = Math.min(minX, x);
|
||||
maxX = Math.max(maxX, x);
|
||||
}
|
||||
if (this.checkIntersection(y, y2, y3, x2, x3)) {
|
||||
x = this.interpolate(y, y2, y3, x2, x3);
|
||||
minX = Math.min(minX, x);
|
||||
maxX = Math.max(maxX, x);
|
||||
}
|
||||
if (this.checkIntersection(y, y3, y1, x3, x1)) {
|
||||
x = this.interpolate(y, y3, y1, x3, x1);
|
||||
minX = Math.min(minX, x);
|
||||
maxX = Math.max(maxX, x);
|
||||
}
|
||||
if (minX == Integer.MAX_VALUE || maxX == Integer.MIN_VALUE) continue;
|
||||
graphics.m_280509_(minX, y, maxX + 1, y + 1, color);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkIntersection(int y, int y1, int y2, int x1, int x2) {
|
||||
return y >= Math.min(y1, y2) && y <= Math.max(y1, y2) && y1 != y2;
|
||||
}
|
||||
|
||||
private int interpolate(int y, int y1, int y2, int x1, int x2) {
|
||||
return x1 + (y - y1) * (x2 - x1) / (y2 - y1);
|
||||
}
|
||||
|
||||
public boolean m_6375_(double mouseX, double mouseY, int button) {
|
||||
if (button == 0) {
|
||||
if (this.isPointInButton((int)mouseX, (int)mouseY)) {
|
||||
this.playButtonSound();
|
||||
this.transitionToFirstTimeScreen();
|
||||
return true;
|
||||
}
|
||||
if (this.currentSlideIndex > 0 && this.isPointInArrow((int)mouseX, (int)mouseY, this.leftArrowX, this.leftArrowY, this.arrowSize)) {
|
||||
Integer nextTransition;
|
||||
this.playButtonSound();
|
||||
int targetIndex = this.currentSlideIndex - 1;
|
||||
this.transitionQueue.offer(targetIndex);
|
||||
if (!this.isTransitioning && (nextTransition = this.transitionQueue.poll()) != null) {
|
||||
this.startTransition(nextTransition);
|
||||
}
|
||||
ExplosionOverhaul.LOGGER.info("Queued left arrow transition to {}, queue size: {}", (Object)targetIndex, (Object)this.transitionQueue.size());
|
||||
return true;
|
||||
}
|
||||
if (this.currentSlideIndex < SLIDES.length - 1 && this.isPointInArrow((int)mouseX, (int)mouseY, this.rightArrowX, this.rightArrowY, this.arrowSize)) {
|
||||
Integer nextTransition;
|
||||
this.playButtonSound();
|
||||
int targetIndex = this.currentSlideIndex + 1;
|
||||
this.transitionQueue.offer(targetIndex);
|
||||
if (!this.isTransitioning && (nextTransition = this.transitionQueue.poll()) != null) {
|
||||
this.startTransition(nextTransition);
|
||||
}
|
||||
ExplosionOverhaul.LOGGER.info("Queued right arrow transition to {}, queue size: {}", (Object)targetIndex, (Object)this.transitionQueue.size());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.m_6375_(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
private boolean isPointInButton(int px, int py) {
|
||||
return px >= this.continueButtonX && px <= this.continueButtonX + this.continueButtonWidth && py >= this.continueButtonY && py <= this.continueButtonY + this.continueButtonHeight;
|
||||
}
|
||||
|
||||
private void renderContinueButton(GuiGraphics graphics, int mouseX, int mouseY, float alpha) {
|
||||
this.continueButtonHovered = this.isPointInButton(mouseX, mouseY);
|
||||
int scaledWidth = (int)((float)this.continueButtonWidth * this.continueButtonScale);
|
||||
int scaledHeight = (int)((float)this.continueButtonHeight * this.continueButtonScale);
|
||||
int offsetX = (scaledWidth - this.continueButtonWidth) / 2;
|
||||
int offsetY = (scaledHeight - this.continueButtonHeight) / 2;
|
||||
int drawX = this.continueButtonX - offsetX;
|
||||
int drawY = this.continueButtonY - offsetY;
|
||||
int bgColor = this.continueButtonHovered ? (int)(alpha * 220.0f) << 24 | 0xF28B0C : (int)(alpha * 160.0f) << 24 | 0x591515;
|
||||
graphics.m_280509_(drawX, drawY, drawX + scaledWidth, drawY + scaledHeight, bgColor);
|
||||
if (this.continueButtonHovered) {
|
||||
int glowColor = (int)(alpha * 80.0f) << 24 | 0xF28B0C;
|
||||
int border = 3;
|
||||
graphics.m_280509_(drawX - border, drawY - border, drawX + scaledWidth + border, drawY, glowColor);
|
||||
graphics.m_280509_(drawX - border, drawY + scaledHeight, drawX + scaledWidth + border, drawY + scaledHeight + border, glowColor);
|
||||
graphics.m_280509_(drawX - border, drawY, drawX, drawY + scaledHeight, glowColor);
|
||||
graphics.m_280509_(drawX + scaledWidth, drawY, drawX + scaledWidth + border, drawY + scaledHeight, glowColor);
|
||||
}
|
||||
String text = "Skip Guide";
|
||||
int textColor = (int)(alpha * 255.0f) << 24 | 0xFFFFFF;
|
||||
int textX = drawX + (scaledWidth - this.f_96547_.m_92895_(text)) / 2;
|
||||
Objects.requireNonNull(this.f_96547_);
|
||||
int textY = drawY + (scaledHeight - 9) / 2;
|
||||
graphics.m_280056_(this.f_96547_, text, textX, textY, textColor, true);
|
||||
}
|
||||
|
||||
public boolean m_6913_() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean m_7043_() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void m_7861_() {
|
||||
super.m_7861_();
|
||||
this.transitionQueue.clear();
|
||||
if (this.currentAnimator != null) {
|
||||
this.currentAnimator.close();
|
||||
}
|
||||
if (this.nextAnimator != null) {
|
||||
this.nextAnimator.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void transitionToFirstTimeScreen() {
|
||||
ExplosionOverhaul.LOGGER.info("All guide slides complete. Transitioning to FirstTimeScreen.");
|
||||
Minecraft.m_91087_().m_91152_((Screen)new FirstTimeScreen());
|
||||
}
|
||||
|
||||
private void drawLine(GuiGraphics graphics, int x1, int y1, int x2, int y2, int color) {
|
||||
int dx = Math.abs(x2 - x1);
|
||||
int dy = Math.abs(y2 - y1);
|
||||
int sx = x1 < x2 ? 1 : -1;
|
||||
int sy = y1 < y2 ? 1 : -1;
|
||||
int err = dx - dy;
|
||||
for (int steps = 0; steps < 200; ++steps) {
|
||||
graphics.m_280509_(x1, y1, x1 + 1, y1 + 1, color);
|
||||
if (x1 == x2 && y1 == y2) break;
|
||||
int e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err -= dy;
|
||||
x1 += sx;
|
||||
}
|
||||
if (e2 >= dx) continue;
|
||||
err += dx;
|
||||
y1 += sy;
|
||||
}
|
||||
}
|
||||
|
||||
private float easeOutCubic(float t) {
|
||||
return 1.0f - (float)Math.pow(1.0f - t, 3.0);
|
||||
}
|
||||
|
||||
private float easeInCubic(float t) {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
private float easeInOutCubic(float t) {
|
||||
return t < 0.5f ? 4.0f * t * t * t : 1.0f - (float)Math.pow(-2.0f * t + 2.0f, 3.0) / 2.0f;
|
||||
}
|
||||
|
||||
private void playButtonSound() {
|
||||
try {
|
||||
Minecraft minecraft = Minecraft.m_91087_();
|
||||
if (minecraft.m_91106_() != null) {
|
||||
minecraft.m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.BUTTON_SOUND.get()), (float)1.0f, (float)1.0f));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
ExplosionOverhaul.LOGGER.warn("Failed to play button sound", (Throwable)e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SlideData {
|
||||
final ResourceLocation spriteSheet;
|
||||
final int totalFrames;
|
||||
final String guideText;
|
||||
|
||||
SlideData(String filename, int frames, String text) {
|
||||
this.spriteSheet = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)("intro_gui/" + filename));
|
||||
this.totalFrames = frames;
|
||||
this.guideText = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
|
||||
import com.vinlanx.explosionoverhaul.ModSounds;
|
||||
import com.vinlanx.explosionoverhaul.client.FadingMusicInstance;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
|
||||
public class IntroMusicManager {
|
||||
private static IntroMusicManager INSTANCE;
|
||||
private static final float FADE_OUT_DURATION = 3.0f;
|
||||
private FadingMusicInstance musicInstance;
|
||||
private SimpleSoundInstance boomInstance;
|
||||
private boolean isPlaying = false;
|
||||
private boolean isFadingOut = false;
|
||||
private boolean vanillaMusicBlocked = false;
|
||||
|
||||
private IntroMusicManager() {
|
||||
}
|
||||
|
||||
public static IntroMusicManager getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new IntroMusicManager();
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (this.isPlaying) {
|
||||
return;
|
||||
}
|
||||
SoundManager soundManager = Minecraft.m_91087_().m_91106_();
|
||||
this.musicInstance = new FadingMusicInstance((SoundEvent)ModSounds.INTRO_MUSIC.get(), 0.25f, SoundSource.MASTER);
|
||||
soundManager.m_120367_((SoundInstance)this.musicInstance);
|
||||
ExplosionOverhaul.LOGGER.info("Started intro music with FadingMusicInstance");
|
||||
this.boomInstance = SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.INTRO_BOOM.get()), (float)1.0f, (float)1.0f);
|
||||
soundManager.m_120367_((SoundInstance)this.boomInstance);
|
||||
this.isPlaying = true;
|
||||
this.vanillaMusicBlocked = true;
|
||||
this.stopVanillaMusic();
|
||||
}
|
||||
|
||||
public void startFadeOut() {
|
||||
ExplosionOverhaul.LOGGER.info("startFadeOut called. isPlaying={}, isFadingOut={}", (Object)this.isPlaying, (Object)this.isFadingOut);
|
||||
if (!this.isPlaying || this.isFadingOut) {
|
||||
ExplosionOverhaul.LOGGER.warn("Cannot start fade out - already fading or not playing");
|
||||
return;
|
||||
}
|
||||
if (this.musicInstance != null) {
|
||||
this.musicInstance.fadeOutAndStop(3.0f);
|
||||
ExplosionOverhaul.LOGGER.info("Started smooth fade out over {} seconds", (Object)Float.valueOf(3.0f));
|
||||
}
|
||||
this.isFadingOut = true;
|
||||
}
|
||||
|
||||
public void stopBoomSound() {
|
||||
if (this.boomInstance != null) {
|
||||
try {
|
||||
SoundManager soundManager = Minecraft.m_91087_().m_91106_();
|
||||
soundManager.m_120399_((SoundInstance)this.boomInstance);
|
||||
this.boomInstance = null;
|
||||
ExplosionOverhaul.LOGGER.info("Boom sound stopped.");
|
||||
}
|
||||
catch (Exception e) {
|
||||
ExplosionOverhaul.LOGGER.warn("Failed to stop boom sound: {}", (Object)e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
ExplosionOverhaul.LOGGER.info("stop() called! Stack trace:", (Throwable)new Exception("Music stop trace"));
|
||||
SoundManager soundManager = Minecraft.m_91087_().m_91106_();
|
||||
if (this.musicInstance != null) {
|
||||
soundManager.m_120399_((SoundInstance)this.musicInstance);
|
||||
this.musicInstance = null;
|
||||
}
|
||||
if (this.boomInstance != null) {
|
||||
soundManager.m_120399_((SoundInstance)this.boomInstance);
|
||||
this.boomInstance = null;
|
||||
}
|
||||
this.isPlaying = false;
|
||||
this.isFadingOut = false;
|
||||
this.vanillaMusicBlocked = false;
|
||||
ExplosionOverhaul.LOGGER.info("Music stopped completely.");
|
||||
}
|
||||
|
||||
public void tick(float deltaTime) {
|
||||
if (!this.isPlaying) {
|
||||
return;
|
||||
}
|
||||
if (this.isFadingOut && this.musicInstance != null) {
|
||||
if (this.musicInstance.hasFinishedFading()) {
|
||||
ExplosionOverhaul.LOGGER.info("Music fade out complete!");
|
||||
this.stop();
|
||||
return;
|
||||
}
|
||||
float currentVolume = this.musicInstance.getCurrentVolume();
|
||||
if (currentVolume % 0.1f < 0.05f) {
|
||||
ExplosionOverhaul.LOGGER.info("Fade out progress - volume: {}", (Object)Float.valueOf(currentVolume));
|
||||
}
|
||||
}
|
||||
if (this.vanillaMusicBlocked) {
|
||||
this.stopVanillaMusic();
|
||||
}
|
||||
}
|
||||
|
||||
private void stopVanillaMusic() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.m_91397_() != null) {
|
||||
mc.m_91397_().m_120186_();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
return this.isPlaying;
|
||||
}
|
||||
|
||||
public boolean isFadingOut() {
|
||||
return this.isFadingOut;
|
||||
}
|
||||
|
||||
public boolean isVanillaMusicBlocked() {
|
||||
return this.vanillaMusicBlocked;
|
||||
}
|
||||
|
||||
public float getFadeProgress() {
|
||||
if (!this.isFadingOut || this.musicInstance == null) {
|
||||
return 0.0f;
|
||||
}
|
||||
return 1.0f - this.musicInstance.getCurrentVolume();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.client.IntroMusicManager;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber(modid="explosionoverhaul", bus=Mod.EventBusSubscriber.Bus.FORGE, value={Dist.CLIENT})
|
||||
public class IntroMusicTickHandler {
|
||||
private static long lastTickTime = System.currentTimeMillis();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase != TickEvent.Phase.END) {
|
||||
return;
|
||||
}
|
||||
IntroMusicManager musicManager = IntroMusicManager.getInstance();
|
||||
if (musicManager.isPlaying() || musicManager.isFadingOut()) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
float deltaTime = (float)(currentTime - lastTickTime) / 1000.0f;
|
||||
lastTickTime = currentTime;
|
||||
musicManager.tick(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.vinlanx.explosionoverhaul.client.IntroMusicManager;
|
||||
import com.vinlanx.explosionoverhaul.client.SpriteSheetAnimator;
|
||||
import com.vinlanx.explosionoverhaul.client.VinlanxSplashScreen;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class IntroSplashScreen
|
||||
extends Screen {
|
||||
private static final ResourceLocation SPRITE_SHEET = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)"intro_gui/screen.png");
|
||||
private static final int FRAME_WIDTH = 1280;
|
||||
private static final int FRAME_HEIGHT = 720;
|
||||
private static final int COLUMNS = 14;
|
||||
private static final int ROWS = 14;
|
||||
private static final int TOTAL_FRAMES = 196;
|
||||
private static final int FPS = 24;
|
||||
private SpriteSheetAnimator animator;
|
||||
private IntroMusicManager musicManager;
|
||||
private long lastFrameTime = System.currentTimeMillis();
|
||||
private boolean animationFinished = false;
|
||||
|
||||
public IntroSplashScreen() {
|
||||
super((Component)Component.m_237113_((String)"Intro"));
|
||||
}
|
||||
|
||||
protected void m_7856_() {
|
||||
super.m_7856_();
|
||||
this.animator = new SpriteSheetAnimator(SPRITE_SHEET, 1280, 720, 14, 14, 196, 24);
|
||||
this.animator.load();
|
||||
this.animator.play();
|
||||
this.musicManager = IntroMusicManager.getInstance();
|
||||
this.musicManager.start();
|
||||
}
|
||||
|
||||
public void m_86600_() {
|
||||
super.m_86600_();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
float deltaTime = (float)(currentTime - this.lastFrameTime) / 1000.0f;
|
||||
this.lastFrameTime = currentTime;
|
||||
if (this.animator != null) {
|
||||
this.animator.tick(deltaTime);
|
||||
if (this.animator.getCurrentFrame() >= 195 && !this.animationFinished) {
|
||||
this.animationFinished = true;
|
||||
this.transitionToFirstTimeScreen();
|
||||
}
|
||||
}
|
||||
if (this.musicManager != null) {
|
||||
this.musicManager.tick(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
public void m_88315_(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
|
||||
int displayWidth;
|
||||
int displayHeight;
|
||||
graphics.m_280509_(0, 0, this.f_96543_, this.f_96544_, -16777216);
|
||||
if (this.animator == null) {
|
||||
return;
|
||||
}
|
||||
ResourceLocation texture = this.animator.getTextureLocation();
|
||||
if (texture == null) {
|
||||
return;
|
||||
}
|
||||
float screenAspectRatio = (float)this.f_96543_ / (float)this.f_96544_;
|
||||
float targetAspectRatio = 1.7777778f;
|
||||
if (screenAspectRatio > targetAspectRatio) {
|
||||
displayHeight = this.f_96544_;
|
||||
displayWidth = (int)((float)displayHeight * targetAspectRatio);
|
||||
} else {
|
||||
displayWidth = this.f_96543_;
|
||||
displayHeight = (int)((float)displayWidth / targetAspectRatio);
|
||||
}
|
||||
int x = (this.f_96543_ - displayWidth) / 2;
|
||||
int y = (this.f_96544_ - displayHeight) / 2;
|
||||
RenderSystem.setShader(GameRenderer::m_172817_);
|
||||
RenderSystem.setShaderTexture((int)0, (ResourceLocation)texture);
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
graphics.m_280411_(texture, x, y, displayWidth, displayHeight, 0.0f, 0.0f, 1280, 720, 1280, 720);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
public boolean m_6913_() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean m_7933_(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == 256) {
|
||||
this.skipToNext();
|
||||
return true;
|
||||
}
|
||||
return super.m_7933_(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public boolean m_6375_(double mouseX, double mouseY, int button) {
|
||||
this.skipToNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean m_7043_() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void m_7861_() {
|
||||
super.m_7861_();
|
||||
if (this.animator != null) {
|
||||
this.animator.close();
|
||||
}
|
||||
if (this.musicManager != null) {
|
||||
this.musicManager.stopBoomSound();
|
||||
}
|
||||
}
|
||||
|
||||
private void skipToNext() {
|
||||
this.animationFinished = true;
|
||||
this.transitionToFirstTimeScreen();
|
||||
}
|
||||
|
||||
private void transitionToFirstTimeScreen() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (!(mc.f_91080_ instanceof TitleScreen)) {
|
||||
mc.execute(() -> {
|
||||
if (mc.f_91080_ instanceof TitleScreen) {
|
||||
mc.m_91152_((Screen)new VinlanxSplashScreen());
|
||||
} else {
|
||||
mc.m_91152_((Screen)new VinlanxSplashScreen());
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
mc.m_91152_((Screen)new VinlanxSplashScreen());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.ParticleRenderType;
|
||||
import net.minecraft.client.particle.SpriteSet;
|
||||
import net.minecraft.client.particle.TextureSheetParticle;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3fc;
|
||||
|
||||
public class LineSparkParticle
|
||||
extends TextureSheetParticle {
|
||||
private final SpriteSet spriteSet;
|
||||
private float length;
|
||||
private float width;
|
||||
private final float initialLength;
|
||||
private static final Vec3 UP = new Vec3(0.0, 1.0, 0.0);
|
||||
|
||||
public LineSparkParticle(ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed, SpriteSet pSpriteSet) {
|
||||
super(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed);
|
||||
float baseSize;
|
||||
this.f_107215_ = pXSpeed;
|
||||
this.f_107216_ = pYSpeed;
|
||||
this.f_107217_ = pZSpeed;
|
||||
this.spriteSet = pSpriteSet;
|
||||
this.f_172258_ = 0.97f;
|
||||
this.f_107226_ = 0.4f;
|
||||
this.f_107225_ = 250 + this.f_107223_.m_188503_(150);
|
||||
this.initialLength = baseSize = (this.f_107223_.m_188501_() * 0.4f + 0.5f) * 1.2f;
|
||||
this.length = 0.1f;
|
||||
this.width = baseSize * 0.125f;
|
||||
this.m_108337_(this.spriteSet.m_5819_(0, 1));
|
||||
}
|
||||
|
||||
public void m_5989_() {
|
||||
float stretchFactor;
|
||||
super.m_5989_();
|
||||
float lifeProgress = (float)this.f_107224_ / (float)this.f_107225_;
|
||||
if (lifeProgress < 0.2f) {
|
||||
t = lifeProgress / 0.2f;
|
||||
stretchFactor = 1.0f - (1.0f - t) * (1.0f - t);
|
||||
} else if (lifeProgress < 0.7f) {
|
||||
stretchFactor = 1.0f;
|
||||
} else {
|
||||
t = (lifeProgress - 0.7f) / 0.3f;
|
||||
stretchFactor = 1.0f - t * t;
|
||||
}
|
||||
stretchFactor = Mth.m_14036_((float)stretchFactor, (float)0.0f, (float)1.0f);
|
||||
float distanceScale = 1.0f;
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc.f_91074_ != null) {
|
||||
double distSqr = mc.f_91074_.m_20275_(this.f_107212_, this.f_107213_, this.f_107214_);
|
||||
double dist = Math.sqrt(distSqr);
|
||||
if (dist > 171.0) {
|
||||
distanceScale = 2.5f;
|
||||
} else if (dist > 141.0) {
|
||||
distanceScale = 2.2f;
|
||||
} else if (dist > 101.0) {
|
||||
distanceScale = 2.0f;
|
||||
} else if (dist > 71.0) {
|
||||
distanceScale = 1.7f;
|
||||
} else if (dist > 50.0) {
|
||||
distanceScale = 1.5f;
|
||||
}
|
||||
}
|
||||
this.length = this.initialLength * stretchFactor * distanceScale;
|
||||
this.width = this.initialLength * 0.125f * distanceScale;
|
||||
if (this.length < 0.01f) {
|
||||
this.length = 0.01f;
|
||||
}
|
||||
this.f_107230_ = Mth.m_14089_((float)((float)this.f_107224_ / (float)this.f_107225_ * (float)Math.PI / 2.0f));
|
||||
if (this.f_107218_) {
|
||||
this.m_107274_();
|
||||
}
|
||||
}
|
||||
|
||||
public ParticleRenderType m_7556_() {
|
||||
return ParticleRenderType.f_107431_;
|
||||
}
|
||||
|
||||
public void m_5744_(VertexConsumer buffer, Camera camera, float partialTicks) {
|
||||
Vec3 camPos = camera.m_90583_();
|
||||
float x = (float)(Mth.m_14139_((double)partialTicks, (double)this.f_107209_, (double)this.f_107212_) - camPos.m_7096_());
|
||||
float y = (float)(Mth.m_14139_((double)partialTicks, (double)this.f_107210_, (double)this.f_107213_) - camPos.m_7098_());
|
||||
float z = (float)(Mth.m_14139_((double)partialTicks, (double)this.f_107211_, (double)this.f_107214_) - camPos.m_7094_());
|
||||
Vec3 velocity = new Vec3(this.f_107215_, this.f_107216_, this.f_107217_).m_82541_();
|
||||
if (velocity.m_82556_() < 1.0E-4) {
|
||||
return;
|
||||
}
|
||||
Vec3 viewVector = new Vec3((double)x, (double)y, (double)z).m_82541_();
|
||||
Vec3 rightVector = velocity.m_82537_(viewVector).m_82541_();
|
||||
if (rightVector.m_82556_() < 1.0E-4 && (rightVector = velocity.m_82537_(UP).m_82541_()).m_82556_() < 1.0E-4) {
|
||||
rightVector = velocity.m_82537_(new Vec3(1.0, 0.0, 0.0)).m_82541_();
|
||||
}
|
||||
Vec3 upVector = rightVector.m_82537_(velocity).m_82541_();
|
||||
Vector3f[] vertices = new Vector3f[]{new Vector3f(x, y, z).add((Vector3fc)upVector.m_82490_((double)(-this.length / 2.0f)).m_82549_(rightVector.m_82490_((double)(this.width / 2.0f))).m_252839_()), new Vector3f(x, y, z).add((Vector3fc)upVector.m_82490_((double)(this.length / 2.0f)).m_82549_(rightVector.m_82490_((double)(this.width / 2.0f))).m_252839_()), new Vector3f(x, y, z).add((Vector3fc)upVector.m_82490_((double)(this.length / 2.0f)).m_82549_(rightVector.m_82490_((double)(-this.width / 2.0f))).m_252839_()), new Vector3f(x, y, z).add((Vector3fc)upVector.m_82490_((double)(-this.length / 2.0f)).m_82549_(rightVector.m_82490_((double)(-this.width / 2.0f))).m_252839_())};
|
||||
int worldLight = this.m_6355_(partialTicks);
|
||||
this.renderQuad(buffer, vertices, this.f_108321_, this.f_107227_, this.f_107228_, this.f_107229_, this.f_107230_, worldLight);
|
||||
TextureAtlasSprite emissiveSprite = this.spriteSet.m_5819_(1, 1);
|
||||
int fullBright = 240;
|
||||
this.renderQuad(buffer, vertices, emissiveSprite, 1.0f, 1.0f, 1.0f, this.f_107230_, fullBright);
|
||||
}
|
||||
|
||||
private void renderQuad(VertexConsumer buffer, Vector3f[] vertices, TextureAtlasSprite sprite, float r, float g, float b, float a, int light) {
|
||||
float u0 = sprite.m_118409_();
|
||||
float u1 = sprite.m_118410_();
|
||||
float v0 = sprite.m_118411_();
|
||||
float v1 = sprite.m_118412_();
|
||||
buffer.m_5483_((double)vertices[0].x(), (double)vertices[0].y(), (double)vertices[0].z()).m_7421_(u1, v1).m_85950_(r, g, b, a).m_85969_(light).m_5752_();
|
||||
buffer.m_5483_((double)vertices[1].x(), (double)vertices[1].y(), (double)vertices[1].z()).m_7421_(u1, v0).m_85950_(r, g, b, a).m_85969_(light).m_5752_();
|
||||
buffer.m_5483_((double)vertices[2].x(), (double)vertices[2].y(), (double)vertices[2].z()).m_7421_(u0, v0).m_85950_(r, g, b, a).m_85969_(light).m_5752_();
|
||||
buffer.m_5483_((double)vertices[3].x(), (double)vertices[3].y(), (double)vertices[3].z()).m_7421_(u0, v1).m_85950_(r, g, b, a).m_85969_(light).m_5752_();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.client.LineSparkParticle;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.ParticleProvider;
|
||||
import net.minecraft.client.particle.SpriteSet;
|
||||
import net.minecraft.core.particles.SimpleParticleType;
|
||||
|
||||
public class LineSparkParticleProvider
|
||||
implements ParticleProvider<SimpleParticleType> {
|
||||
private final SpriteSet spriteSet;
|
||||
|
||||
public LineSparkParticleProvider(SpriteSet pSprites) {
|
||||
this.spriteSet = pSprites;
|
||||
}
|
||||
|
||||
public Particle createParticle(SimpleParticleType pType, ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
return new LineSparkParticle(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, this.spriteSet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.client.SoundEngineAudioQueue;
|
||||
import com.vinlanx.explosionoverhaul.client.SoundPhysicsCompatibility;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.lwjgl.openal.ALC10;
|
||||
import org.lwjgl.openal.EXTEfx;
|
||||
|
||||
@OnlyIn(value=Dist.CLIENT)
|
||||
@Mod.EventBusSubscriber(modid="explosionoverhaul", value={Dist.CLIENT})
|
||||
public class LowPassConcussionEffect {
|
||||
private static final float HF_MIN = 0.01f;
|
||||
private static final float HF_MAX = 1.0f;
|
||||
private static final float GAIN_MIN = 0.1f;
|
||||
private static final int FADE_IN_TICKS = 40;
|
||||
private static final int FADE_OUT_TICKS = 100;
|
||||
private static volatile Phase phase = Phase.IDLE;
|
||||
private static volatile int holdTicks = 0;
|
||||
private static volatile int ticksInPhase = 0;
|
||||
private static final AtomicBoolean efxAvailable = new AtomicBoolean(false);
|
||||
private static volatile int filterId = 0;
|
||||
private static volatile float targetHfMin = 1.0f;
|
||||
private static volatile float targetGainMin = 1.0f;
|
||||
private static volatile float currentDeafnessGain = 1.0f;
|
||||
public static volatile boolean enabled = true;
|
||||
public static volatile boolean debugShowChat = false;
|
||||
private static volatile boolean compatibilityMode = false;
|
||||
private static volatile float lastAppliedHf = 1.0f;
|
||||
private static volatile float lastAppliedGain = 1.0f;
|
||||
|
||||
public static void setDeafnessGain(float gain) {
|
||||
currentDeafnessGain = Math.max(0.0f, Math.min(1.0f, gain));
|
||||
if (phase == Phase.IDLE && currentDeafnessGain < 0.99f && !compatibilityMode) {
|
||||
SoundEngineAudioQueue.enqueueAudio(() -> LowPassConcussionEffect.ensureFilterExists());
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureFilterExists() {
|
||||
if (!efxAvailable.get()) {
|
||||
long ctx = ALC10.alcGetCurrentContext();
|
||||
long dev = ALC10.alcGetContextsDevice((long)ctx);
|
||||
if (!ALC10.alcIsExtensionPresent((long)dev, (CharSequence)"ALC_EXT_EFX")) {
|
||||
efxAvailable.set(false);
|
||||
return;
|
||||
}
|
||||
efxAvailable.set(true);
|
||||
}
|
||||
if (filterId == 0) {
|
||||
filterId = EXTEfx.alGenFilters();
|
||||
EXTEfx.alFilteri((int)filterId, (int)32769, (int)1);
|
||||
EXTEfx.alFilterf((int)filterId, (int)1, (float)1.0f);
|
||||
EXTEfx.alFilterf((int)filterId, (int)2, (float)1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public static void start(int seconds, float intensity) {
|
||||
Minecraft mc;
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
if (seconds < 1) {
|
||||
seconds = 1;
|
||||
}
|
||||
if (seconds > 600) {
|
||||
seconds = 600;
|
||||
}
|
||||
float effectiveIntensity = (Boolean)Config.CLIENT.enableLowPass.get() != false ? intensity : 0.001f;
|
||||
float addedStrength = Math.max(0.0f, Math.min(1.0f, effectiveIntensity));
|
||||
if (phase != Phase.IDLE) {
|
||||
float currentStrength = (1.0f - targetHfMin) / 0.99f;
|
||||
float totalStrength = Math.min(1.0f, currentStrength + addedStrength);
|
||||
targetHfMin = 1.0f - totalStrength * 0.99f;
|
||||
holdTicks = Math.min(2000, holdTicks + seconds * 20);
|
||||
if (phase == Phase.FADE_OUT) {
|
||||
phase = Phase.HOLD;
|
||||
ticksInPhase = 0;
|
||||
}
|
||||
} else {
|
||||
float totalStrength = addedStrength;
|
||||
targetHfMin = 1.0f - totalStrength * 0.99f;
|
||||
targetGainMin = 0.1f;
|
||||
holdTicks = seconds * 20;
|
||||
ticksInPhase = 0;
|
||||
phase = Phase.FADE_IN;
|
||||
}
|
||||
if (!compatibilityMode) {
|
||||
SoundEngineAudioQueue.enqueueAudio(() -> {
|
||||
try {
|
||||
LowPassConcussionEffect.ensureFilterExists();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
efxAvailable.set(false);
|
||||
}
|
||||
});
|
||||
SoundEngineAudioQueue.drainNow();
|
||||
}
|
||||
if (debugShowChat && (mc = Minecraft.m_91087_()) != null && mc.f_91074_ != null) {
|
||||
mc.f_91074_.m_5661_((Component)Component.m_237113_((String)("Low pass test queued for " + seconds + "s (strength=" + addedStrength + ")")), false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void start(int seconds, float intensity, double effectivePercent, String visibility, int intensityPercent) {
|
||||
Minecraft mc;
|
||||
if (debugShowChat && (mc = Minecraft.m_91087_()) != null && mc.f_91074_ != null) {
|
||||
mc.f_91074_.m_5661_((Component)Component.m_237113_((String)"__________________________________________"), false);
|
||||
String msg = String.format("\u041f\u043e\u0442\u0443\u0436\u043d\u0456\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0443\u0437\u0456\u0457 %.1f%% (%s) \u2014 \u0421\u0438\u043b\u0430 \u043f\u0440\u0438\u0433\u043b\u0443\u0448\u0435\u043d\u043d\u044f %d%%, \u0427\u0430\u0441 \u043f\u0440\u0438\u0433\u043b\u0443\u0448\u0435\u043d\u043d\u044f %.1f \u0441\u0435\u043a", effectivePercent, visibility, intensityPercent, (double)seconds);
|
||||
mc.f_91074_.m_5661_((Component)Component.m_237113_((String)msg).m_130940_(ChatFormatting.WHITE), false);
|
||||
mc.f_91074_.m_5661_((Component)Component.m_237113_((String)"__________________________________________"), false);
|
||||
}
|
||||
LowPassConcussionEffect.start(seconds, intensity);
|
||||
}
|
||||
|
||||
public static void stop() {
|
||||
phase = Phase.IDLE;
|
||||
ticksInPhase = 0;
|
||||
lastAppliedHf = 1.0f;
|
||||
lastAppliedGain = 1.0f;
|
||||
targetGainMin = 1.0f;
|
||||
if (compatibilityMode) {
|
||||
SoundEngineAudioQueue.enqueueAudio(SoundPhysicsCompatibility::reapplyDirectFilterParameters);
|
||||
}
|
||||
SoundEngineAudioQueue.enqueueAudio(() -> {
|
||||
if (filterId != 0) {
|
||||
try {
|
||||
EXTEfx.alFilterf((int)filterId, (int)2, (float)1.0f);
|
||||
EXTEfx.alFilterf((int)filterId, (int)1, (float)1.0f);
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
// empty catch block
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isActive() {
|
||||
return phase != Phase.IDLE || currentDeafnessGain < 0.99f;
|
||||
}
|
||||
|
||||
public static int getFilterId() {
|
||||
return filterId;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase == TickEvent.Phase.END) {
|
||||
LowPassConcussionEffect.onClientTick();
|
||||
}
|
||||
}
|
||||
|
||||
public static void onClientTick() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
if (mc != null && mc.m_91104_()) {
|
||||
return;
|
||||
}
|
||||
if (currentDeafnessGain < 0.99f || phase != Phase.IDLE) {
|
||||
float hf = 1.0f;
|
||||
float gainInterp = 1.0f;
|
||||
if (phase != Phase.IDLE) {
|
||||
++ticksInPhase;
|
||||
switch (phase) {
|
||||
case FADE_IN: {
|
||||
float t = Math.min(1.0f, (float)ticksInPhase / 40.0f);
|
||||
hf = LowPassConcussionEffect.lerp(1.0f, targetHfMin, LowPassConcussionEffect.easeOutQuad(t));
|
||||
gainInterp = LowPassConcussionEffect.lerp(1.0f, targetGainMin, LowPassConcussionEffect.easeOutQuad(t));
|
||||
if (ticksInPhase < 40) break;
|
||||
phase = Phase.HOLD;
|
||||
ticksInPhase = 0;
|
||||
hf = targetHfMin;
|
||||
gainInterp = targetGainMin;
|
||||
break;
|
||||
}
|
||||
case HOLD: {
|
||||
hf = targetHfMin;
|
||||
gainInterp = targetGainMin;
|
||||
if (ticksInPhase < holdTicks) break;
|
||||
phase = Phase.FADE_OUT;
|
||||
ticksInPhase = 0;
|
||||
break;
|
||||
}
|
||||
case FADE_OUT: {
|
||||
float t = Math.min(1.0f, (float)ticksInPhase / 100.0f);
|
||||
hf = LowPassConcussionEffect.lerp(targetHfMin, 1.0f, LowPassConcussionEffect.easeInQuad(t));
|
||||
gainInterp = LowPassConcussionEffect.lerp(targetGainMin, 1.0f, LowPassConcussionEffect.easeInQuad(t));
|
||||
if (ticksInPhase < 100) break;
|
||||
LowPassConcussionEffect.stop();
|
||||
hf = 1.0f;
|
||||
gainInterp = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
float combinedGain = Math.max(0.0f, Math.min(1.0f, gainInterp * currentDeafnessGain));
|
||||
LowPassConcussionEffect.applyFilterParamsOnAudioThread(hf, combinedGain);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyFilterParamsOnAudioThread(float hf, float gain) {
|
||||
float clampedHf = Math.max(0.01f, Math.min(1.0f, hf));
|
||||
float clampedGain = Math.max(0.0f, Math.min(1.0f, gain));
|
||||
lastAppliedHf = clampedHf;
|
||||
lastAppliedGain = clampedGain;
|
||||
if (compatibilityMode) {
|
||||
SoundEngineAudioQueue.enqueueAudio(SoundPhysicsCompatibility::reapplyDirectFilterParameters);
|
||||
}
|
||||
if (!efxAvailable.get()) {
|
||||
return;
|
||||
}
|
||||
int fid = filterId;
|
||||
if (fid == 0) {
|
||||
return;
|
||||
}
|
||||
SoundEngineAudioQueue.enqueueAudio(() -> {
|
||||
try {
|
||||
EXTEfx.alFilterf((int)fid, (int)2, (float)clampedHf);
|
||||
EXTEfx.alFilterf((int)fid, (int)1, (float)clampedGain);
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
// empty catch block
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static float lerp(float a, float b, float t) {
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
private static float easeOutQuad(float t) {
|
||||
return 1.0f - (1.0f - t) * (1.0f - t);
|
||||
}
|
||||
|
||||
private static float easeInQuad(float t) {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
private static String alErrorName(int err) {
|
||||
return switch (err) {
|
||||
case 0 -> "AL_NO_ERROR";
|
||||
case 40961 -> "AL_INVALID_NAME";
|
||||
case 40962 -> "AL_INVALID_ENUM";
|
||||
case 40963 -> "AL_INVALID_VALUE";
|
||||
case 40964 -> "AL_INVALID_OPERATION";
|
||||
case 40965 -> "AL_OUT_OF_MEMORY";
|
||||
default -> "AL_UNKNOWN_ERROR";
|
||||
};
|
||||
}
|
||||
|
||||
public static void setCompatibilityMode(boolean compatibilityActive) {
|
||||
compatibilityMode = compatibilityActive;
|
||||
}
|
||||
|
||||
public static float getCurrentHfMultiplier() {
|
||||
return Math.max(0.01f, Math.min(1.0f, lastAppliedHf));
|
||||
}
|
||||
|
||||
public static float getCurrentGainMultiplier() {
|
||||
return Math.max(0.0f, Math.min(1.0f, lastAppliedGain));
|
||||
}
|
||||
|
||||
public static void attachFilterToSource(int sourceId) {
|
||||
if (sourceId <= 0) {
|
||||
return;
|
||||
}
|
||||
if (!efxAvailable.get() || filterId == 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (!AL10.alIsSource((int)sourceId)) {
|
||||
return;
|
||||
}
|
||||
if (AL10.alGetSourcei((int)sourceId, (int)514) == 1) {
|
||||
return;
|
||||
}
|
||||
AL10.alSourcei((int)sourceId, (int)131077, (int)filterId);
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
// empty catch block
|
||||
}
|
||||
}
|
||||
|
||||
public static void detachFilterFromSource(int sourceId) {
|
||||
try {
|
||||
if (AL10.alIsSource((int)sourceId)) {
|
||||
AL10.alSourcei((int)sourceId, (int)131077, (int)0);
|
||||
}
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
// empty catch block
|
||||
}
|
||||
}
|
||||
|
||||
private static enum Phase {
|
||||
IDLE,
|
||||
FADE_IN,
|
||||
HOLD,
|
||||
FADE_OUT;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.CraterDeformer;
|
||||
import com.vinlanx.explosionoverhaul.client.BlacklistScreen;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionTextureManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
|
||||
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
||||
import me.shedaniel.clothconfig2.api.ConfigCategory;
|
||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.neoforged.neoforge.common.ForgeConfigSpec;
|
||||
|
||||
public class ModConfigScreen {
|
||||
public static Screen create(Screen parent) {
|
||||
ConfigBuilder builder = ConfigBuilder.create().setParentScreen(parent).setTitle((Component)Component.m_237115_((String)"title.explosionoverhaul.config"));
|
||||
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
|
||||
ConfigCategory serverCategory = builder.getOrCreateCategory((Component)Component.m_237115_((String)"category.explosionoverhaul.server"));
|
||||
builder.setSavingRunnable(() -> {
|
||||
Config.CLIENT_SPEC.save();
|
||||
Config.COMMON_SPEC.save();
|
||||
ExplosionTextureManager.getInstance().reload();
|
||||
});
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableFallingBlocks"), ((Boolean)Config.COMMON.enableFallingBlocks.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableFallingBlocks")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableFallingBlocks).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableExplosionClustering"), ((Boolean)Config.COMMON.enableExplosionClustering.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableExplosionClustering")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableExplosionClustering).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableCraterDestruction"), ((Boolean)Config.COMMON.enableCraterDestruction.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableCraterDestruction")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableCraterDestruction).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableGlassBreaking"), ((Boolean)Config.COMMON.enableGlassBreaking.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableGlassBreaking")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableGlassBreaking).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableDripstoneFalling"), ((Boolean)Config.COMMON.enableDripstoneFalling.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableDripstoneFalling")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableDripstoneFalling).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableLampFlicker"), ((Boolean)Config.COMMON.enableLampFlicker.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableLampFlicker")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableLampFlicker).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.craterSettingsHeader")).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.craterSizeMultiplier"), (int)((Double)Config.COMMON.craterSizeMultiplier.get() * 100.0), 10, 5000).setDefaultValue(100).setTextGetter(value -> {
|
||||
double val = (double)value.intValue() / 100.0;
|
||||
Object text = String.format("%.2fx", val);
|
||||
if (val > 10.0) {
|
||||
text = (String)text + " \u00a7c(EXTREME!)";
|
||||
}
|
||||
return Component.m_237113_((String)text);
|
||||
}).setTooltipSupplier(value -> Optional.of(ModConfigScreen.generateCraterTable((double)value.intValue() / 100.0))).setSaveConsumer(newValue -> Config.COMMON.craterSizeMultiplier.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.craterCoreRatio"), (int)((Double)Config.COMMON.craterCoreRatio.get() * 100.0), 10, 95).setDefaultValue(70).setTextGetter(value -> Component.m_237113_((String)(value + "%"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.craterCoreRatio")}).setSaveConsumer(newValue -> Config.COMMON.craterCoreRatio.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)"--- Async Crater Pipeline ---")).setTooltip(new Component[]{Component.m_237113_((String)"Computes crater geometry off-thread and applies block changes in batches per tick.")}).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableAsyncCrater"), ((Boolean)Config.COMMON.enableAsyncCrater.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableAsyncCrater")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableAsyncCrater).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.maxClusterPower"), ((Integer)Config.COMMON.maxClusterPower.get()).intValue(), 4, 1000).setDefaultValue(100).setTextGetter(v -> Component.m_237113_((String)String.valueOf(v))).setTooltipSupplier(v -> {
|
||||
if (v >= 500) {
|
||||
return Optional.of(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.maxClusterPower"), Component.m_237113_((String)""), Component.m_237113_((String)"\u26a0 ").m_130944_(new ChatFormatting[]{ChatFormatting.RED, ChatFormatting.BOLD}).m_7220_((Component)Component.m_237115_((String)"warning.explosionoverhaul.crashRisk").m_130944_(new ChatFormatting[]{ChatFormatting.DARK_RED, ChatFormatting.BOLD}))});
|
||||
}
|
||||
if (v >= 300) {
|
||||
return Optional.of(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.maxClusterPower"), Component.m_237113_((String)""), Component.m_237115_((String)"warning.explosionoverhaul.severeRenderingLag").m_130940_(ChatFormatting.DARK_RED)});
|
||||
}
|
||||
if (v >= 150) {
|
||||
return Optional.of(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.maxClusterPower"), Component.m_237113_((String)""), Component.m_237115_((String)"warning.explosionoverhaul.renderingLag").m_130940_(ChatFormatting.GOLD)});
|
||||
}
|
||||
return Optional.of(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.maxClusterPower")});
|
||||
}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.maxClusterPower).set(arg_0)).build());
|
||||
int availableThreads = Runtime.getRuntime().availableProcessors();
|
||||
int maxThreadsForSystem = Math.min(32, availableThreads);
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.craterMaxThreads"), ((Integer)Config.COMMON.craterMaxThreads.get()).intValue(), 0, maxThreadsForSystem).setDefaultValue(0).setTextGetter(v -> Component.m_237113_((String)(v == 0 ? "Auto (" + availableThreads + ")" : String.valueOf(v)))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.craterMaxThreads")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.craterMaxThreads).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.craterApplyBlocksPerTick"), ((Integer)Config.COMMON.craterApplyBlocksPerTick.get()).intValue(), 0, 150000).setDefaultValue(50000).setTextGetter(v -> Component.m_237113_((String)(v + " blocks/tick"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.craterApplyBlocksPerTick")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.craterApplyBlocksPerTick).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.craterMaxFallingBlocksPerTick"), ((Integer)Config.COMMON.craterMaxFallingBlocksPerTick.get()).intValue(), 0, 2000).setDefaultValue(500).setTextGetter(v -> Component.m_237113_((String)(v + " entities/tick"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.craterMaxFallingBlocksPerTick")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.craterMaxFallingBlocksPerTick).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableDirectChunkWrites"), ((Boolean)Config.COMMON.enableDirectChunkWrites.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableDirectChunkWrites")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableDirectChunkWrites).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.craterChunksPerTick"), ((Integer)Config.COMMON.craterChunksPerTick.get()).intValue(), 0, 500).setDefaultValue(120).setTextGetter(v -> Component.m_237113_((String)(v + " chunks/tick"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.craterChunksPerTick")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.craterChunksPerTick).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.glassBreakingSettings")).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.glassBreakingIntervalTicks"), ((Integer)Config.COMMON.glassBreakingIntervalTicks.get()).intValue(), 1, 20).setDefaultValue(1).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.glassBreakingIntervalTicks")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.glassBreakingIntervalTicks).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.glassBlocksPerCycle"), ((Integer)Config.COMMON.glassBlocksPerCycle.get()).intValue(), 10, 500).setDefaultValue(70).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.glassBlocksPerCycle")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.glassBlocksPerCycle).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.lampFlickerSettings")).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.lampFlickerSearchRadius"), ((Integer)Config.COMMON.lampFlickerSearchRadius.get()).intValue(), 1, 100).setDefaultValue(50).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.lampFlickerSearchRadius")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.lampFlickerSearchRadius).set(arg_0)).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.dripstoneFallingSettings")).build());
|
||||
serverCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.dripstoneFallingSearchRadius"), ((Integer)Config.COMMON.dripstoneFallingSearchRadius.get()).intValue(), 1, 100).setDefaultValue(50).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.dripstoneFallingSearchRadius")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.dripstoneFallingSearchRadius).set(arg_0)).build());
|
||||
ConfigCategory ambientCategory = builder.getOrCreateCategory((Component)Component.m_237115_((String)"category.explosionoverhaul.ambient"));
|
||||
Config.Common.Ambient ambientConfig = Config.COMMON.ambient;
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableAmbientExplosions"), ((Boolean)ambientConfig.enableAmbientExplosions.get()).booleanValue()).setDefaultValue(false).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableAmbientExplosions")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)ambientConfig.enableAmbientExplosions).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.minTimeBetweenExplosions"), (Integer)ambientConfig.minTimeBetweenExplosions.get() / 20, 5, 3600).setDefaultValue(60).setTextGetter(value -> Component.m_237113_((String)(value + " s"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.minTimeBetweenExplosions")}).setSaveConsumer(newValue -> ambientConfig.minTimeBetweenExplosions.set((Object)(newValue * 20))).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.maxTimeBetweenExplosions"), (Integer)ambientConfig.maxTimeBetweenExplosions.get() / 20, 10, 3600).setDefaultValue(300).setTextGetter(value -> Component.m_237113_((String)(value + " s"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.maxTimeBetweenExplosions")}).setSaveConsumer(newValue -> ambientConfig.maxTimeBetweenExplosions.set((Object)(newValue * 20))).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.minExplosionDistance"), ((Integer)ambientConfig.minExplosionDistance.get()).intValue(), 100, 10000).setDefaultValue(501).setTextGetter(value -> Component.m_237113_((String)(value + " blocks"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.minExplosionDistance")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)ambientConfig.minExplosionDistance).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.maxExplosionDistance"), ((Integer)ambientConfig.maxExplosionDistance.get()).intValue(), 200, 10000).setDefaultValue(5001).setTextGetter(value -> Component.m_237113_((String)(value + " blocks"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.maxExplosionDistance")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)ambientConfig.maxExplosionDistance).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.maxAmbientExplosionPower"), (int)((Double)ambientConfig.maxAmbientExplosionPower.get() * 10.0), 400, 2000).setDefaultValue(800).setTextGetter(value -> Component.m_237113_((String)String.format("%.1f", (double)value.intValue() / 10.0))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.maxAmbientExplosionPower")}).setSaveConsumer(newValue -> ambientConfig.maxAmbientExplosionPower.set((Object)((double)newValue.intValue() / 10.0))).build());
|
||||
Config.Common.Ambient.Scenarios scenariosConfig = ambientConfig.scenarios;
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.scenariosHeader")).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.scenariosHeader")}).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.singleExplosionWeight"), ((Integer)scenariosConfig.singleExplosionWeight.get()).intValue(), 0, 100).setTextGetter(v -> Component.m_237113_((String)(v + "%"))).setDefaultValue(70).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.singleExplosionWeight).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.chainReactionWeight"), ((Integer)scenariosConfig.chainReactionWeight.get()).intValue(), 0, 100).setTextGetter(v -> Component.m_237113_((String)(v + "%"))).setDefaultValue(15).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.chainReactionWeight).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.shellingWeight"), ((Integer)scenariosConfig.shellingWeight.get()).intValue(), 0, 100).setTextGetter(v -> Component.m_237113_((String)(v + "%"))).setDefaultValue(15).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.shellingWeight).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.chainReactionSettingsHeader")).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.minChainReactionShots"), ((Integer)scenariosConfig.minChainReactionShots.get()).intValue(), 2, 20).setDefaultValue(3).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.minChainReactionShots).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.maxChainReactionShots"), ((Integer)scenariosConfig.maxChainReactionShots.get()).intValue(), 2, 20).setDefaultValue(7).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.maxChainReactionShots).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.minTimeBetweenChainShots"), ((Integer)scenariosConfig.minTimeBetweenChainShots.get()).intValue(), 5, 200).setTextGetter(v -> Component.m_237113_((String)String.format("%.2fs", (double)v.intValue() / 20.0))).setDefaultValue(10).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.minTimeBetweenChainShots).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.maxTimeBetweenChainShots"), ((Integer)scenariosConfig.maxTimeBetweenChainShots.get()).intValue(), 10, 400).setTextGetter(v -> Component.m_237113_((String)String.format("%.2fs", (double)v.intValue() / 20.0))).setDefaultValue(40).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.maxTimeBetweenChainShots).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.shellingSettingsHeader")).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.minShellingDelay"), ((Integer)scenariosConfig.minShellingDelay.get()).intValue(), 20, 400).setTextGetter(v -> Component.m_237113_((String)String.format("%.2fs", (double)v.intValue() / 20.0))).setDefaultValue(40).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.minShellingDelay).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.maxShellingDelay"), ((Integer)scenariosConfig.maxShellingDelay.get()).intValue(), 20, 400).setTextGetter(v -> Component.m_237113_((String)String.format("%.2fs", (double)v.intValue() / 20.0))).setDefaultValue(140).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)scenariosConfig.maxShellingDelay).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.powerTiersHeader")).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.powerTiersHeader")}).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.tier1_weight"), ((Integer)ambientConfig.powerTiers.tier1_weight.get()).intValue(), 0, 100).setTextGetter(v -> Component.m_237113_((String)(v + "%"))).setDefaultValue(50).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)ambientConfig.powerTiers.tier1_weight).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.tier2_weight"), ((Integer)ambientConfig.powerTiers.tier2_weight.get()).intValue(), 0, 100).setTextGetter(v -> Component.m_237113_((String)(v + "%"))).setDefaultValue(25).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)ambientConfig.powerTiers.tier2_weight).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.tier3_weight"), ((Integer)ambientConfig.powerTiers.tier3_weight.get()).intValue(), 0, 100).setTextGetter(v -> Component.m_237113_((String)(v + "%"))).setDefaultValue(15).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)ambientConfig.powerTiers.tier3_weight).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.tier4_weight"), ((Integer)ambientConfig.powerTiers.tier4_weight.get()).intValue(), 0, 100).setTextGetter(v -> Component.m_237113_((String)(v + "%"))).setDefaultValue(8).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)ambientConfig.powerTiers.tier4_weight).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.tier5_weight"), ((Integer)ambientConfig.powerTiers.tier5_weight.get()).intValue(), 0, 100).setTextGetter(v -> Component.m_237113_((String)(v + "%"))).setDefaultValue(2).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)ambientConfig.powerTiers.tier5_weight).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.soundTypesHeader")).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableSurfaceSounds"), ((Boolean)ambientConfig.soundTypes.enableSurfaceSounds.get()).booleanValue()).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableSurfaceSounds")}).setDefaultValue(true).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)ambientConfig.soundTypes.enableSurfaceSounds).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableCaveSounds"), ((Boolean)ambientConfig.soundTypes.enableCaveSounds.get()).booleanValue()).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableCaveSounds")}).setDefaultValue(true).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)ambientConfig.soundTypes.enableCaveSounds).set(arg_0)).build());
|
||||
ambientCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableAmbientCaveDust"), ((Boolean)ambientConfig.soundTypes.enableAmbientCaveDust.get()).booleanValue()).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableAmbientCaveDust")}).setDefaultValue(true).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)ambientConfig.soundTypes.enableAmbientCaveDust).set(arg_0)).build());
|
||||
ConfigCategory renderCategory = builder.getOrCreateCategory((Component)Component.m_237115_((String)"category.explosionoverhaul.render"));
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startEnumSelector((Component)Component.m_237115_((String)"option.explosionoverhaul.glowTextureQuality"), Config.Client.GlowTextureQuality.class, (Enum)((Config.Client.GlowTextureQuality)((Object)Config.CLIENT.glowTextureQuality.get()))).setDefaultValue((Enum)Config.Client.GlowTextureQuality.QUALITY_256).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.glowTextureQuality")}).setSaveConsumer(arg_0 -> Config.CLIENT.glowTextureQuality.set(arg_0)).setEnumNameProvider(value -> Component.m_237113_((String)(value == Config.Client.GlowTextureQuality.QUALITY_64 ? "64x" : "256x"))).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startEnumSelector((Component)Component.m_237115_((String)"option.explosionoverhaul.particleRenderMode"), Config.Client.ParticleRenderMode.class, (Enum)((Config.Client.ParticleRenderMode)((Object)Config.CLIENT.particleRenderMode.get()))).setDefaultValue((Enum)Config.Client.ParticleRenderMode.VANILA).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.particleRenderMode")}).setSaveConsumer(arg_0 -> Config.CLIENT.particleRenderMode.set(arg_0)).setEnumNameProvider(value -> {
|
||||
if (value == Config.Client.ParticleRenderMode.VANILA) {
|
||||
return Component.m_237113_((String)"Vanilla-like");
|
||||
}
|
||||
if (value == Config.Client.ParticleRenderMode.REALISTIC_2) {
|
||||
return Component.m_237113_((String)"Realistic 2");
|
||||
}
|
||||
return Component.m_237113_((String)"Realistic");
|
||||
}).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.particleSizeScale"), (int)((Double)Config.CLIENT.particleSizeScale.get() * 100.0), 10, 500).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)String.format("%.2fx", (double)value.intValue() / 100.0))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.particleSizeScale")}).setSaveConsumer(newValue -> Config.CLIENT.particleSizeScale.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableExplosionParticles"), ((Boolean)Config.CLIENT.enableExplosionParticles.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableExplosionParticles")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableExplosionParticles).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enablePlasmaParticles"), ((Boolean)Config.CLIENT.enablePlasmaParticles.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enablePlasmaParticles")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enablePlasmaParticles).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enablePlasmaSmokeTrail"), ((Boolean)Config.CLIENT.enablePlasmaSmokeTrail.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enablePlasmaSmokeTrail")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enablePlasmaSmokeTrail).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.plasmaSmokeFrequency"), (int)((Double)Config.CLIENT.plasmaSmokeFrequency.get() * 100.0), 0, 100).setDefaultValue(25).setTextGetter(value -> Component.m_237113_((String)(value + "%"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.plasmaSmokeFrequency")}).setSaveConsumer(newValue -> Config.CLIENT.plasmaSmokeFrequency.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.plasmaSmokeCount"), ((Integer)Config.CLIENT.plasmaSmokeCount.get()).intValue(), 0, 5).setDefaultValue(1).setTextGetter(value -> Component.m_237113_((String)String.valueOf(value))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.plasmaSmokeCount")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.CLIENT.plasmaSmokeCount).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableFlashEffect"), ((Boolean)Config.CLIENT.enableFlashEffect.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableFlashEffect")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableFlashEffect).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.flashMaxOpacity"), (int)((Double)Config.CLIENT.flashMaxOpacity.get() * 100.0), 0, 100).setDefaultValue(50).setTextGetter(value -> Component.m_237113_((String)(value + "%"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.flashMaxOpacity")}).setSaveConsumer(newValue -> Config.CLIENT.flashMaxOpacity.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableLineSparks"), ((Boolean)Config.CLIENT.enableLineSparks.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableLineSparks")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableLineSparks).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.lineSparkAmountMultiplier"), (int)((Double)Config.CLIENT.lineSparkAmountMultiplier.get() * 100.0), 0, 500).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)String.format("%d%%", value))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.lineSparkAmountMultiplier")}).setSaveConsumer(newValue -> Config.CLIENT.lineSparkAmountMultiplier.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableGroundDustEffect"), ((Boolean)Config.CLIENT.enableGroundDustEffect.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableGroundDustEffect")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableGroundDustEffect).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.groundDustQuality"), (int)((Double)Config.CLIENT.groundDustQuality.get() * 100.0), 0, 100).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)(value + "%"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.groundDustQuality")}).setSaveConsumer(newValue -> Config.CLIENT.groundDustQuality.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.groundDustRaycastFrequency"), ((Integer)Config.CLIENT.groundDustRaycastFrequency.get()).intValue(), 1, 20).setDefaultValue(10).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.groundDustRaycastFrequency")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.CLIENT.groundDustRaycastFrequency).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableGroundMistEffect"), ((Boolean)Config.CLIENT.enableGroundMistEffect.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableGroundMistEffect")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableGroundMistEffect).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.groundMistQuality"), (int)((Double)Config.CLIENT.groundMistQuality.get() * 100.0), 0, 100).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)(value + "%"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.groundMistQuality")}).setSaveConsumer(newValue -> Config.CLIENT.groundMistQuality.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.groundMistRaycastFrequency"), ((Integer)Config.CLIENT.groundMistRaycastFrequency.get()).intValue(), 1, 20).setDefaultValue(10).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.groundMistRaycastFrequency")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.CLIENT.groundMistRaycastFrequency).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableShockwaveEffect"), ((Boolean)Config.CLIENT.enableShockwaveEffect.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableShockwaveEffect")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableShockwaveEffect).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237113_((String)" ")).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableWindEffect"), ((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableWindEffect")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableWindEffect).set(arg_0)).build());
|
||||
renderCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.windSpeedMultiplier"), (int)((Double)Config.CLIENT.windSpeedMultiplier.get() * 100.0), 100, 200).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)String.format("%.2fx", (double)value.intValue() / 100.0))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.windSpeedMultiplier")}).setSaveConsumer(newValue -> Config.CLIENT.windSpeedMultiplier.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
ConfigCategory cameraCategory = builder.getOrCreateCategory((Component)Component.m_237115_((String)"category.explosionoverhaul.camera"));
|
||||
cameraCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableCameraShake"), ((Boolean)Config.CLIENT.enableCameraShake.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableCameraShake")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableCameraShake).set(arg_0)).build());
|
||||
cameraCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.cameraShakeAmplifier"), (int)((Double)Config.CLIENT.cameraShakeAmplifier.get() * 10.0), 0, 100).setDefaultValue(10).setTextGetter(value -> Component.m_237113_((String)String.format("%.1fx", (double)value.intValue() / 10.0))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.cameraShakeAmplifier")}).setSaveConsumer(newValue -> Config.CLIENT.cameraShakeAmplifier.set((Object)((double)newValue.intValue() / 10.0))).build());
|
||||
cameraCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.cameraServerHeader")).build());
|
||||
cameraCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enablePlayerShake"), ((Boolean)Config.COMMON.enablePlayerShake.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enablePlayerShake")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enablePlayerShake).set(arg_0)).build());
|
||||
cameraCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.playerShakeAmplifier"), (int)((Double)Config.COMMON.playerShakeAmplifier.get() * 10.0), 0, 100).setDefaultValue(10).setTextGetter(value -> Component.m_237113_((String)String.format("%.1fx", (double)value.intValue() / 10.0))).setTooltip(new Component[]{Component.m_237115_((String)"option.explosionoverhaul.playerShakeAmplifier")}).setSaveConsumer(newValue -> Config.COMMON.playerShakeAmplifier.set((Object)((double)newValue.intValue() / 10.0))).build());
|
||||
ConfigCategory scanCategory = builder.getOrCreateCategory((Component)Component.m_237115_((String)"category.explosionoverhaul.scan"));
|
||||
scanCategory.addEntry((AbstractConfigListEntry)entryBuilder.startTextDescription((Component)Component.m_237115_((String)"option.explosionoverhaul.scanSettingsHeader")).build());
|
||||
int availableCores = Runtime.getRuntime().availableProcessors();
|
||||
int maxThreads = Math.min(32, availableCores);
|
||||
scanCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.maxScanThreads"), ((Integer)Config.COMMON.scan.maxScanThreads.get()).intValue(), 0, maxThreads).setDefaultValue(0).setTextGetter(value -> {
|
||||
if (value == 0) {
|
||||
return Component.m_237113_((String)("Auto (" + availableCores + " threads)"));
|
||||
}
|
||||
return Component.m_237113_((String)String.valueOf(value));
|
||||
}).setTooltip(new Component[]{Component.m_237113_((String)("Maximum number of threads to use for chunk scanning.\n0 = Auto-detect (recommended): automatically uses all " + availableCores + " available threads\n1 = Single-threaded (slowest but safest for low-end servers)\n2-" + maxThreads + " = Custom thread count (available range for your system)\nYour system supports up to " + availableCores + " threads.\nMore threads = faster scanning but higher CPU usage."))}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.scan.maxScanThreads).set(arg_0)).build());
|
||||
scanCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.cpuUsagePercent"), ((Integer)Config.COMMON.scan.cpuUsagePercent.get()).intValue(), 1, 100).setDefaultValue(75).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.cpuUsagePercent")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.IntValue)Config.COMMON.scan.cpuUsagePercent).set(arg_0)).build());
|
||||
scanCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableBlockIndexing"), ((Boolean)Config.COMMON.scan.enableBlockIndexing.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableBlockIndexing")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.scan.enableBlockIndexing).set(arg_0)).build());
|
||||
scanCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.showScanProgressHUD"), ((Boolean)Config.COMMON.scan.showScanProgressHUD.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.showScanProgressHUD")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.scan.showScanProgressHUD).set(arg_0)).build());
|
||||
ConfigCategory soundsCategory = builder.getOrCreateCategory((Component)Component.m_237115_((String)"category.explosionoverhaul.sounds"));
|
||||
soundsCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableAdvancedSoundSpeed"), ((Boolean)Config.COMMON.enableAdvancedSoundSpeed.get()).booleanValue()).setDefaultValue(false).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableAdvancedSoundSpeed")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.COMMON.enableAdvancedSoundSpeed).set(arg_0)).build());
|
||||
ConfigCategory concussionCategory = builder.getOrCreateCategory((Component)Component.m_237115_((String)"category.explosionoverhaul.concussion"));
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableConcussion"), ((Boolean)Config.CLIENT.enableConcussion.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableConcussion")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableConcussion).set(arg_0)).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.concussionDurationMultiplier"), (int)((Double)Config.CLIENT.concussionDurationMultiplier.get() * 100.0), 0, 500).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)String.format("%.2fx", (double)value.intValue() / 100.0))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.concussionDurationMultiplier")}).setSaveConsumer(newValue -> Config.CLIENT.concussionDurationMultiplier.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.concussionChanceMultiplier"), (int)((Double)Config.CLIENT.concussionChanceMultiplier.get() * 100.0), 0, 500).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)(value + "%"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.concussionChanceMultiplier")}).setSaveConsumer(newValue -> Config.CLIENT.concussionChanceMultiplier.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableHeartbeatPulse"), ((Boolean)Config.CLIENT.enableHeartbeatPulse.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableHeartbeatPulse")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableHeartbeatPulse).set(arg_0)).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableCameraSway"), ((Boolean)Config.CLIENT.enableCameraSway.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableCameraSway")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableCameraSway).set(arg_0)).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.cameraSwayIntensity"), (int)((Double)Config.CLIENT.cameraSwayIntensity.get() * 100.0), 0, 500).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)String.format("%.2fx", (double)value.intValue() / 100.0))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.cameraSwayIntensity")}).setSaveConsumer(newValue -> Config.CLIENT.cameraSwayIntensity.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableDeafness"), ((Boolean)Config.CLIENT.enableDeafness.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableDeafness")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableDeafness).set(arg_0)).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.enableLowPass"), ((Boolean)Config.CLIENT.enableLowPass.get()).booleanValue()).setDefaultValue(true).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.enableLowPass")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.enableLowPass).set(arg_0)).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.deafnessChanceMultiplier"), (int)((Double)Config.CLIENT.deafnessChanceMultiplier.get() * 100.0), 0, 500).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)(value + "%"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.deafnessChanceMultiplier")}).setSaveConsumer(newValue -> Config.CLIENT.deafnessChanceMultiplier.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startIntSlider((Component)Component.m_237115_((String)"option.explosionoverhaul.lowPassChanceMultiplier"), (int)((Double)Config.CLIENT.lowPassChanceMultiplier.get() * 100.0), 0, 500).setDefaultValue(100).setTextGetter(value -> Component.m_237113_((String)(value + "%"))).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.lowPassChanceMultiplier")}).setSaveConsumer(newValue -> Config.CLIENT.lowPassChanceMultiplier.set((Object)((double)newValue.intValue() / 100.0))).build());
|
||||
concussionCategory.addEntry((AbstractConfigListEntry)entryBuilder.startBooleanToggle((Component)Component.m_237115_((String)"option.explosionoverhaul.showHeartbeatHUD"), ((Boolean)Config.CLIENT.showHeartbeatHUD.get()).booleanValue()).setDefaultValue(false).setTooltip(new Component[]{Component.m_237115_((String)"tooltip.explosionoverhaul.showHeartbeatHUD")}).setSaveConsumer(arg_0 -> ((ForgeConfigSpec.BooleanValue)Config.CLIENT.showHeartbeatHUD).set(arg_0)).build());
|
||||
ConfigCategory blacklistCategory = builder.getOrCreateCategory((Component)Component.m_237115_((String)"category.explosionoverhaul.blacklists"));
|
||||
blacklistCategory.addEntry((AbstractConfigListEntry)new LinkButtonEntry((Component)Component.m_237115_((String)"option.explosionoverhaul.blacklist_button"), (Component)Component.m_237115_((String)"tooltip.explosionoverhaul.blacklist_button"), () -> Minecraft.m_91087_().m_91152_((Screen)new BlacklistScreen(parent))));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static Component[] generateCraterTable(double multiplier) {
|
||||
int[] powerLevels;
|
||||
ArrayList<MutableComponent> lines = new ArrayList<MutableComponent>();
|
||||
lines.add(Component.m_237115_((String)"tooltip.explosionoverhaul.craterSizeMultiplier.title"));
|
||||
lines.add(Component.m_237113_((String)""));
|
||||
lines.add(Component.m_237113_((String)"\u00a7bPower \u00a78| \u00a7aApprox. Diameter"));
|
||||
lines.add(Component.m_237113_((String)"\u00a77--------------------------"));
|
||||
for (int power : powerLevels = new int[]{4, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}) {
|
||||
float baseRadius = CraterDeformer.calculateRadius(power);
|
||||
float diameter = (float)((double)baseRadius * multiplier * 2.0);
|
||||
String formattedLine = String.format("\u00a7f%-12d\u00a78| \u00a7a~%.1f blocks", power, Float.valueOf(diameter));
|
||||
lines.add(Component.m_237113_((String)formattedLine));
|
||||
}
|
||||
lines.add(Component.m_237113_((String)"\u00a77--------------------------"));
|
||||
lines.add(Component.m_237115_((String)"tooltip.explosionoverhaul.craterSizeMultiplier.footer"));
|
||||
lines.add(Component.m_237113_((String)""));
|
||||
lines.add(Component.m_237115_((String)"tooltip.explosionoverhaul.craterShapeInfo"));
|
||||
return lines.toArray(new Component[0]);
|
||||
}
|
||||
|
||||
public static class LinkButtonEntry
|
||||
extends AbstractConfigListEntry<Object> {
|
||||
private final Button button;
|
||||
private final Component tooltip;
|
||||
|
||||
public LinkButtonEntry(Component fieldName, Component tooltip, Runnable action) {
|
||||
super(fieldName, false);
|
||||
this.tooltip = tooltip;
|
||||
this.button = Button.m_253074_((Component)fieldName, b -> action.run()).m_253136_();
|
||||
this.button.m_93674_(200);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics graphics, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
|
||||
this.button.m_252865_(x + entryWidth / 2 - 100);
|
||||
this.button.m_253211_(y);
|
||||
this.button.m_88315_(graphics, mouseX, mouseY, delta);
|
||||
if (mouseX >= this.button.m_252754_() && mouseX <= this.button.m_252754_() + this.button.m_5711_() && mouseY >= this.button.m_252907_() && mouseY <= this.button.m_252907_() + this.button.m_93694_()) {
|
||||
graphics.m_280557_(Minecraft.m_91087_().f_91062_, this.tooltip, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
public List<? extends GuiEventListener> m_6702_() {
|
||||
return Collections.singletonList(this.button);
|
||||
}
|
||||
|
||||
public List<? extends NarratableEntry> narratables() {
|
||||
return Collections.singletonList(this.button);
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Optional<Object> getDefaultValue() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
|
||||
|
||||
public class ModKeyMappings {
|
||||
public static final String KEY_CATEGORY = "key.categories.explosionoverhaul";
|
||||
public static final KeyMapping ACCEPT_SCAN = new KeyMapping("key.explosionoverhaul.accept_scan", InputConstants.Type.KEYSYM, 49, "key.categories.explosionoverhaul");
|
||||
public static final KeyMapping DECLINE_SCAN = new KeyMapping("key.explosionoverhaul.decline_scan", InputConstants.Type.KEYSYM, 50, "key.categories.explosionoverhaul");
|
||||
public static final KeyMapping INFO_SCAN = new KeyMapping("key.explosionoverhaul.info_scan", InputConstants.Type.KEYSYM, 51, "key.categories.explosionoverhaul");
|
||||
|
||||
public static void register(RegisterKeyMappingsEvent event) {
|
||||
event.register(ACCEPT_SCAN);
|
||||
event.register(DECLINE_SCAN);
|
||||
event.register(INFO_SCAN);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.CustomGlowParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.PlasmaParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionWindController;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class PhysicsBasedExplosionEffect {
|
||||
private final ClientLevel level;
|
||||
private final Random random;
|
||||
private final Vec3 position;
|
||||
private final float power;
|
||||
private int age = 0;
|
||||
private final int maxAge = 8;
|
||||
private final float maxRadius;
|
||||
private final int particleCount;
|
||||
private final float particleScaleBase;
|
||||
private final int totalLifetime;
|
||||
private boolean finished = false;
|
||||
private final int totalSparks;
|
||||
private float sparkSpawnAccumulator = 0.0f;
|
||||
private final List<Vec3> sparkDirections;
|
||||
private int sparkIndex = 0;
|
||||
|
||||
public PhysicsBasedExplosionEffect(Vec3 position, float power) {
|
||||
this.position = position;
|
||||
this.power = power;
|
||||
this.random = new Random();
|
||||
this.level = Minecraft.m_91087_().f_91073_;
|
||||
if (this.level == null) {
|
||||
this.finished = true;
|
||||
this.maxRadius = 0.0f;
|
||||
this.particleCount = 0;
|
||||
this.particleScaleBase = 0.0f;
|
||||
this.totalLifetime = 0;
|
||||
this.totalSparks = 0;
|
||||
this.sparkDirections = new ArrayList<Vec3>();
|
||||
return;
|
||||
}
|
||||
float calcPower = Mth.m_14036_((float)power, (float)1.0f, (float)100.0f);
|
||||
float powerFraction = calcPower / 100.0f;
|
||||
this.maxRadius = Mth.m_14179_((float)powerFraction, (float)3.0f, (float)40.0f);
|
||||
this.particleCount = (int)Mth.m_14179_((float)powerFraction, (float)40.0f, (float)400.0f);
|
||||
this.particleScaleBase = Mth.m_14179_((float)powerFraction, (float)5.0f, (float)37.5f);
|
||||
this.totalLifetime = (int)Mth.m_14179_((float)powerFraction, (float)300.0f, (float)1800.0f) + this.random.nextInt(100) - 50;
|
||||
this.totalSparks = (int)Mth.m_14179_((float)powerFraction, (float)3.0f, (float)150.0f);
|
||||
this.sparkDirections = new ArrayList<Vec3>();
|
||||
if (this.totalSparks > 0) {
|
||||
double goldenRatio = (1.0 + Math.sqrt(5.0)) / 2.0;
|
||||
double angleIncrement = Math.PI * 2 * goldenRatio;
|
||||
for (int i = 0; i < this.totalSparks; ++i) {
|
||||
double y = 1.0 - (double)i / (double)(this.totalSparks - 1) * 2.0;
|
||||
double radius = Math.sqrt(1.0 - y * y);
|
||||
double theta = angleIncrement * (double)i;
|
||||
double x = Math.cos(theta) * radius;
|
||||
double z = Math.sin(theta) * radius;
|
||||
this.sparkDirections.add(new Vec3(x, z, y).m_82541_());
|
||||
}
|
||||
Collections.shuffle(this.sparkDirections, this.random);
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (this.finished) {
|
||||
return;
|
||||
}
|
||||
if (!((Boolean)Config.CLIENT.enableExplosionParticles.get()).booleanValue()) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
++this.age;
|
||||
if (this.age > this.maxAge) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
if (Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.REALISTIC_2) {
|
||||
this.tickRealistic2();
|
||||
} else {
|
||||
this.tickRegular();
|
||||
}
|
||||
}
|
||||
|
||||
private void tickRealistic2() {
|
||||
if (this.age == 1) {
|
||||
double distance;
|
||||
float f = this.age;
|
||||
Objects.requireNonNull(this);
|
||||
float progress = f / 8.0f;
|
||||
float currentRadius = this.maxRadius * (float)Math.pow(progress, 0.4);
|
||||
Vec3 particlePos = this.position.m_82520_((this.random.nextDouble() - 0.5) * (double)currentRadius, (this.random.nextDouble() - 0.5) * (double)currentRadius, (this.random.nextDouble() - 0.5) * (double)currentRadius);
|
||||
Vec3 motion = new Vec3((this.random.nextDouble() - 0.5) * 0.05, (this.random.nextDouble() - 0.5) * 0.05, (this.random.nextDouble() - 0.5) * 0.05);
|
||||
double distance3D = particlePos.m_82554_(this.position);
|
||||
double heightPercent = this.maxRadius <= 0.0f ? 0.5 : Mth.m_14008_((double)(distance3D / (double)this.maxRadius), (double)0.25, (double)1.0);
|
||||
Vec3 windDirection = ExplosionWindController.getWindDirection();
|
||||
double glowSpeed = ExplosionWindController.computeGlowSpeed(heightPercent);
|
||||
if (windDirection != Vec3.f_82478_ && glowSpeed > 0.0) {
|
||||
motion = motion.m_82549_(windDirection.m_82490_(glowSpeed * 0.6));
|
||||
}
|
||||
int zone = (distance = particlePos.m_82554_(this.position)) / (double)this.maxRadius < 0.4 ? 1 : 0;
|
||||
float particleScale = this.particleScaleBase * 1.0f * ((Double)Config.CLIENT.particleSizeScale.get()).floatValue();
|
||||
int animationType = this.power <= 5.0f ? 2 : this.random.nextInt(2);
|
||||
CustomGlowParticleOptions options = new CustomGlowParticleOptions(zone, this.power, particleScale, animationType, (float)this.position.f_82480_, this.maxRadius, (float)heightPercent);
|
||||
this.level.m_7106_((ParticleOptions)options, particlePos.f_82479_, particlePos.f_82480_, particlePos.f_82481_, motion.f_82479_, motion.f_82480_, motion.f_82481_);
|
||||
}
|
||||
if (this.totalSparks > 0 && this.sparkIndex < this.totalSparks && ((Boolean)Config.CLIENT.enablePlasmaParticles.get()).booleanValue()) {
|
||||
float f = this.age;
|
||||
Objects.requireNonNull(this);
|
||||
float progress2 = f / 8.0f;
|
||||
float currentRadius2 = this.maxRadius * (float)Math.pow(progress2, 0.4);
|
||||
float f2 = this.totalSparks;
|
||||
Objects.requireNonNull(this);
|
||||
float sparksToSpawnThisTick = f2 / 8.0f;
|
||||
this.sparkSpawnAccumulator += sparksToSpawnThisTick;
|
||||
int sparksToActuallySpawn = (int)this.sparkSpawnAccumulator;
|
||||
if (sparksToActuallySpawn > 0) {
|
||||
this.sparkSpawnAccumulator -= (float)sparksToActuallySpawn;
|
||||
for (int j = 0; j < sparksToActuallySpawn && this.sparkIndex < this.totalSparks; ++j) {
|
||||
Vec3 plasmaMotion = this.sparkDirections.get(this.sparkIndex);
|
||||
++this.sparkIndex;
|
||||
Vec3 plasmaSpawnPos = this.position.m_82549_(plasmaMotion.m_82490_((double)currentRadius2 * 0.8));
|
||||
float strongSparkChance = 0.1f;
|
||||
if (this.power > 10.0f) {
|
||||
float powerFractionForChance = Mth.m_184655_((float)this.power, (float)10.0f, (float)100.0f);
|
||||
strongSparkChance = Mth.m_14179_((float)powerFractionForChance, (float)0.1f, (float)0.35f);
|
||||
}
|
||||
float force = this.random.nextFloat() < strongSparkChance ? Mth.m_14179_((float)(this.power / 100.0f), (float)2.0f, (float)14.0f) * (0.9f + this.random.nextFloat() * 0.4f) : Mth.m_14179_((float)(this.power / 100.0f), (float)1.3f, (float)6.5f) * (0.6f + this.random.nextFloat() * 0.4f);
|
||||
plasmaMotion = plasmaMotion.m_82490_((double)force);
|
||||
PlasmaParticleOptions plasmaOptions = new PlasmaParticleOptions(this.power);
|
||||
this.level.m_6493_((ParticleOptions)plasmaOptions, true, plasmaSpawnPos.f_82479_, plasmaSpawnPos.f_82480_, plasmaSpawnPos.f_82481_, plasmaMotion.f_82479_, plasmaMotion.f_82480_, plasmaMotion.f_82481_);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.finished = false;
|
||||
}
|
||||
|
||||
private void tickRegular() {
|
||||
int particlesThisTick = this.particleCount / this.maxAge;
|
||||
if (this.age == this.maxAge) {
|
||||
particlesThisTick = this.particleCount - particlesThisTick * (this.maxAge - 1);
|
||||
}
|
||||
float f = this.age;
|
||||
Objects.requireNonNull(this);
|
||||
float progress = f / 8.0f;
|
||||
float currentRadius = this.maxRadius * (float)Math.pow(progress, 0.4);
|
||||
for (int i = 0; i < particlesThisTick; ++i) {
|
||||
double distance;
|
||||
double u = this.random.nextDouble();
|
||||
double v = this.random.nextDouble();
|
||||
double theta = Math.PI * 2 * u;
|
||||
double phi = Math.acos(2.0 * v - 1.0);
|
||||
double r = currentRadius;
|
||||
Vec3 particlePos = this.position.m_82520_(r * Math.sin(phi) * Math.cos(theta), r * Math.sin(phi) * Math.sin(theta), r * Math.cos(phi));
|
||||
Vec3 motion = new Vec3((this.random.nextDouble() - 0.5) * 0.05, (this.random.nextDouble() - 0.5) * 0.05, (this.random.nextDouble() - 0.5) * 0.05);
|
||||
double distance3D = particlePos.m_82554_(this.position);
|
||||
double heightPercent = this.maxRadius <= 0.0f ? 0.5 : Mth.m_14008_((double)(distance3D / (double)this.maxRadius), (double)0.25, (double)1.0);
|
||||
Vec3 windDirection = ExplosionWindController.getWindDirection();
|
||||
double glowSpeed = ExplosionWindController.computeGlowSpeed(heightPercent);
|
||||
if (windDirection != Vec3.f_82478_ && glowSpeed > 0.0) {
|
||||
motion = motion.m_82549_(windDirection.m_82490_(glowSpeed * 0.6));
|
||||
}
|
||||
int zone = (distance = particlePos.m_82554_(this.position)) / (double)this.maxRadius < 0.4 ? 1 : 0;
|
||||
float particleScale = this.particleScaleBase * (0.8f + this.random.nextFloat() * 0.4f) * ((Double)Config.CLIENT.particleSizeScale.get()).floatValue();
|
||||
int animationType = this.power <= 5.0f ? 2 : this.random.nextInt(2);
|
||||
CustomGlowParticleOptions options = new CustomGlowParticleOptions(zone, this.power, particleScale, animationType, (float)this.position.f_82480_, this.maxRadius, (float)heightPercent);
|
||||
this.level.m_7106_((ParticleOptions)options, particlePos.f_82479_, particlePos.f_82480_, particlePos.f_82481_, motion.f_82479_, motion.f_82480_, motion.f_82481_);
|
||||
}
|
||||
if (this.totalSparks > 0 && this.sparkIndex < this.totalSparks && ((Boolean)Config.CLIENT.enablePlasmaParticles.get()).booleanValue()) {
|
||||
float f2 = this.totalSparks;
|
||||
Objects.requireNonNull(this);
|
||||
float sparksToSpawnThisTick = f2 / 8.0f;
|
||||
this.sparkSpawnAccumulator += sparksToSpawnThisTick;
|
||||
int sparksToActuallySpawn = (int)this.sparkSpawnAccumulator;
|
||||
if (sparksToActuallySpawn > 0) {
|
||||
this.sparkSpawnAccumulator -= (float)sparksToActuallySpawn;
|
||||
for (int j = 0; j < sparksToActuallySpawn && this.sparkIndex < this.totalSparks; ++j) {
|
||||
Vec3 plasmaMotion = this.sparkDirections.get(this.sparkIndex);
|
||||
++this.sparkIndex;
|
||||
Vec3 plasmaSpawnPos = this.position.m_82549_(plasmaMotion.m_82490_((double)currentRadius * 0.8));
|
||||
float strongSparkChance = 0.1f;
|
||||
if (this.power > 10.0f) {
|
||||
float powerFractionForChance = Mth.m_184655_((float)this.power, (float)10.0f, (float)100.0f);
|
||||
strongSparkChance = Mth.m_14179_((float)powerFractionForChance, (float)0.1f, (float)0.35f);
|
||||
}
|
||||
float force = this.random.nextFloat() < strongSparkChance ? Mth.m_14179_((float)(this.power / 100.0f), (float)2.0f, (float)14.0f) * (0.9f + this.random.nextFloat() * 0.4f) : Mth.m_14179_((float)(this.power / 100.0f), (float)1.3f, (float)6.5f) * (0.6f + this.random.nextFloat() * 0.4f);
|
||||
plasmaMotion = plasmaMotion.m_82490_((double)force);
|
||||
PlasmaParticleOptions plasmaOptions = new PlasmaParticleOptions(this.power);
|
||||
this.level.m_6493_((ParticleOptions)plasmaOptions, true, plasmaSpawnPos.f_82479_, plasmaSpawnPos.f_82480_, plasmaSpawnPos.f_82481_, plasmaMotion.f_82479_, plasmaMotion.f_82480_, plasmaMotion.f_82481_);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.finished = false;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.PlasmaParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.SmokeParticleOptions;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.ParticleProvider;
|
||||
import net.minecraft.client.particle.ParticleRenderType;
|
||||
import net.minecraft.client.particle.SpriteSet;
|
||||
import net.minecraft.client.particle.TextureSheetParticle;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Quaternionfc;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class PlasmaParticle
|
||||
extends TextureSheetParticle {
|
||||
private final SpriteSet sprites;
|
||||
private final float initialQuadSize;
|
||||
|
||||
protected PlasmaParticle(ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed, PlasmaParticleOptions options, SpriteSet pSpriteSet) {
|
||||
super(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed);
|
||||
this.sprites = pSpriteSet;
|
||||
this.f_172258_ = 0.96f;
|
||||
this.f_107226_ = 0.2f;
|
||||
this.f_107215_ = pXSpeed;
|
||||
this.f_107216_ = pYSpeed;
|
||||
this.f_107217_ = pZSpeed;
|
||||
float power = options.getPower();
|
||||
float powerFraction = Mth.m_14036_((float)(power / 100.0f), (float)0.0f, (float)1.0f);
|
||||
this.f_107663_ = this.initialQuadSize = Mth.m_14179_((float)powerFraction, (float)0.4f, (float)2.5f);
|
||||
this.f_107225_ = 200 + this.f_107223_.m_188503_(40) - 20;
|
||||
this.f_107227_ = 0.8f;
|
||||
this.f_107228_ = 0.8f;
|
||||
this.f_107229_ = 0.8f;
|
||||
this.m_108335_(pSpriteSet);
|
||||
}
|
||||
|
||||
public ParticleRenderType m_7556_() {
|
||||
return ParticleRenderType.f_107431_;
|
||||
}
|
||||
|
||||
public int m_6355_(float pPartialTick) {
|
||||
return 240;
|
||||
}
|
||||
|
||||
public void m_5744_(VertexConsumer pBuffer, Camera pRenderInfo, float pPartialTicks) {
|
||||
RenderSystem.disableDepthTest();
|
||||
Vec3 vec3 = pRenderInfo.m_90583_();
|
||||
float f = (float)(Mth.m_14139_((double)pPartialTicks, (double)this.f_107209_, (double)this.f_107212_) - vec3.m_7096_());
|
||||
float f1 = (float)(Mth.m_14139_((double)pPartialTicks, (double)this.f_107210_, (double)this.f_107213_) - vec3.m_7098_());
|
||||
float f2 = (float)(Mth.m_14139_((double)pPartialTicks, (double)this.f_107211_, (double)this.f_107214_) - vec3.m_7094_());
|
||||
Quaternionf quaternion = new Quaternionf((Quaternionfc)pRenderInfo.m_253121_());
|
||||
if (this.f_107231_ != 0.0f) {
|
||||
float f3 = Mth.m_14179_((float)pPartialTicks, (float)this.f_107204_, (float)this.f_107231_);
|
||||
quaternion.rotateZ(f3);
|
||||
}
|
||||
Vector3f[] avector3f = new Vector3f[]{new Vector3f(-1.0f, -1.0f, 0.0f), new Vector3f(-1.0f, 1.0f, 0.0f), new Vector3f(1.0f, 1.0f, 0.0f), new Vector3f(1.0f, -1.0f, 0.0f)};
|
||||
float f4 = this.m_5902_(pPartialTicks);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Vector3f vector3f = avector3f[i];
|
||||
vector3f.rotate((Quaternionfc)quaternion);
|
||||
vector3f.mul(f4);
|
||||
vector3f.add(f, f1, f2);
|
||||
}
|
||||
float f7 = this.m_5970_();
|
||||
float f8 = this.m_5952_();
|
||||
float f5 = this.m_5951_();
|
||||
float f6 = this.m_5950_();
|
||||
int j = this.m_6355_(pPartialTicks);
|
||||
pBuffer.m_5483_((double)avector3f[0].x(), (double)avector3f[0].y(), (double)avector3f[0].z()).m_7421_(f8, f6).m_85950_(this.f_107227_, this.f_107228_, this.f_107229_, this.f_107230_).m_85969_(j).m_5752_();
|
||||
pBuffer.m_5483_((double)avector3f[1].x(), (double)avector3f[1].y(), (double)avector3f[1].z()).m_7421_(f8, f5).m_85950_(this.f_107227_, this.f_107228_, this.f_107229_, this.f_107230_).m_85969_(j).m_5752_();
|
||||
pBuffer.m_5483_((double)avector3f[2].x(), (double)avector3f[2].y(), (double)avector3f[2].z()).m_7421_(f7, f5).m_85950_(this.f_107227_, this.f_107228_, this.f_107229_, this.f_107230_).m_85969_(j).m_5752_();
|
||||
pBuffer.m_5483_((double)avector3f[3].x(), (double)avector3f[3].y(), (double)avector3f[3].z()).m_7421_(f7, f6).m_85950_(this.f_107227_, this.f_107228_, this.f_107229_, this.f_107230_).m_85969_(j).m_5752_();
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
|
||||
public void m_5989_() {
|
||||
super.m_5989_();
|
||||
this.m_108339_(this.sprites);
|
||||
if (!this.f_107220_) {
|
||||
float lifeProgress = (float)this.f_107224_ / (float)this.f_107225_;
|
||||
float flicker = 1.0f - this.f_107223_.m_188501_() * 0.3f;
|
||||
this.f_107230_ = Mth.m_14036_((float)(flicker * (1.0f - lifeProgress * lifeProgress)), (float)0.0f, (float)1.0f);
|
||||
this.f_107663_ = this.initialQuadSize * (0.9f + this.f_107223_.m_188501_() * 0.2f);
|
||||
if (((Boolean)Config.CLIENT.enablePlasmaSmokeTrail.get()).booleanValue() && this.f_107224_ > 2 && (double)this.f_107223_.m_188501_() < (Double)Config.CLIENT.plasmaSmokeFrequency.get()) {
|
||||
int smokeCount = (Integer)Config.CLIENT.plasmaSmokeCount.get();
|
||||
for (int i = 0; i < smokeCount; ++i) {
|
||||
this.f_107208_.m_7106_((ParticleOptions)new SmokeParticleOptions(0.5f, 200, 0.6f, 0.6f, 0.6f, 0.4f, false, 0.0f, 0.0f, null), this.f_107212_, this.f_107213_, this.f_107214_, (this.f_107223_.m_188500_() - 0.5) * 0.03, (this.f_107223_.m_188500_() - 0.5) * 0.03, (this.f_107223_.m_188500_() - 0.5) * 0.03);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Provider
|
||||
implements ParticleProvider<PlasmaParticleOptions> {
|
||||
private final SpriteSet sprites;
|
||||
|
||||
public Provider(SpriteSet pSprites) {
|
||||
this.sprites = pSprites;
|
||||
}
|
||||
|
||||
public Particle createParticle(PlasmaParticleOptions pType, ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
return new PlasmaParticle(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, pType, this.sprites);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class PositionalSoundInstance
|
||||
extends AbstractTickableSoundInstance {
|
||||
public PositionalSoundInstance(SoundEvent pSound, SoundSource pSource, float pVolume, float pPitch, RandomSource pRandom, double pX, double pY, double pZ) {
|
||||
super(pSound, pSource, pRandom);
|
||||
this.f_119573_ = pVolume;
|
||||
this.f_119574_ = pPitch;
|
||||
this.f_119575_ = pX;
|
||||
this.f_119576_ = pY;
|
||||
this.f_119577_ = pZ;
|
||||
this.f_119578_ = false;
|
||||
this.f_119579_ = 0;
|
||||
this.f_119582_ = false;
|
||||
this.f_119580_ = SoundInstance.Attenuation.LINEAR;
|
||||
}
|
||||
|
||||
public void m_7788_() {
|
||||
}
|
||||
|
||||
public void updatePosition(Vec3 newPosition) {
|
||||
this.f_119575_ = newPosition.m_7096_();
|
||||
this.f_119576_ = newPosition.m_7098_();
|
||||
this.f_119577_ = newPosition.m_7094_();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ShockwaveEffect {
|
||||
private final ClientLevel level;
|
||||
private final Vec3 position;
|
||||
private final float power;
|
||||
private final Random random = new Random();
|
||||
private int age = 0;
|
||||
private final int maxAge;
|
||||
private final float maxRadius;
|
||||
private final int particlesPerTick;
|
||||
private final float shellThickness;
|
||||
private boolean finished = false;
|
||||
|
||||
public ShockwaveEffect(Vec3 position, float power) {
|
||||
this.level = Minecraft.m_91087_().f_91073_;
|
||||
this.position = position;
|
||||
this.power = power;
|
||||
float powerFraction = Mth.m_184655_((float)this.power, (float)5.0f, (float)100.0f);
|
||||
this.maxAge = (int)Mth.m_14179_((float)powerFraction, (float)4.0f, (float)7.0f);
|
||||
float fireballPowerFraction = Mth.m_14036_((float)power, (float)1.0f, (float)100.0f) / 100.0f;
|
||||
float fireballRadius = Mth.m_14179_((float)fireballPowerFraction, (float)3.0f, (float)40.0f);
|
||||
float normalizedPowerSqrt = Mth.m_184655_((float)((float)Math.sqrt(power)), (float)((float)Math.sqrt(5.0)), (float)((float)Math.sqrt(100.0)));
|
||||
float shockwaveMultiplier = Mth.m_14179_((float)normalizedPowerSqrt, (float)2.0f, (float)8.0f);
|
||||
this.maxRadius = fireballRadius * shockwaveMultiplier * 3.0f;
|
||||
this.particlesPerTick = (int)Mth.m_14179_((float)powerFraction, (float)70.0f, (float)400.0f);
|
||||
this.shellThickness = Mth.m_14179_((float)powerFraction, (float)0.5f, (float)4.0f);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (this.finished || this.level == null) {
|
||||
return;
|
||||
}
|
||||
if (!((Boolean)Config.CLIENT.enableShockwaveEffect.get()).booleanValue()) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
++this.age;
|
||||
if (this.age > this.maxAge) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
float progress = (float)this.age / (float)this.maxAge;
|
||||
float easedProgress = Mth.m_14031_((float)(progress * (float)Math.PI / 2.0f));
|
||||
float currentRadius = this.maxRadius * easedProgress;
|
||||
for (int i = 0; i < this.particlesPerTick; ++i) {
|
||||
double u = this.random.nextDouble();
|
||||
double v = this.random.nextDouble();
|
||||
double theta = Math.PI * 2 * u;
|
||||
double phi = Math.acos(2.0 * v - 1.0);
|
||||
float radiusOffset = (this.random.nextFloat() - 0.5f) * this.shellThickness;
|
||||
float finalRadius = currentRadius + radiusOffset;
|
||||
if (finalRadius < 0.0f) {
|
||||
finalRadius = 0.0f;
|
||||
}
|
||||
Vec3 particlePos = this.position.m_82520_((double)finalRadius * Math.sin(phi) * Math.cos(theta), (double)finalRadius * Math.sin(phi) * Math.sin(theta), (double)finalRadius * Math.cos(phi));
|
||||
this.level.m_6493_((ParticleOptions)ParticleTypes.f_123813_, true, particlePos.f_82479_, particlePos.f_82480_, particlePos.f_82481_, 0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.vinlanx.explosionoverhaul.SmokeParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionWindController;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.ParticleProvider;
|
||||
import net.minecraft.client.particle.ParticleRenderType;
|
||||
import net.minecraft.client.particle.SpriteSet;
|
||||
import net.minecraft.client.particle.TextureSheetParticle;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class SmokeParticle
|
||||
extends TextureSheetParticle {
|
||||
private final float initialAlpha;
|
||||
private final boolean isHeavy;
|
||||
private final float windSpeed;
|
||||
private final float heightPercent;
|
||||
|
||||
protected SmokeParticle(ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed, SmokeParticleOptions options, SpriteSet spriteSet) {
|
||||
super(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed);
|
||||
this.f_172258_ = 0.96f;
|
||||
this.f_107226_ = 0.0f;
|
||||
this.f_107225_ = options.getLifetime();
|
||||
this.f_107663_ = options.getScale();
|
||||
this.f_107227_ = options.getRed();
|
||||
this.f_107228_ = options.getGreen();
|
||||
this.f_107229_ = options.getBlue();
|
||||
this.f_107230_ = options.getAlpha();
|
||||
this.initialAlpha = options.getAlpha();
|
||||
this.isHeavy = options.isHeavy();
|
||||
this.windSpeed = options.getWindSpeed();
|
||||
this.heightPercent = options.getHeightPercent();
|
||||
this.m_108337_(spriteSet.m_213979_(this.f_107223_));
|
||||
}
|
||||
|
||||
public void m_5744_(VertexConsumer pBuffer, Camera pRenderInfo, float pPartialTicks) {
|
||||
RenderSystem.depthMask((this.f_107230_ > 0.3f ? 1 : 0) != 0);
|
||||
super.m_5744_(pBuffer, pRenderInfo, pPartialTicks);
|
||||
RenderSystem.depthMask((boolean)true);
|
||||
}
|
||||
|
||||
public void m_5989_() {
|
||||
Vec3 direction;
|
||||
this.f_107209_ = this.f_107212_;
|
||||
this.f_107210_ = this.f_107213_;
|
||||
this.f_107211_ = this.f_107214_;
|
||||
if (this.f_107224_++ >= this.f_107225_) {
|
||||
this.m_107274_();
|
||||
return;
|
||||
}
|
||||
if (this.isHeavy) {
|
||||
this.f_107216_ = -0.04;
|
||||
}
|
||||
this.m_6257_(this.f_107215_, this.f_107216_, this.f_107217_);
|
||||
this.f_107215_ *= (double)this.f_172258_;
|
||||
this.f_107216_ *= (double)this.f_172258_;
|
||||
this.f_107217_ *= (double)this.f_172258_;
|
||||
if (this.windSpeed > 0.0f && (direction = ExplosionWindController.getWindDirection()) != Vec3.f_82478_) {
|
||||
double targetX = direction.f_82479_ * (double)this.windSpeed;
|
||||
double targetZ = direction.f_82481_ * (double)this.windSpeed;
|
||||
this.f_107215_ += (targetX - this.f_107215_) * 0.12;
|
||||
this.f_107217_ += (targetZ - this.f_107217_) * 0.12;
|
||||
}
|
||||
float lifeProgress = (float)this.f_107224_ / (float)this.f_107225_;
|
||||
this.f_107230_ = this.initialAlpha * (1.0f - lifeProgress);
|
||||
}
|
||||
|
||||
public boolean shouldCull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ParticleRenderType m_7556_() {
|
||||
return ParticleRenderType.f_107431_;
|
||||
}
|
||||
|
||||
public static class Provider
|
||||
implements ParticleProvider<SmokeParticleOptions> {
|
||||
private final SpriteSet sprites;
|
||||
|
||||
public Provider(SpriteSet pSprites) {
|
||||
this.sprites = pSprites;
|
||||
}
|
||||
|
||||
public Particle createParticle(SmokeParticleOptions options, ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
return new SmokeParticle(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, options, this.sprites);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public final class SoundEngineAudioQueue {
|
||||
private static final Queue<Runnable> QUEUE = new ConcurrentLinkedQueue<Runnable>();
|
||||
|
||||
private SoundEngineAudioQueue() {
|
||||
}
|
||||
|
||||
public static void enqueueAudio(Runnable task) {
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
if (SoundEngineAudioQueue.isSoundThread()) {
|
||||
try {
|
||||
task.run();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
SoundEngineAudioQueue.drainNow();
|
||||
} else {
|
||||
QUEUE.offer(task);
|
||||
}
|
||||
}
|
||||
|
||||
public static void drainNow() {
|
||||
Runnable next;
|
||||
if (!SoundEngineAudioQueue.isSoundThread()) {
|
||||
return;
|
||||
}
|
||||
while ((next = QUEUE.poll()) != null) {
|
||||
try {
|
||||
next.run();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSoundThread() {
|
||||
return "Sound engine".equals(Thread.currentThread().getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.sonicether.soundphysics.SoundPhysics;
|
||||
import com.vinlanx.explosionoverhaul.client.LowPassConcussionEffect;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import net.neoforged.fml.ModList;
|
||||
import org.lwjgl.openal.AL10;
|
||||
|
||||
public class SoundPhysicsCompatibility {
|
||||
private static boolean sprLoaded = false;
|
||||
private static final Map<Integer, SprParams> sourceParams = new ConcurrentHashMap<Integer, SprParams>();
|
||||
|
||||
public static void init() {
|
||||
sprLoaded = ModList.get().isLoaded("sound_physics_remastered");
|
||||
if (sprLoaded) {
|
||||
LowPassConcussionEffect.setCompatibilityMode(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCompatibilityEnabled() {
|
||||
return sprLoaded;
|
||||
}
|
||||
|
||||
public static void cacheParams(int sourceID, float sg0, float sg1, float sg2, float sg3, float sc0, float sc1, float sc2, float sc3, float dc, float dg) {
|
||||
sourceParams.put(sourceID, new SprParams(sg0, sg1, sg2, sg3, sc0, sc1, sc2, sc3, dc, dg));
|
||||
}
|
||||
|
||||
public static void onSourceStop(int sourceID) {
|
||||
sourceParams.remove(sourceID);
|
||||
}
|
||||
|
||||
public static void reapplyDirectFilterParameters() {
|
||||
if (!sprLoaded || sourceParams.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
sourceParams.entrySet().removeIf(entry -> {
|
||||
int id = (Integer)entry.getKey();
|
||||
if (!AL10.alIsSource((int)id)) {
|
||||
return true;
|
||||
}
|
||||
SprParams p = (SprParams)entry.getValue();
|
||||
try {
|
||||
SoundPhysics.setEnvironment((int)id, (float)p.sg0, (float)p.sg1, (float)p.sg2, (float)p.sg3, (float)p.sc0, (float)p.sc1, (float)p.sc2, (float)p.sc3, (float)p.dc, (float)p.dg);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
public static float combineGain(float sprGain) {
|
||||
return sprGain * LowPassConcussionEffect.getCurrentGainMultiplier();
|
||||
}
|
||||
|
||||
public static float combineHF(float sprHF) {
|
||||
return Math.min(sprHF, LowPassConcussionEffect.getCurrentHfMultiplier());
|
||||
}
|
||||
|
||||
private static class SprParams {
|
||||
float sg0;
|
||||
float sg1;
|
||||
float sg2;
|
||||
float sg3;
|
||||
float sc0;
|
||||
float sc1;
|
||||
float sc2;
|
||||
float sc3;
|
||||
float dc;
|
||||
float dg;
|
||||
|
||||
SprParams(float sg0, float sg1, float sg2, float sg3, float sc0, float sc1, float sc2, float sc3, float dc, float dg) {
|
||||
this.sg0 = sg0;
|
||||
this.sg1 = sg1;
|
||||
this.sg2 = sg2;
|
||||
this.sg3 = sg3;
|
||||
this.sc0 = sc0;
|
||||
this.sc1 = sc1;
|
||||
this.sc2 = sc2;
|
||||
this.sc3 = sc3;
|
||||
this.dc = dc;
|
||||
this.dg = dg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
|
||||
public class SpriteSheetAnimator {
|
||||
private final ResourceLocation spriteSheetLocation;
|
||||
private final int frameWidth;
|
||||
private final int frameHeight;
|
||||
private final int columns;
|
||||
private final int rows;
|
||||
private final int totalFrames;
|
||||
private final float frameTime;
|
||||
private NativeImage spriteSheet;
|
||||
private DynamicTexture dynamicTexture;
|
||||
private ResourceLocation dynamicTextureLocation;
|
||||
private int currentFrame = 0;
|
||||
private float animationTime = 0.0f;
|
||||
private boolean isPlaying = false;
|
||||
private Map<Integer, Runnable> frameCallbacks = new HashMap<Integer, Runnable>();
|
||||
private Map<Integer, Boolean> frameCallbacksTriggered = new HashMap<Integer, Boolean>();
|
||||
|
||||
public SpriteSheetAnimator(ResourceLocation spriteSheetLocation, int frameWidth, int frameHeight, int columns, int rows, int totalFrames, int fps) {
|
||||
this.spriteSheetLocation = spriteSheetLocation;
|
||||
this.frameWidth = frameWidth;
|
||||
this.frameHeight = frameHeight;
|
||||
this.columns = columns;
|
||||
this.rows = rows;
|
||||
this.totalFrames = totalFrames;
|
||||
this.frameTime = 1.0f / (float)fps;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
try {
|
||||
InputStream stream = ((Resource)mc.m_91098_().m_213713_(this.spriteSheetLocation).orElseThrow()).m_215507_();
|
||||
this.spriteSheet = NativeImage.m_85058_((InputStream)stream);
|
||||
stream.close();
|
||||
NativeImage frameImage = new NativeImage(this.frameWidth, this.frameHeight, false);
|
||||
this.dynamicTexture = new DynamicTexture(frameImage);
|
||||
this.dynamicTextureLocation = mc.m_91097_().m_118490_("explosionoverhaul_anim", this.dynamicTexture);
|
||||
this.updateTexture();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println("Failed to load sprite sheet: " + this.spriteSheetLocation);
|
||||
e.printStackTrace();
|
||||
this.spriteSheet = null;
|
||||
this.dynamicTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void tick(float deltaTime) {
|
||||
if (!this.isPlaying || this.spriteSheet == null) {
|
||||
return;
|
||||
}
|
||||
this.animationTime += deltaTime;
|
||||
if (this.animationTime >= this.frameTime) {
|
||||
Boolean wasTriggered;
|
||||
this.animationTime = 0.0f;
|
||||
++this.currentFrame;
|
||||
if (this.currentFrame >= this.totalFrames) {
|
||||
this.currentFrame = 0;
|
||||
this.frameCallbacksTriggered.clear();
|
||||
}
|
||||
this.updateTexture();
|
||||
if (this.frameCallbacks.containsKey(this.currentFrame) && !(wasTriggered = this.frameCallbacksTriggered.getOrDefault(this.currentFrame, false)).booleanValue()) {
|
||||
this.frameCallbacks.get(this.currentFrame).run();
|
||||
this.frameCallbacksTriggered.put(this.currentFrame, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTexture() {
|
||||
if (this.spriteSheet == null || this.dynamicTexture == null) {
|
||||
return;
|
||||
}
|
||||
if (this.currentFrame < 0) {
|
||||
this.currentFrame = 0;
|
||||
}
|
||||
if (this.currentFrame >= this.totalFrames) {
|
||||
this.currentFrame = this.totalFrames - 1;
|
||||
}
|
||||
int col = this.currentFrame % this.columns;
|
||||
int row = this.currentFrame / this.columns;
|
||||
int srcX = col * this.frameWidth;
|
||||
int srcY = row * this.frameHeight;
|
||||
NativeImage frameImage = this.dynamicTexture.m_117991_();
|
||||
if (frameImage == null) {
|
||||
return;
|
||||
}
|
||||
for (int y = 0; y < this.frameHeight; ++y) {
|
||||
for (int x = 0; x < this.frameWidth; ++x) {
|
||||
if (srcX + x < this.spriteSheet.m_84982_() && srcY + y < this.spriteSheet.m_85084_()) {
|
||||
int pixel = this.spriteSheet.m_84985_(srcX + x, srcY + y);
|
||||
frameImage.m_84988_(x, y, pixel);
|
||||
continue;
|
||||
}
|
||||
frameImage.m_84988_(x, y, 0);
|
||||
}
|
||||
}
|
||||
this.dynamicTexture.m_117985_();
|
||||
}
|
||||
|
||||
public void play() {
|
||||
this.isPlaying = true;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
this.isPlaying = false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.currentFrame = 0;
|
||||
this.animationTime = 0.0f;
|
||||
this.isPlaying = false;
|
||||
this.frameCallbacksTriggered.clear();
|
||||
this.updateTexture();
|
||||
}
|
||||
|
||||
public ResourceLocation getTextureLocation() {
|
||||
return this.dynamicTextureLocation;
|
||||
}
|
||||
|
||||
public int getFrameWidth() {
|
||||
return this.frameWidth;
|
||||
}
|
||||
|
||||
public int getFrameHeight() {
|
||||
return this.frameHeight;
|
||||
}
|
||||
|
||||
public int getCurrentFrame() {
|
||||
return this.currentFrame;
|
||||
}
|
||||
|
||||
public void registerFrameCallback(int frameNumber, Runnable callback) {
|
||||
if (frameNumber >= 0 && frameNumber < this.totalFrames) {
|
||||
this.frameCallbacks.put(frameNumber, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterFrameCallback(int frameNumber) {
|
||||
this.frameCallbacks.remove(frameNumber);
|
||||
this.frameCallbacksTriggered.remove(frameNumber);
|
||||
}
|
||||
|
||||
public void clearFrameCallbacks() {
|
||||
this.frameCallbacks.clear();
|
||||
this.frameCallbacksTriggered.clear();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (this.dynamicTexture != null) {
|
||||
this.dynamicTexture.close();
|
||||
}
|
||||
if (this.spriteSheet != null) {
|
||||
this.spriteSheet.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
|
||||
import com.vinlanx.explosionoverhaul.ModSounds;
|
||||
import com.vinlanx.explosionoverhaul.client.GuideSlidesScreen;
|
||||
import com.vinlanx.explosionoverhaul.client.SpriteSheetAnimator;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
|
||||
public class VinlanxSplashScreen
|
||||
extends Screen {
|
||||
private static final ResourceLocation SPRITE_SHEET = ResourceLocation.fromNamespaceAndPath((String)"explosionoverhaul", (String)"intro_gui/vinlanx_screen.png");
|
||||
private static final int FRAME_WIDTH = 1280;
|
||||
private static final int FRAME_HEIGHT = 720;
|
||||
private static final int COLUMNS = 12;
|
||||
private static final int ROWS = 12;
|
||||
private static final int TOTAL_FRAMES = 126;
|
||||
private static final int FPS = 24;
|
||||
private SpriteSheetAnimator animator;
|
||||
private boolean animationFinished = false;
|
||||
private long lastFrameTime = System.currentTimeMillis();
|
||||
private SimpleSoundInstance boomSoundInstance;
|
||||
|
||||
public VinlanxSplashScreen() {
|
||||
super((Component)Component.m_237113_((String)"Vinlanx Intro"));
|
||||
}
|
||||
|
||||
protected void m_7856_() {
|
||||
super.m_7856_();
|
||||
this.animator = new SpriteSheetAnimator(SPRITE_SHEET, 1280, 720, 12, 12, 126, 24);
|
||||
this.animator.load();
|
||||
this.animator.play();
|
||||
try {
|
||||
SoundManager soundManager = Minecraft.m_91087_().m_91106_();
|
||||
this.boomSoundInstance = SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.INTRO_BOOM_2.get()), (float)1.0f, (float)1.0f);
|
||||
soundManager.m_120367_((SoundInstance)this.boomSoundInstance);
|
||||
}
|
||||
catch (Exception e) {
|
||||
ExplosionOverhaul.LOGGER.warn("Failed to play intro_boom_2: {}", (Object)e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void m_86600_() {
|
||||
super.m_86600_();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
float deltaTime = (float)(currentTime - this.lastFrameTime) / 1000.0f;
|
||||
this.lastFrameTime = currentTime;
|
||||
if (this.animator != null) {
|
||||
this.animator.tick(deltaTime);
|
||||
if (!this.animationFinished && this.animator.getCurrentFrame() >= 125) {
|
||||
this.animationFinished = true;
|
||||
this.transitionToFirstTimeScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void m_88315_(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
|
||||
int displayWidth;
|
||||
int displayHeight;
|
||||
graphics.m_280509_(0, 0, this.f_96543_, this.f_96544_, -16777216);
|
||||
if (this.animator == null) {
|
||||
return;
|
||||
}
|
||||
ResourceLocation texture = this.animator.getTextureLocation();
|
||||
if (texture == null) {
|
||||
return;
|
||||
}
|
||||
float screenAspectRatio = (float)this.f_96543_ / (float)this.f_96544_;
|
||||
float targetAspectRatio = 1.7777778f;
|
||||
if (screenAspectRatio > targetAspectRatio) {
|
||||
displayHeight = this.f_96544_;
|
||||
displayWidth = (int)((float)displayHeight * targetAspectRatio);
|
||||
} else {
|
||||
displayWidth = this.f_96543_;
|
||||
displayHeight = (int)((float)displayWidth / targetAspectRatio);
|
||||
}
|
||||
int x = (this.f_96543_ - displayWidth) / 2;
|
||||
int y = (this.f_96544_ - displayHeight) / 2;
|
||||
RenderSystem.setShader(GameRenderer::m_172817_);
|
||||
RenderSystem.setShaderTexture((int)0, (ResourceLocation)texture);
|
||||
RenderSystem.setShaderColor((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
graphics.m_280411_(texture, x, y, displayWidth, displayHeight, 0.0f, 0.0f, 1280, 720, 1280, 720);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
public boolean m_6913_() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean m_7933_(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == 256) {
|
||||
this.skipToNext();
|
||||
return true;
|
||||
}
|
||||
return super.m_7933_(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public boolean m_6375_(double mouseX, double mouseY, int button) {
|
||||
this.skipToNext();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean m_7043_() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void m_7861_() {
|
||||
super.m_7861_();
|
||||
if (this.animator != null) {
|
||||
this.animator.close();
|
||||
}
|
||||
if (this.boomSoundInstance != null) {
|
||||
try {
|
||||
Minecraft.m_91087_().m_91106_().m_120399_((SoundInstance)this.boomSoundInstance);
|
||||
}
|
||||
catch (Exception e) {
|
||||
ExplosionOverhaul.LOGGER.warn("Failed to stop intro_boom_2: {}", (Object)e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void skipToNext() {
|
||||
this.animationFinished = true;
|
||||
this.transitionToFirstTimeScreen();
|
||||
}
|
||||
|
||||
private void transitionToFirstTimeScreen() {
|
||||
Minecraft mc = Minecraft.m_91087_();
|
||||
mc.m_91152_((Screen)new GuideSlidesScreen());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user