generated from MrSphay/codex-agent-repository-kit
483 lines
21 KiB
Java
483 lines
21 KiB
Java
/*
|
|
* 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.minecraftforge.client.event.RenderGuiOverlayEvent;
|
|
import net.minecraftforge.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;
|
|
}
|
|
}
|
|
}
|
|
|