mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-07-04 09:29:28 +00:00
Update music score and added resume mode to song playback for wilderness
This commit is contained in:
parent
026e1c2e5d
commit
e6113e2ac6
8
Platform/Apple/tools/jace/.idea/.gitignore
vendored
Normal file
8
Platform/Apple/tools/jace/.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
23
Platform/Apple/tools/jace/lawlesslegends.iml
Normal file
23
Platform/Apple/tools/jace/lawlesslegends.iml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.12" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.javassist:javassist:3.26.0-GA" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.13.2" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.collections:eclipse-collections:10.4.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.collections:eclipse-collections-api:10.4.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.xerial.thirdparty:nestedvm:1.0" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -14,10 +14,14 @@ import java.io.InputStreamReader;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import javafx.util.Duration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hacks that affect lawless legends gameplay
|
* Hacks that affect lawless legends gameplay
|
||||||
@ -32,7 +36,7 @@ public class LawlessHacks extends Cheats {
|
|||||||
public LawlessHacks(Computer computer) {
|
public LawlessHacks(Computer computer) {
|
||||||
super(computer);
|
super(computer);
|
||||||
readScores();
|
readScores();
|
||||||
currentScore = SCORE_ORCHESTRAL;
|
currentScore = SCORE_CHIPTUNE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -76,8 +80,8 @@ public class LawlessHacks extends Cheats {
|
|||||||
|
|
||||||
public static final String SCORE_NONE = "none";
|
public static final String SCORE_NONE = "none";
|
||||||
public static final String SCORE_COMMON = "common";
|
public static final String SCORE_COMMON = "common";
|
||||||
public static final String SCORE_ORCHESTRAL = "orchestral";
|
public static final String SCORE_ORCHESTRAL = "8-bit orchestral samples";
|
||||||
public static final String SCORE_CHIPTUNE = "chiptune";
|
public static final String SCORE_CHIPTUNE = "8-bit chipmusic";
|
||||||
|
|
||||||
private static int currentSong;
|
private static int currentSong;
|
||||||
private static boolean repeatSong = false;
|
private static boolean repeatSong = false;
|
||||||
@ -100,14 +104,14 @@ public class LawlessHacks extends Cheats {
|
|||||||
}
|
}
|
||||||
} else if (isMusic) {
|
} else if (isMusic) {
|
||||||
System.out.println("Play music "+track);
|
System.out.println("Play music "+track);
|
||||||
playMusic(track);
|
playMusic(track, false);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Play sfx "+track);
|
System.out.println("Play sfx "+track);
|
||||||
playSfx(track);
|
playSfx(track);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Media getAudioTrack(int number) {
|
private String getSongName(int number) {
|
||||||
Map<Integer, String> score = scores.get(currentScore);
|
Map<Integer, String> score = scores.get(currentScore);
|
||||||
if (score == null) {
|
if (score == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -120,6 +124,11 @@ public class LawlessHacks extends Cheats {
|
|||||||
}
|
}
|
||||||
filename = score.get(number);
|
filename = score.get(number);
|
||||||
}
|
}
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Media getAudioTrack(int number) {
|
||||||
|
String filename = getSongName(number);
|
||||||
String pathStr = "jace/data/sound/" + filename;
|
String pathStr = "jace/data/sound/" + filename;
|
||||||
// System.out.println("looking in "+pathStr);
|
// System.out.println("looking in "+pathStr);
|
||||||
URL path = getClass().getClassLoader().getResource(pathStr);
|
URL path = getClass().getClassLoader().getResource(pathStr);
|
||||||
@ -134,11 +143,11 @@ public class LawlessHacks extends Cheats {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playMusic(int track) {
|
private void playMusic(int track, boolean switchScores) {
|
||||||
if (currentSong != track) {
|
if (currentSong != track || switchScores) {
|
||||||
fadeOutSong(() -> startNewSong(track));
|
fadeOutSong(() -> startNewSong(track, switchScores));
|
||||||
} else {
|
} else {
|
||||||
new Thread(() -> startNewSong(track)).start();
|
new Thread(() -> startNewSong(track, false)).start();
|
||||||
}
|
}
|
||||||
currentSong = track;
|
currentSong = track;
|
||||||
}
|
}
|
||||||
@ -155,10 +164,21 @@ public class LawlessHacks extends Cheats {
|
|||||||
playbackEffect = null;
|
playbackEffect = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<Double> getCurrentTime() {
|
||||||
|
if (currentSongPlayer == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
} else if (currentSongPlayer.getCurrentTime() == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
} else {
|
||||||
|
return Optional.of(currentSongPlayer.getCurrentTime().toMillis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void fadeOutSong(Runnable nextAction) {
|
private void fadeOutSong(Runnable nextAction) {
|
||||||
stopSongEffect();
|
stopSongEffect();
|
||||||
MediaPlayer player = currentSongPlayer;
|
MediaPlayer player = currentSongPlayer;
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
getCurrentTime().ifPresent(val -> lastTime.put(currentSong, val + 1500));
|
||||||
playbackEffect = new Thread(() -> {
|
playbackEffect = new Thread(() -> {
|
||||||
DoubleProperty volume = player.volumeProperty();
|
DoubleProperty volume = player.volumeProperty();
|
||||||
while (playbackEffect == Thread.currentThread() && volume.get() > 0.0) {
|
while (playbackEffect == Thread.currentThread() && volume.get() > 0.0) {
|
||||||
@ -207,23 +227,29 @@ public class LawlessHacks extends Cheats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double FADE_AMT = 0.05; // 5% per interval, or 20 stops between 0% and 100%
|
double FADE_AMT = 0.05; // 5% per interval, or 20 stops between 0% and 100%
|
||||||
int FADE_SPEED = 100; // 100ms per 5%, or 2 second duration
|
// int FADE_SPEED = 100; // 100ms per 5%, or 2 second duration
|
||||||
|
int FADE_SPEED = 75; // 75ms per 5%, or 1.5 second duration
|
||||||
|
|
||||||
private void startNewSong(int track) {
|
private void startNewSong(int track, boolean switchScores) {
|
||||||
if (!isMusicEnabled()) {
|
if (!isMusicEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MediaPlayer player;
|
MediaPlayer player;
|
||||||
if (track != currentSong || !isPlayingMusic()) {
|
if (track != currentSong || !isPlayingMusic() || switchScores) {
|
||||||
// If the same song is already playing don't restart it
|
// If the same song is already playing don't restart it
|
||||||
Media song = getAudioTrack(track);
|
Media song = getAudioTrack(track);
|
||||||
if (song == null) {
|
if (song == null) {
|
||||||
System.out.println("Unable to start song " + track + "; File not found");
|
System.out.println("Unable to start song " + track + "; File " + getSongName(track) + " not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player = new MediaPlayer(song);
|
player = new MediaPlayer(song);
|
||||||
player.setCycleCount(repeatSong ? MediaPlayer.INDEFINITE : 1);
|
player.setCycleCount(repeatSong ? MediaPlayer.INDEFINITE : 1);
|
||||||
player.setVolume(0.0);
|
player.setVolume(0.0);
|
||||||
|
if (autoResume.contains(track) || switchScores) {
|
||||||
|
double time = lastTime.getOrDefault(track, 0.0);
|
||||||
|
System.out.println("Auto-resume from time " + time);
|
||||||
|
player.setStartTime(Duration.millis(time));
|
||||||
|
}
|
||||||
player.play();
|
player.play();
|
||||||
} else {
|
} else {
|
||||||
// But if the same song was already playing but possibly fading out
|
// But if the same song was already playing but possibly fading out
|
||||||
@ -272,10 +298,7 @@ public class LawlessHacks extends Cheats {
|
|||||||
stopMusic();
|
stopMusic();
|
||||||
currentSong = -1;
|
currentSong = -1;
|
||||||
} else if ((currentSongPlayer != null || wasStoppedPreviously) && currentSong > 0) {
|
} else if ((currentSongPlayer != null || wasStoppedPreviously) && currentSong > 0) {
|
||||||
stopSongEffect();
|
playMusic(currentSong, true);
|
||||||
int currentSongTemp = currentSong;
|
|
||||||
currentSong = Integer.MAX_VALUE;
|
|
||||||
startNewSong(currentSongTemp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,9 +307,11 @@ public class LawlessHacks extends Cheats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Pattern COMMENT = Pattern.compile("\\s*[-#;']+.*");
|
Pattern COMMENT = Pattern.compile("\\s*[-#;']+.*");
|
||||||
Pattern LABEL = Pattern.compile("[A-Za-z\\s\\-_]+");
|
Pattern LABEL = Pattern.compile("(8-)?[A-Za-z\\s\\-_]+");
|
||||||
Pattern ENTRY = Pattern.compile("([0-9]+)\\s+(.*)");
|
Pattern ENTRY = Pattern.compile("([0-9]+)\\s+(.*)");
|
||||||
private Map<String, Map<Integer, String>> scores = new HashMap<>();
|
private final Map<String, Map<Integer, String>> scores = new HashMap<>();
|
||||||
|
private final Set<Integer> autoResume = new HashSet<>();
|
||||||
|
private final Map<Integer, Double> lastTime = new HashMap<>();
|
||||||
private void readScores() {
|
private void readScores() {
|
||||||
InputStream data = getClass().getClassLoader().getResourceAsStream("jace/data/sound/scores.txt");
|
InputStream data = getClass().getClassLoader().getResourceAsStream("jace/data/sound/scores.txt");
|
||||||
readScores(data);
|
readScores(data);
|
||||||
@ -295,6 +320,11 @@ public class LawlessHacks extends Cheats {
|
|||||||
private void readScores(InputStream data) {
|
private void readScores(InputStream data) {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(data));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(data));
|
||||||
reader.lines().forEach(line -> {
|
reader.lines().forEach(line -> {
|
||||||
|
boolean useAutoResume = false;
|
||||||
|
if (line.indexOf('*') > 0) {
|
||||||
|
useAutoResume = true;
|
||||||
|
line = line.replace("*", "");
|
||||||
|
}
|
||||||
if (COMMENT.matcher(line).matches() || line.trim().isEmpty()) {
|
if (COMMENT.matcher(line).matches() || line.trim().isEmpty()) {
|
||||||
// System.out.println("Ignoring: "+line);
|
// System.out.println("Ignoring: "+line);
|
||||||
return;
|
return;
|
||||||
@ -308,6 +338,9 @@ public class LawlessHacks extends Cheats {
|
|||||||
int num = Integer.parseInt(m.group(1));
|
int num = Integer.parseInt(m.group(1));
|
||||||
String file = m.group(2);
|
String file = m.group(2);
|
||||||
scores.get(currentScore).put(num, file);
|
scores.get(currentScore).put(num, file);
|
||||||
|
if (useAutoResume) {
|
||||||
|
autoResume.add(num);
|
||||||
|
}
|
||||||
// System.out.println("Score: " + currentScore + "; Song: " + num + "; " + file);
|
// System.out.println("Score: " + currentScore + "; Song: " + num + "; " + file);
|
||||||
} else {
|
} else {
|
||||||
// System.out.println("Couldn't parse: " + line);
|
// System.out.println("Couldn't parse: " + line);
|
||||||
|
@ -83,13 +83,13 @@
|
|||||||
<ComboBox fx:id="musicSelection">
|
<ComboBox fx:id="musicSelection">
|
||||||
<items>
|
<items>
|
||||||
<FXCollections fx:factory="observableArrayList">
|
<FXCollections fx:factory="observableArrayList">
|
||||||
<String fx:value="Orchestral" />
|
<String fx:value="8-bit Chipmusic" />
|
||||||
<String fx:value="Chiptune" />
|
<String fx:value="8-bit Orchestral samples" />
|
||||||
<String fx:value="None" />
|
<String fx:value="None" />
|
||||||
</FXCollections>
|
</FXCollections>
|
||||||
</items>
|
</items>
|
||||||
<value>
|
<value>
|
||||||
<String fx:value="Orchestral"/>
|
<String fx:value="8-bit Chipmusic"/>
|
||||||
</value>
|
</value>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<!--
|
<!--
|
||||||
|
@ -1,48 +1,49 @@
|
|||||||
---- Scores file defines all the music and SFX
|
---- Scores file defines all the music and SFX
|
||||||
---- Note: Anything that is shared for all scores is under the "common" section
|
---- Note: Anything that is shared for all scores is under the "common" section
|
||||||
---- Lines that start with dashes, hash marks, single quotes are treated as comments
|
---- Lines that start with dashes, hash marks, single quotes are treated as comments
|
||||||
|
---- Lines that contain an asterisk will use auto-resume, otherwise will always restart
|
||||||
Common
|
Common
|
||||||
--- Sound effects start at number 129
|
--- Sound effects start at number 129
|
||||||
129 bang.mp3
|
129 bang.mp3
|
||||||
130 boom.mp3
|
130 boom.mp3
|
||||||
|
|
||||||
Orchestral
|
8-bit Orchestral samples
|
||||||
1 Title.mp3
|
1 8 Bit Weapon - Lawless Legends Original Double Score - 19 Lawless Legends 8-Bit Samples.mp3
|
||||||
2 Miller.mp3
|
2 8 Bit Weapon - Lawless Legends Original Double Score - 20 Fort Miller 8-Bit Samples.mp3
|
||||||
3 Tragedy.mp3
|
3 8 Bit Weapon - Lawless Legends Original Double Score - 21 Tragedy in the West 8-Bit Samples.mp3
|
||||||
4 Victory.mp3
|
4 8 Bit Weapon - Lawless Legends Original Double Score - 22 Victory! 8-Bit Samples.mp3
|
||||||
5 Grub.mp3
|
5 8 Bit Weapon - Lawless Legends Original Double Score - 23 Grub Gulch 8-Bit Samples.mp3
|
||||||
6 mines.mp3
|
6 8 Bit Weapon - Lawless Legends Original Double Score - 25 Mines of Mystery 8-Bit Samples.mp3
|
||||||
7 Texas.mp3
|
7 8 Bit Weapon - Lawless Legends Original Double Score - 24 Texas Flats 8-Bit Samples.mp3
|
||||||
8 Strange.mp3
|
8 8 Bit Weapon - Lawless Legends Original Double Score - 26 Strange Tales 8-Bit Samples.mp3
|
||||||
9 Oro.mp3
|
9 8 Bit Weapon - Lawless Legends Original Double Score - 27 Oro's Villa 8-Bit Samples.mp3
|
||||||
10 Village.mp3
|
10 8 Bit Weapon - Lawless Legends Original Double Score - 28 Tahnku Village 8-Bit Samples.mp3
|
||||||
11 Sanctuary.mp3
|
11 8 Bit Weapon - Lawless Legends Original Double Score - 29 Tahnku Sanctuary 8-Bit Samples.mp3
|
||||||
12 Meriposa.mp3
|
12 8 Bit Weapon - Lawless Legends Original Double Score - 30 Mariposa City 8-Bit Samples.mp3
|
||||||
13 Freemont.mp3
|
13 8 Bit Weapon - Lawless Legends Original Double Score - 31 Freemont Estate 8-Bit Samples.mp3
|
||||||
14 Littlecreek.mp3
|
14 8 Bit Weapon - Lawless Legends Original Double Score - 32 Fort Littlecreek 8-Bit Samples.mp3
|
||||||
15 Grove.mp3
|
15 8 Bit Weapon - Lawless Legends Original Double Score - 33 Sacred Grove 8-Bit Samples.mp3
|
||||||
16 Poverty.mp3
|
16 8 Bit Weapon - Lawless Legends Original Double Score - 34 Poverty Flats 8-Bit Samples.mp3
|
||||||
17 Killed.mp3
|
17 8 Bit Weapon - Lawless Legends Original Double Score - 35 Killed in Cold Blood 8-Bit Samples.mp3
|
||||||
18 Wilderness.mp3
|
18 *8 Bit Weapon - Lawless Legends Original Double Score - 36 The Sierra Nevada Wilderness 8-Bit Samples.mp3
|
||||||
|
|
||||||
---- Chiptune version uses the blips and bleeps that are the voice of a generation
|
---- Chiptune version uses the blips and bleeps that are the voice of a generation
|
||||||
Chiptune
|
8-bit Chipmusic
|
||||||
1 Title8.mp3
|
1 8 Bit Weapon - Lawless Legends Original Double Score - 01 Lawless Legends 8-Bit C64.mp3
|
||||||
2 Miller8.mp3
|
2 8 Bit Weapon - Lawless Legends Original Double Score - 02 Fort Miller 8-Bit C64.mp3
|
||||||
3 Tragedy8.mp3
|
3 8 Bit Weapon - Lawless Legends Original Double Score - 03 Tragedy in the West 8-Bit C64.mp3
|
||||||
4 Victory8.mp3
|
4 8 Bit Weapon - Lawless Legends Original Double Score - 04 Victory! 8-Bit C64.mp3
|
||||||
5 Grub8.mp3
|
5 8 Bit Weapon - Lawless Legends Original Double Score - 05 Grub Gulch 8-Bit C64.mp3
|
||||||
6 Mines8.mp3
|
6 8 Bit Weapon - Lawless Legends Original Double Score - 06 Mines of Mystery 8-Bit C64.mp3
|
||||||
7 Texas8.mp3
|
7 8 Bit Weapon - Lawless Legends Original Double Score - 07 Texas Flats 8-Bit C64.mp3
|
||||||
8 Strange8.mp3
|
8 8 Bit Weapon - Lawless Legends Original Double Score - 08 Strange Tales 8-Bit C64.mp3
|
||||||
9 Oro8.mp3
|
9 8 Bit Weapon - Lawless Legends Original Double Score - 09 Oro's Villa 8-Bit C64.mp3
|
||||||
10 Village8.mp3
|
10 8 Bit Weapon - Lawless Legends Original Double Score - 10 Tahnku Village 8-Bit C64.mp3
|
||||||
11 Sanctuary8.mp3
|
11 8 Bit Weapon - Lawless Legends Original Double Score - 11 Tahnku Sanctuary 8-Bit C64.mp3
|
||||||
12 Mariposa8.mp3
|
12 8 Bit Weapon - Lawless Legends Original Double Score - 12 Mariposa 8-Bit C64.mp3
|
||||||
13 Freemont8.mp3
|
13 8 Bit Weapon - Lawless Legends Original Double Score - 13 Freemont Estate 8-Bit C64.mp3
|
||||||
14 Littlecreek8.mp3
|
14 8 Bit Weapon - Lawless Legends Original Double Score - 14 Fort Littlecreek 8-Bit C64.mp3
|
||||||
15 Grove8.mp3
|
15 8 Bit Weapon - Lawless Legends Original Double Score - 15 Sacred Grove 8-Bit C64.mp3
|
||||||
16 Poverty8.mp3
|
16 8 Bit Weapon - Lawless Legends Original Double Score - 16 Poverty Flats 8-Bit C64.mp3
|
||||||
17 Killed8.mp3
|
17 8 Bit Weapon - Lawless Legends Original Double Score - 17 Killed in Cold Blood 8-Bit C64.mp3
|
||||||
18 Wilderness8.mp3
|
18 *8 Bit Weapon - Lawless Legends Original Double Score - 18 The Sierra Nevada Wilderness 8-Bit C64.mp3
|
Loading…
Reference in New Issue
Block a user