Improve sound by using ITickableSound as opposed to starting and stopping the sound every tick

This commit is contained in:
malte0811 2018-05-27 13:32:43 +02:00
parent b65cdc6fbe
commit 7ebf25b3d5
3 changed files with 118 additions and 29 deletions

View file

@ -23,6 +23,7 @@ import blusunrize.immersiveengineering.common.util.Utils;
import blusunrize.lib.manual.ManualInstance;
import blusunrize.lib.manual.ManualPages;
import blusunrize.lib.manual.ManualPages.PositionedItemStack;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.CommonProxy;
@ -68,7 +69,6 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.ClientCommandHandler;
@ -361,33 +361,37 @@ public class ClientProxy extends CommonProxy {
@Override
public void updateMechMBTurningSound(TileEntityMechMB te, MechEnergy energy) {
final double MIN_SPEED = 5;
Set<ISound> added = new HashSet<>();
if (energy.getSpeed() > MIN_SPEED) {
boolean adjusting = energy.isAdjusting();
double speedToUse = energy.getSpeed()-MIN_SPEED;//Volume should be zero by the time the sound stops
float lambda = MathHelper.clamp((float) speedToUse / 50 - .5F, 0, 1);
float totalVolume = (float) (energy.weight / 20e3 * Math.tanh(speedToUse/30));
totalVolume = Math.min(totalVolume, 1.5F);
float pitch = (float) Math.min(Math.sqrt(speedToUse), 3);
if (lambda > 0) {
PositionedSoundRecord sound = new PositionedSoundRecord(turnFast, SoundCategory.BLOCKS, lambda * totalVolume, pitch,
!adjusting, 0, ISound.AttenuationType.LINEAR, te.getPos().getX(), te.getPos().getY(),
te.getPos().getZ());
ClientUtils.mc().getSoundHandler().playSound(sound);
addSound(te.getPos(), sound);
added.add(sound);
SoundHandler sndHandler = ClientUtils.mc().getSoundHandler();
List<ISound> soundsAtPos;
if (playingSounds.containsKey(te.getPos())) {
soundsAtPos = playingSounds.get(te.getPos());
soundsAtPos.removeIf(s -> !sndHandler.isSoundPlaying(s));
if (soundsAtPos.isEmpty()) {
playingSounds.remove(te.getPos());
}
if (lambda < 1) {
PositionedSoundRecord sound = new PositionedSoundRecord(turnSlow, SoundCategory.BLOCKS, (1 - lambda) * totalVolume, pitch,
!adjusting, 0, ISound.AttenuationType.LINEAR, te.getPos().getX(), te.getPos().getY(),
te.getPos().getZ());
ClientUtils.mc().getSoundHandler().playSound(sound);
addSound(te.getPos(), sound);
added.add(sound);
} else {
soundsAtPos = ImmutableList.of();
}
boolean hasSlow = false, hasFast = false;
for (ISound s:soundsAtPos) {
if (s.getSoundLocation().equals(turnFast)) {
hasFast = true;
} else if (s.getSoundLocation().equals(turnSlow)) {
hasSlow = true;
}
}
stopAllSoundsExcept(te.getPos(), added);
if (!hasSlow && energy.getVolumeSlow() > 0) {
ISound snd = new IWTickableSound(turnSlow, SoundCategory.BLOCKS, energy::getVolumeSlow, energy::getPitch,
te.getPos().getX(), te.getPos().getY(), te.getPos().getZ());
sndHandler.playSound(snd);
addSound(te.getPos(), snd);
}
if (!hasFast && energy.getVolumeFast() > 0) {
ISound snd = new IWTickableSound(turnFast, SoundCategory.BLOCKS, energy::getVolumeFast, energy::getPitch,
te.getPos().getX(), te.getPos().getY(), te.getPos().getZ());
sndHandler.playSound(snd);
addSound(te.getPos(), snd);
}
}
@Override

View file

@ -0,0 +1,61 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2018 malte0811
* Industrial Wires is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Industrial Wires is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Industrial Wires. If not, see <http://www.gnu.org/licenses/>.
*/
package malte0811.industrialWires.client;
import net.minecraft.client.audio.ITickableSound;
import net.minecraft.client.audio.PositionedSound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import java.util.function.Supplier;
public class IWTickableSound extends PositionedSound implements ITickableSound {
private Supplier<Float> getVolume;
private Supplier<Float> getPitch;
protected IWTickableSound(ResourceLocation sound, SoundCategory category,
Supplier<Float> getVolume, Supplier<Float> getPitch,
float xPosF, float yPosF, float zPosF) {
super(sound, category);
this.getVolume = getVolume;
this.getPitch = getPitch;
this.repeat = true;
this.repeatDelay = 0;
this.xPosF = xPosF;
this.yPosF = yPosF;
this.zPosF = zPosF;
}
@Override
public boolean isDonePlaying() {
return getVolume.get()<=0;
}
@Override
public void update() {
//NOP
}
@Override
public float getVolume() {
return getVolume.get();
}
@Override
public float getPitch() {
return getPitch.get();
}
}

View file

@ -16,6 +16,7 @@
package malte0811.industrialWires.converter;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@ -85,9 +86,32 @@ public final class MechEnergy {
}
}
@SideOnly(Side.CLIENT)
public boolean isAdjusting()
{
return ticksTillReached>=0;
//Sound helper methods
public float getVolumeSlow() {
return (1-getSoundLambda())*getTotalVolume();
}
public float getVolumeFast() {
return getSoundLambda()*getTotalVolume();
}
public float getPitch() {
return (float) Math.min(.3*Math.sqrt(getSpeedForSound()), 2);
}
private float getTotalVolume() {
float ret = (float) (weight / 20e3 * Math.tanh(getSpeedForSound()/30));
ret = Math.min(ret, 1.5F);
return ret;
}
private float getSoundLambda() {
return (float) MathHelper.clamp(getSpeedForSound() / 20 - .5F, 0, 1);
}
private double getSpeedForSound() {
final double MIN_SPEED = 5;
return getSpeed()-MIN_SPEED;//Volume should be zero by the time the sound stops
}
}