Sound framework improvements
This commit is contained in:
@@ -111,7 +111,6 @@ public class AssetsProcess extends BaseProcessor{
|
|||||||
|
|
||||||
HashSet<String> names = new HashSet<>();
|
HashSet<String> names = new HashSet<>();
|
||||||
Fi.get(path).walk(p -> {
|
Fi.get(path).walk(p -> {
|
||||||
String fname = p.name();
|
|
||||||
String name = p.nameWithoutExtension();
|
String name = p.nameWithoutExtension();
|
||||||
|
|
||||||
if(names.contains(name)){
|
if(names.contains(name)){
|
||||||
@@ -122,18 +121,18 @@ public class AssetsProcess extends BaseProcessor{
|
|||||||
|
|
||||||
if(SourceVersion.isKeyword(name)) name += "s";
|
if(SourceVersion.isKeyword(name)) name += "s";
|
||||||
|
|
||||||
String filepath = path.substring(path.lastIndexOf("/") + 1) + "/" + fname;
|
String filepath = path.substring(path.lastIndexOf("/") + 1) + p.path().substring(p.path().lastIndexOf(path) + path.length());
|
||||||
String filename = "\"" + filepath + "\"";
|
|
||||||
|
|
||||||
|
String filename = "\"" + filepath + "\"";
|
||||||
loadBegin.addStatement("arc.Core.assets.load(" + filename + ", " + rtype + ".class).loaded = a -> " + name + " = (" + rtype + ")a", filepath, filepath.replace(".ogg", ".mp3"));
|
loadBegin.addStatement("arc.Core.assets.load(" + filename + ", " + rtype + ".class).loaded = a -> " + name + " = (" + rtype + ")a", filepath, filepath.replace(".ogg", ".mp3"));
|
||||||
|
|
||||||
dispose.addStatement("arc.Core.assets.unload(" + filename + ")");
|
dispose.addStatement("arc.Core.assets.unload(" + filename + ")");
|
||||||
dispose.addStatement(name + " = null");
|
dispose.addStatement(name + " = null");
|
||||||
type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), name, Modifier.STATIC, Modifier.PUBLIC).initializer("new arc.mock.Mock" + rtype.substring(rtype.lastIndexOf(".") + 1) + "()").build());
|
type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), name, Modifier.STATIC, Modifier.PUBLIC).initializer("new arc.audio." + rtype.substring(rtype.lastIndexOf(".") + 1) + "()").build());
|
||||||
});
|
});
|
||||||
|
|
||||||
if(classname.equals("Sounds")){
|
if(classname.equals("Sounds")){
|
||||||
type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), "none", Modifier.STATIC, Modifier.PUBLIC).initializer("new arc.mock.Mock" + rtype.substring(rtype.lastIndexOf(".") + 1) + "()").build());
|
type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), "none", Modifier.STATIC, Modifier.PUBLIC).initializer("new arc.audio." + rtype.substring(rtype.lastIndexOf(".") + 1) + "()").build());
|
||||||
}
|
}
|
||||||
|
|
||||||
type.addMethod(loadBegin.build());
|
type.addMethod(loadBegin.build());
|
||||||
|
|||||||
@@ -10,11 +10,10 @@ import arc.util.*;
|
|||||||
import arc.util.Log.*;
|
import arc.util.Log.*;
|
||||||
import mindustry.ai.*;
|
import mindustry.ai.*;
|
||||||
import mindustry.async.*;
|
import mindustry.async.*;
|
||||||
import mindustry.audio.*;
|
|
||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.game.*;
|
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.input.*;
|
import mindustry.input.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
@@ -188,7 +187,6 @@ public class Vars implements Loadable{
|
|||||||
public static GameState state;
|
public static GameState state;
|
||||||
public static EntityCollisions collisions;
|
public static EntityCollisions collisions;
|
||||||
public static Waves waves;
|
public static Waves waves;
|
||||||
public static LoopControl loops;
|
|
||||||
public static Platform platform = new Platform(){};
|
public static Platform platform = new Platform(){};
|
||||||
public static Mods mods;
|
public static Mods mods;
|
||||||
public static Schematics schematics;
|
public static Schematics schematics;
|
||||||
@@ -255,7 +253,6 @@ public class Vars implements Loadable{
|
|||||||
if(mods == null) mods = new Mods();
|
if(mods == null) mods = new Mods();
|
||||||
|
|
||||||
content = new ContentLoader();
|
content = new ContentLoader();
|
||||||
loops = new LoopControl();
|
|
||||||
waves = new Waves();
|
waves = new Waves();
|
||||||
collisions = new EntityCollisions();
|
collisions = new EntityCollisions();
|
||||||
world = new World();
|
world = new World();
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
package mindustry.audio;
|
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.audio.*;
|
|
||||||
import arc.math.*;
|
|
||||||
import arc.math.geom.*;
|
|
||||||
import arc.struct.*;
|
|
||||||
import mindustry.*;
|
|
||||||
|
|
||||||
public class LoopControl{
|
|
||||||
private ObjectMap<Sound, SoundData> sounds = new ObjectMap<>();
|
|
||||||
|
|
||||||
public void play(Sound sound, float volume){
|
|
||||||
if(Vars.headless) return;
|
|
||||||
|
|
||||||
play(sound, Core.camera.position, volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play(Sound sound, Position pos, float volume){
|
|
||||||
if(Vars.headless) return;
|
|
||||||
|
|
||||||
float baseVol = sound.calcFalloff(pos.getX(), pos.getY());
|
|
||||||
float vol = baseVol * volume;
|
|
||||||
|
|
||||||
SoundData data = sounds.get(sound, SoundData::new);
|
|
||||||
data.volume += vol;
|
|
||||||
data.volume = Mathf.clamp(data.volume, 0f, 1f);
|
|
||||||
data.total += baseVol;
|
|
||||||
data.sum.add(pos.getX() * baseVol, pos.getY() * baseVol);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(){
|
|
||||||
float avol = Core.settings.getInt("ambientvol", 100) / 100f;
|
|
||||||
|
|
||||||
sounds.each((sound, data) -> {
|
|
||||||
data.curVolume = Mathf.lerpDelta(data.curVolume, data.volume * avol, 0.2f);
|
|
||||||
|
|
||||||
boolean play = data.curVolume > 0.01f;
|
|
||||||
float pan = Mathf.zero(data.total, 0.0001f) ? 0f : sound.calcPan(data.sum.x / data.total, data.sum.y / data.total);
|
|
||||||
if(data.soundID <= 0 || !sound.isPlaying(data.soundID)){
|
|
||||||
if(play){
|
|
||||||
data.soundID = sound.loop(data.curVolume, 1f, pan);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if(data.curVolume <= 0.001f){
|
|
||||||
sound.stop();
|
|
||||||
data.soundID = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sound.set(data.soundID, pan, data.curVolume);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.volume = 0f;
|
|
||||||
data.total = 0f;
|
|
||||||
data.sum.setZero();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SoundData{
|
|
||||||
float volume;
|
|
||||||
float total;
|
|
||||||
Vec2 sum = new Vec2();
|
|
||||||
|
|
||||||
int soundID;
|
|
||||||
float curVolume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,18 +2,21 @@ package mindustry.audio;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.audio.*;
|
import arc.audio.*;
|
||||||
import arc.audio.SoloudAudio.*;
|
import arc.audio.Filters.*;
|
||||||
|
import arc.files.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
/** Controls playback of multiple music tracks.*/
|
/** Controls playback of multiple audio tracks.*/
|
||||||
public class MusicControl{
|
public class SoundControl{
|
||||||
protected static final float finTime = 120f, foutTime = 120f, musicInterval = 60 * 60 * 3f, musicChance = 0.6f, musicWaveChance = 0.46f;
|
protected static final float finTime = 120f, foutTime = 120f, musicInterval = 60 * 60 * 3f, musicChance = 0.6f, musicWaveChance = 0.46f;
|
||||||
|
|
||||||
/** normal, ambient music, plays at any time */
|
/** normal, ambient music, plays at any time */
|
||||||
@@ -29,12 +32,15 @@ public class MusicControl{
|
|||||||
protected float fade;
|
protected float fade;
|
||||||
protected boolean silenced;
|
protected boolean silenced;
|
||||||
|
|
||||||
protected boolean wasPaused;
|
protected AudioBus uiBus = new AudioBus();
|
||||||
|
protected boolean wasPaused, wasPlaying;
|
||||||
protected AudioFilter filter = new BiquadFilter(){{
|
protected AudioFilter filter = new BiquadFilter(){{
|
||||||
set(0, 500, 1);
|
set(0, 500, 1);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public MusicControl(){
|
protected ObjectMap<Sound, SoundData> sounds = new ObjectMap<>();
|
||||||
|
|
||||||
|
public SoundControl(){
|
||||||
Events.on(ClientLoadEvent.class, e -> reload());
|
Events.on(ClientLoadEvent.class, e -> reload());
|
||||||
|
|
||||||
//only run music 10 seconds after a wave spawns
|
//only run music 10 seconds after a wave spawns
|
||||||
@@ -47,6 +53,13 @@ public class MusicControl{
|
|||||||
playRandom();
|
playRandom();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
setupFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setupFilters(){
|
||||||
|
Core.audio.soundBus.setFilter(0, filter);
|
||||||
|
Core.audio.soundBus.setFilterParam(0, Filters.paramWet, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void reload(){
|
protected void reload(){
|
||||||
@@ -55,6 +68,33 @@ public class MusicControl{
|
|||||||
ambientMusic = Seq.with(Musics.game1, Musics.game3, Musics.game6, Musics.game8, Musics.game9);
|
ambientMusic = Seq.with(Musics.game1, Musics.game3, Musics.game6, Musics.game8, Musics.game9);
|
||||||
darkMusic = Seq.with(Musics.game2, Musics.game5, Musics.game7, Musics.game4);
|
darkMusic = Seq.with(Musics.game2, Musics.game5, Musics.game7, Musics.game4);
|
||||||
bossMusic = Seq.with(Musics.boss1, Musics.boss2, Musics.game2, Musics.game5);
|
bossMusic = Seq.with(Musics.boss1, Musics.boss2, Musics.game2, Musics.game5);
|
||||||
|
|
||||||
|
//setup UI bus for all sounds that are in the UI folder
|
||||||
|
for(var sound : Core.assets.getAll(Sound.class, new Seq<>())){
|
||||||
|
var file = Fi.get(Core.assets.getAssetFileName(sound));
|
||||||
|
if(file.parent().name().equals("ui")){
|
||||||
|
sound.setBus(uiBus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loop(Sound sound, float volume){
|
||||||
|
if(Vars.headless) return;
|
||||||
|
|
||||||
|
loop(sound, Core.camera.position, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loop(Sound sound, Position pos, float volume){
|
||||||
|
if(Vars.headless) return;
|
||||||
|
|
||||||
|
float baseVol = sound.calcFalloff(pos.getX(), pos.getY());
|
||||||
|
float vol = baseVol * volume;
|
||||||
|
|
||||||
|
SoundData data = sounds.get(sound, SoundData::new);
|
||||||
|
data.volume += vol;
|
||||||
|
data.volume = Mathf.clamp(data.volume, 0f, 1f);
|
||||||
|
data.total += baseVol;
|
||||||
|
data.sum.add(pos.getX() * baseVol, pos.getY() * baseVol);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop(){
|
public void stop(){
|
||||||
@@ -69,10 +109,30 @@ public class MusicControl{
|
|||||||
/** Update and play the right music track.*/
|
/** Update and play the right music track.*/
|
||||||
public void update(){
|
public void update(){
|
||||||
boolean paused = state.isGame() && Core.scene.hasDialog();
|
boolean paused = state.isGame() && Core.scene.hasDialog();
|
||||||
|
boolean playing = state.isGame();
|
||||||
|
|
||||||
|
//check if current track is finished
|
||||||
|
if(current != null && !current.isPlaying()){
|
||||||
|
current = null;
|
||||||
|
fade = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//fade the lowpass filter in/out
|
||||||
if(paused != wasPaused){
|
if(paused != wasPaused){
|
||||||
Core.audio.setFilter(0, paused ? filter : null);
|
|
||||||
wasPaused = paused;
|
wasPaused = paused;
|
||||||
|
Core.audio.soundBus.fadeFilterParam(0, Filters.paramWet, paused ? 1f : 0f, 0.4f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//play/stop ordinary effects
|
||||||
|
if(playing != wasPlaying){
|
||||||
|
wasPlaying = playing;
|
||||||
|
|
||||||
|
if(playing){
|
||||||
|
Core.audio.soundBus.play();
|
||||||
|
setupFilters();
|
||||||
|
}else{
|
||||||
|
Core.audio.soundBus.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.isMenu()){
|
if(state.isMenu()){
|
||||||
@@ -99,6 +159,42 @@ public class MusicControl{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateLoops();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateLoops(){
|
||||||
|
//clear loops when in menu
|
||||||
|
if(!state.isGame()){
|
||||||
|
sounds.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float avol = Core.settings.getInt("ambientvol", 100) / 100f;
|
||||||
|
|
||||||
|
sounds.each((sound, data) -> {
|
||||||
|
data.curVolume = Mathf.lerpDelta(data.curVolume, data.volume * avol, 0.2f);
|
||||||
|
|
||||||
|
boolean play = data.curVolume > 0.01f;
|
||||||
|
float pan = Mathf.zero(data.total, 0.0001f) ? 0f : sound.calcPan(data.sum.x / data.total, data.sum.y / data.total);
|
||||||
|
if(data.soundID <= 0 || !Core.audio.isPlaying(data.soundID)){
|
||||||
|
if(play){
|
||||||
|
data.soundID = sound.loop(data.curVolume, 1f, pan);
|
||||||
|
Core.audio.protect(data.soundID, true);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(data.curVolume <= 0.001f){
|
||||||
|
sound.stop();
|
||||||
|
data.soundID = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Core.audio.set(data.soundID, pan, data.curVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.volume = 0f;
|
||||||
|
data.total = 0f;
|
||||||
|
data.sum.setZero();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Plays a random track.*/
|
/** Plays a random track.*/
|
||||||
@@ -191,12 +287,6 @@ public class MusicControl{
|
|||||||
current = music;
|
current = music;
|
||||||
current.setVolume(1f);
|
current.setVolume(1f);
|
||||||
current.setLooping(false);
|
current.setLooping(false);
|
||||||
current.setCompletionListener(m -> {
|
|
||||||
if(current == m){
|
|
||||||
current = null;
|
|
||||||
fade = 0f;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
current.play();
|
current.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,4 +298,13 @@ public class MusicControl{
|
|||||||
protected void silence(){
|
protected void silence(){
|
||||||
play(null);
|
play(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static class SoundData{
|
||||||
|
float volume;
|
||||||
|
float total;
|
||||||
|
Vec2 sum = new Vec2();
|
||||||
|
|
||||||
|
int soundID;
|
||||||
|
float curVolume;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.audio;
|
package mindustry.audio;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
import arc.audio.*;
|
import arc.audio.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -31,19 +32,19 @@ public class SoundLoop{
|
|||||||
}else{
|
}else{
|
||||||
volume = Mathf.clamp(volume - fadeSpeed * Time.delta);
|
volume = Mathf.clamp(volume - fadeSpeed * Time.delta);
|
||||||
if(volume <= 0.001f){
|
if(volume <= 0.001f){
|
||||||
sound.stop(id);
|
Core.audio.stop(id);
|
||||||
id = -1;
|
id = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sound.set(id, sound.calcPan(x, y), sound.calcVolume(x, y) * volume * baseVolume);
|
Core.audio.set(id, sound.calcPan(x, y), sound.calcVolume(x, y) * volume * baseVolume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop(){
|
public void stop(){
|
||||||
if(id != -1){
|
if(id != -1){
|
||||||
sound.stop(id);
|
Core.audio.stop(id);
|
||||||
id = -1;
|
id = -1;
|
||||||
volume = baseVolume = -1;
|
volume = baseVolume = -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import static mindustry.Vars.*;
|
|||||||
*/
|
*/
|
||||||
public class Control implements ApplicationListener, Loadable{
|
public class Control implements ApplicationListener, Loadable{
|
||||||
public Saves saves;
|
public Saves saves;
|
||||||
public MusicControl music;
|
public SoundControl sound;
|
||||||
public Tutorial tutorial;
|
public Tutorial tutorial;
|
||||||
public InputHandler input;
|
public InputHandler input;
|
||||||
|
|
||||||
@@ -52,14 +52,11 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
public Control(){
|
public Control(){
|
||||||
saves = new Saves();
|
saves = new Saves();
|
||||||
tutorial = new Tutorial();
|
tutorial = new Tutorial();
|
||||||
music = new MusicControl();
|
sound = new SoundControl();
|
||||||
|
|
||||||
Events.on(StateChangeEvent.class, event -> {
|
Events.on(StateChangeEvent.class, event -> {
|
||||||
if((event.from == State.playing && event.to == State.menu) || (event.from == State.menu && event.to != State.menu)){
|
if((event.from == State.playing && event.to == State.menu) || (event.from == State.menu && event.to != State.menu)){
|
||||||
Time.runTask(5f, platform::updateRPC);
|
Time.runTask(5f, platform::updateRPC);
|
||||||
for(Sound sound : assets.getAll(Sound.class, new Seq<>())){
|
|
||||||
sound.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -497,8 +494,7 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
|
|
||||||
input.updateState();
|
input.updateState();
|
||||||
|
|
||||||
music.update();
|
sound.update();
|
||||||
loops.update();
|
|
||||||
|
|
||||||
if(Core.input.keyTap(Binding.fullscreen)){
|
if(Core.input.keyTap(Binding.fullscreen)){
|
||||||
boolean full = settings.getBool("fullscreen");
|
boolean full = settings.getBool("fullscreen");
|
||||||
|
|||||||
@@ -1368,12 +1368,14 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sound != null){
|
if(!headless){
|
||||||
sound.update(x, y, shouldActiveSound());
|
if(sound != null){
|
||||||
}
|
sound.update(x, y, shouldActiveSound());
|
||||||
|
}
|
||||||
|
|
||||||
if(block.ambientSound != Sounds.none && shouldAmbientSound()){
|
if(block.ambientSound != Sounds.none && shouldAmbientSound()){
|
||||||
loops.play(block.ambientSound, self(), block.ambientSoundVolume * ambientVolume());
|
control.sound.loop(block.ambientSound, self(), block.ambientSoundVolume * ambientVolume());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enabled || !block.noUpdateDisabled){
|
if(enabled || !block.noUpdateDisabled){
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ abstract class FireComp implements Timedc, Posc, Firec, Syncc{
|
|||||||
Fx.fireSmoke.at(x + Mathf.range(4f), y + Mathf.range(4f));
|
Fx.fireSmoke.at(x + Mathf.range(4f), y + Mathf.range(4f));
|
||||||
}
|
}
|
||||||
|
|
||||||
loops.play(Sounds.fire, this, 0.07f);
|
if(!headless){
|
||||||
|
control.sound.loop(Sounds.fire, this, 0.07f);
|
||||||
|
}
|
||||||
|
|
||||||
time = Mathf.clamp(time + Time.delta, 0, lifetime());
|
time = Mathf.clamp(time + Time.delta, 0, lifetime());
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!headless){
|
if(!headless){
|
||||||
loops.play(type.mineSound, this, type.mineSoundVolume);
|
control.sound.loop(type.mineSound, this, type.mineSoundVolume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class LAssembler{
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
for(String line : lines){
|
for(String line : lines){
|
||||||
//comments
|
//comments
|
||||||
if(line.startsWith("#")) continue;
|
if(line.startsWith("#") || line.isEmpty()) continue;
|
||||||
//remove trailing semicolons in case someone adds them in for no reason
|
//remove trailing semicolons in case someone adds them in for no reason
|
||||||
if(line.endsWith(";")) line = line.substring(0, line.length() - 1);
|
if(line.endsWith(";")) line = line.substring(0, line.length() - 1);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package mindustry.mod;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.assets.*;
|
import arc.assets.*;
|
||||||
|
import arc.assets.loaders.*;
|
||||||
|
import arc.assets.loaders.SoundLoader.*;
|
||||||
import arc.audio.*;
|
import arc.audio.*;
|
||||||
import arc.files.*;
|
import arc.files.*;
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
@@ -89,15 +91,14 @@ public class ContentParser{
|
|||||||
});
|
});
|
||||||
put(Sound.class, (type, data) -> {
|
put(Sound.class, (type, data) -> {
|
||||||
if(fieldOpt(Sounds.class, data) != null) return fieldOpt(Sounds.class, data);
|
if(fieldOpt(Sounds.class, data) != null) return fieldOpt(Sounds.class, data);
|
||||||
if(Vars.headless) return new MockSound();
|
if(Vars.headless) return new Sound();
|
||||||
|
|
||||||
String name = "sounds/" + data.asString();
|
String name = "sounds/" + data.asString();
|
||||||
String path = Vars.tree.get(name + ".ogg").exists() ? name + ".ogg" : name + ".mp3";
|
String path = Vars.tree.get(name + ".ogg").exists() ? name + ".ogg" : name + ".mp3";
|
||||||
|
|
||||||
if(Core.assets.contains(path, Sound.class)) return Core.assets.get(path, Sound.class);
|
if(Core.assets.contains(path, Sound.class)) return Core.assets.get(path, Sound.class);
|
||||||
ModLoadingSound sound = new ModLoadingSound();
|
var sound = new Sound();
|
||||||
AssetDescriptor<?> desc = Core.assets.load(path, Sound.class);
|
AssetDescriptor<?> desc = Core.assets.load(path, Sound.class, new SoundParameter(sound));
|
||||||
desc.loaded = result -> sound.sound = (Sound)result;
|
|
||||||
desc.errored = Throwable::printStackTrace;
|
desc.errored = Throwable::printStackTrace;
|
||||||
return sound;
|
return sound;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
package mindustry.mod;
|
|
||||||
|
|
||||||
import arc.audio.*;
|
|
||||||
import arc.mock.*;
|
|
||||||
import arc.util.*;
|
|
||||||
|
|
||||||
public class ModLoadingMusic implements Music{
|
|
||||||
public Music music = new MockMusic();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void play(){
|
|
||||||
music.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pause(){
|
|
||||||
music.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop(){
|
|
||||||
music.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPlaying(){
|
|
||||||
return music.isPlaying();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLooping(){
|
|
||||||
return music.isLooping();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLooping(boolean isLooping){
|
|
||||||
music.setLooping(isLooping);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getVolume(){
|
|
||||||
return music.getVolume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVolume(float volume){
|
|
||||||
music.setVolume(volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPan(float pan, float volume){
|
|
||||||
music.setPan(pan, volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getPosition(){
|
|
||||||
return music.getPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(float position){
|
|
||||||
music.setPosition(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose(){
|
|
||||||
music.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCompletionListener(OnCompletionListener listener){
|
|
||||||
music.setCompletionListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFilter(int index, @Nullable AudioFilter filter){
|
|
||||||
music.setFilter(index, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDisposed(){
|
|
||||||
return music.isDisposed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
package mindustry.mod;
|
|
||||||
|
|
||||||
import arc.audio.*;
|
|
||||||
import arc.math.geom.*;
|
|
||||||
import arc.mock.*;
|
|
||||||
import arc.util.*;
|
|
||||||
|
|
||||||
public class ModLoadingSound implements Sound{
|
|
||||||
public Sound sound = new MockSound();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float calcPan(float x, float y){
|
|
||||||
return sound.calcPan(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float calcVolume(float x, float y){
|
|
||||||
return sound.calcVolume(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float calcFalloff(float x, float y){
|
|
||||||
return sound.calcFalloff(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int at(float x, float y, float pitch){
|
|
||||||
return sound.at(x, y, pitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int at(float x, float y){
|
|
||||||
return sound.at(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int at(Position pos){
|
|
||||||
return sound.at(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int at(Position pos, float pitch){
|
|
||||||
return sound.at(pos, pitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int play(){
|
|
||||||
return sound.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int play(float volume){
|
|
||||||
return sound.play(volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int play(float volume, float pitch, float pan){
|
|
||||||
return sound.play(volume, pitch, pan);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int loop(){
|
|
||||||
return sound.loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int loop(float volume){
|
|
||||||
return sound.loop(volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int loop(float volume, float pitch, float pan){
|
|
||||||
return sound.loop(volume, pitch, pan);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop(){
|
|
||||||
sound.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose(){
|
|
||||||
sound.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop(int soundId){
|
|
||||||
sound.stop(soundId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pause(int soundId){
|
|
||||||
sound.pause(soundId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resume(int soundId){
|
|
||||||
sound.resume(soundId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLooping(int soundId, boolean looping){
|
|
||||||
sound.setLooping(soundId, looping);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPitch(int soundId, float pitch){
|
|
||||||
sound.setPitch(soundId, pitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVolume(int soundId, float volume){
|
|
||||||
sound.setVolume(soundId, volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(int soundId, float pan, float volume){
|
|
||||||
sound.set(soundId, pan, volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDisposed(){
|
|
||||||
return sound.isDisposed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int play(float volume, float pitch, float pan, boolean loop){
|
|
||||||
return sound.play(volume, pitch, pan, loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFilter(int index, @Nullable AudioFilter filter){
|
|
||||||
sound.setFilter(index, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPlaying(int soundId){
|
|
||||||
return sound.isPlaying(soundId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,10 @@ package mindustry.mod;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.assets.*;
|
import arc.assets.*;
|
||||||
|
import arc.assets.loaders.MusicLoader.*;
|
||||||
|
import arc.assets.loaders.SoundLoader.*;
|
||||||
import arc.audio.*;
|
import arc.audio.*;
|
||||||
import arc.files.*;
|
import arc.files.*;
|
||||||
import arc.mock.*;
|
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.Log.*;
|
import arc.util.Log.*;
|
||||||
@@ -87,33 +88,31 @@ public class Scripts implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Sound loadSound(String soundName){
|
public Sound loadSound(String soundName){
|
||||||
if(Vars.headless) return new MockSound();
|
if(Vars.headless) return new Sound();
|
||||||
|
|
||||||
String name = "sounds/" + soundName;
|
String name = "sounds/" + soundName;
|
||||||
String path = Vars.tree.get(name + ".ogg").exists() ? name + ".ogg" : name + ".mp3";
|
String path = Vars.tree.get(name + ".ogg").exists() ? name + ".ogg" : name + ".mp3";
|
||||||
|
|
||||||
if(Core.assets.contains(path, Sound.class)) return Core.assets.get(path, Sound.class);
|
if(Core.assets.contains(path, Sound.class)) return Core.assets.get(path, Sound.class);
|
||||||
ModLoadingSound sound = new ModLoadingSound();
|
var sound = new Sound();
|
||||||
AssetDescriptor<?> desc = Core.assets.load(path, Sound.class);
|
AssetDescriptor<?> desc = Core.assets.load(path, Sound.class, new SoundParameter(sound));
|
||||||
desc.loaded = result -> sound.sound = (Sound)result;
|
|
||||||
desc.errored = Throwable::printStackTrace;
|
desc.errored = Throwable::printStackTrace;
|
||||||
|
|
||||||
return sound;
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Music loadMusic(String soundName){
|
public Music loadMusic(String soundName){
|
||||||
if(Vars.headless) return new MockMusic();
|
if(Vars.headless) return new Music();
|
||||||
|
|
||||||
String name = "music/" + soundName;
|
String name = "music/" + soundName;
|
||||||
String path = Vars.tree.get(name + ".ogg").exists() ? name + ".ogg" : name + ".mp3";
|
String path = Vars.tree.get(name + ".ogg").exists() ? name + ".ogg" : name + ".mp3";
|
||||||
|
|
||||||
if(Core.assets.contains(path, Music.class)) return Core.assets.get(path, Music.class);
|
if(Core.assets.contains(path, Music.class)) return Core.assets.get(path, Music.class);
|
||||||
ModLoadingMusic sound = new ModLoadingMusic();
|
var music = new Music();
|
||||||
AssetDescriptor<?> desc = Core.assets.load(path, Music.class);
|
AssetDescriptor<?> desc = Core.assets.load(path, Music.class, new MusicParameter(music));
|
||||||
desc.loaded = result -> sound.music = (Music)result;
|
|
||||||
desc.errored = Throwable::printStackTrace;
|
desc.errored = Throwable::printStackTrace;
|
||||||
|
|
||||||
return sound;
|
return music;
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|||||||
@@ -356,12 +356,12 @@ public class UnitType extends UnlockableContent{
|
|||||||
ItemStack[] stacks = null;
|
ItemStack[] stacks = null;
|
||||||
|
|
||||||
//calculate costs based on reconstructors or factories found
|
//calculate costs based on reconstructors or factories found
|
||||||
Block rec = content.blocks().find(b -> b instanceof Reconstructor && ((Reconstructor)b).upgrades.contains(u -> u[1] == this));
|
Block rec = content.blocks().find(b -> b instanceof Reconstructor re && re.upgrades.contains(u -> u[1] == this));
|
||||||
|
|
||||||
if(rec != null && rec.consumes.has(ConsumeType.item) && rec.consumes.get(ConsumeType.item) instanceof ConsumeItems){
|
if(rec != null && rec.consumes.has(ConsumeType.item) && rec.consumes.get(ConsumeType.item) instanceof ConsumeItems ci){
|
||||||
stacks = ((ConsumeItems)rec.consumes.get(ConsumeType.item)).items;
|
stacks = ci.items;
|
||||||
}else{
|
}else{
|
||||||
UnitFactory factory = (UnitFactory)content.blocks().find(u -> u instanceof UnitFactory && ((UnitFactory)u).plans.contains(p -> p.unit == this));
|
UnitFactory factory = (UnitFactory)content.blocks().find(u -> u instanceof UnitFactory uf && uf.plans.contains(p -> p.unit == this));
|
||||||
if(factory != null){
|
if(factory != null){
|
||||||
stacks = factory.plans.find(p -> p.unit == this).requirements;
|
stacks = factory.plans.find(p -> p.unit == this).requirements;
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
if(stacks != null){
|
if(stacks != null){
|
||||||
ItemStack[] out = new ItemStack[stacks.length];
|
ItemStack[] out = new ItemStack[stacks.length];
|
||||||
for(int i = 0; i < out.length; i++){
|
for(int i = 0; i < out.length; i++){
|
||||||
out[i] = new ItemStack(stacks[i].item, UI.roundAmount((int)(Math.pow(stacks[i].amount, 1) * 50)));
|
out[i] = new ItemStack(stacks[i].item, UI.roundAmount((int)(Math.pow(stacks[i].amount, 1.1) * 50)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public abstract class Weather extends UnlockableContent{
|
|||||||
|
|
||||||
if(!headless && sound != Sounds.none){
|
if(!headless && sound != Sounds.none){
|
||||||
float noise = soundVolOscMag > 0 ? (float)Math.abs(Noise.rawNoise(Time.time() / soundVolOscScl)) * soundVolOscMag : 0;
|
float noise = soundVolOscMag > 0 ? (float)Math.abs(Noise.rawNoise(Time.time() / soundVolOscScl)) * soundVolOscMag : 0;
|
||||||
loops.play(sound, Math.max((soundVol + noise) * state.opacity, soundVolMin));
|
control.sound.loop(sound, Math.max((soundVol + noise) * state.opacity, soundVolMin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
if(to.near().contains(launchSector)) return launchSector;
|
if(to.near().contains(launchSector)) return launchSector;
|
||||||
|
|
||||||
Sector launchFrom = launchSector;
|
Sector launchFrom = launchSector;
|
||||||
if(launchFrom == null){
|
if(launchFrom == null || (to.preset == null && !to.near().contains(launchSector))){
|
||||||
//TODO pick one with the most resources
|
//TODO pick one with the most resources
|
||||||
launchFrom = to.near().find(Sector::hasBase);
|
launchFrom = to.near().find(Sector::hasBase);
|
||||||
if(launchFrom == null && to.preset != null){
|
if(launchFrom == null && to.preset != null){
|
||||||
@@ -465,7 +465,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for(ItemStack stack : items){
|
for(ItemStack stack : items){
|
||||||
res.image(stack.item.icon(Cicon.small)).padRight(3);
|
res.image(stack.item.icon(Cicon.small)).padRight(3);
|
||||||
res.add(UI.formatAmount(stack.amount)).color(Color.lightGray);
|
res.add(UI.formatAmount(Math.max(stack.amount, 0))).color(Color.lightGray);
|
||||||
if(++i % 2 == 0){
|
if(++i % 2 == 0){
|
||||||
res.row();
|
res.row();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -617,7 +617,7 @@ public class Block extends UnlockableContent{
|
|||||||
public ItemStack[] researchRequirements(){
|
public ItemStack[] researchRequirements(){
|
||||||
ItemStack[] out = new ItemStack[requirements.length];
|
ItemStack[] out = new ItemStack[requirements.length];
|
||||||
for(int i = 0; i < out.length; i++){
|
for(int i = 0; i < out.length; i++){
|
||||||
int quantity = 60 + Mathf.round(Mathf.pow(requirements[i].amount, 1.09f) * 20 * researchCostMultiplier, 10);
|
int quantity = 60 + Mathf.round(Mathf.pow(requirements[i].amount, 1.11f) * 20 * researchCostMultiplier, 10);
|
||||||
|
|
||||||
out[i] = new ItemStack(requirements[i].item, UI.roundAmount(quantity));
|
out[i] = new ItemStack(requirements[i].item, UI.roundAmount(quantity));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,9 @@ public class TractorBeamTurret extends BaseTurret{
|
|||||||
|
|
||||||
//look at target
|
//look at target
|
||||||
if(target != null && target.within(this, range) && target.team() != team && target.type.flying && efficiency() > 0.01f){
|
if(target != null && target.within(this, range) && target.team() != team && target.type.flying && efficiency() > 0.01f){
|
||||||
loops.play(shootSound, this, shootSoundVolume);
|
if(!headless){
|
||||||
|
control.sound.loop(shootSound, this, shootSoundVolume);
|
||||||
|
}
|
||||||
|
|
||||||
any = true;
|
any = true;
|
||||||
float dest = angleTo(target);
|
float dest = angleTo(target);
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=f7fcd4a78e01b1ad41e1bc57c25a78d12c51ec54
|
archash=a14ed44889c9baa7ea20bb22c576c8e1aa7d3fff
|
||||||
|
|||||||
Reference in New Issue
Block a user