Added more types, changed how items and stuff will work. Began work on audio and npcs.

This commit is contained in:
Raktbastr 2026-05-15 16:18:51 -05:00
parent 05a97e072a
commit 33957c55dc
28 changed files with 472 additions and 518 deletions

14
TODO.md Normal file
View file

@ -0,0 +1,14 @@
# TODO
- Barter system
- Ventor inventories
- Save/load system
- Achievements
- Combat
- NPCs
- Music/sfx
- Redo weapons and ids and stuff
- Strings to things and ids maybe not needed?
- Custom assets
- Installer
- Gameplay
- Graphics

View file

@ -1,5 +1,6 @@
plugins {
id("java")
id("io.freefair.lombok") version "9.5.0"
}
group = "net.halfheart"
@ -14,8 +15,20 @@ dependencies {
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("org.json:json:20231013")
compileOnly("org.projectlombok:lombok:1.18.46")
annotationProcessor("org.projectlombok:lombok:1.18.46")
testCompileOnly("org.projectlombok:lombok:1.18.46")
testAnnotationProcessor("org.projectlombok:lombok:1.18.46")
}
tasks.test {
useJUnitPlatform()
}
tasks.jar {
manifest {
attributes(
"Main-Class" to "net.halfheart.Main",
)
}
}

2
readme.md Normal file
View file

@ -0,0 +1,2 @@
# Fallout Lonesome Road
A fanmade Fallout game. Its really just an excuse for me to do Java right now. Hopefully its engine can be used in a different project of mine.

View file

@ -2,6 +2,6 @@ package net.halfheart;
public class Main {
public static void main(String[] args) {
System.out.print(System.getProperty("user.home"));
}
}

View file

@ -1,47 +0,0 @@
package net.halfheart.lonesomeroad;
import net.halfheart.ventricleengine.objects.*;
import net.halfheart.ventricleengine.WeaponsHandler;
import net.halfheart.ventricleengine.ArmorsHandler;
import net.halfheart.ventricleengine.AidModifierHandler;
import net.halfheart.ventricleengine.ItemsHandler;
import net.halfheart.ventricleengine.PlayerHandler;
public record ID() {
public static Weapon FISTS = WeaponsHandler.constructWeapon("Fists");
public static Weapon COMBATKNIFE = WeaponsHandler.constructWeapon("Combat Knife");
public static Weapon RIPPER = WeaponsHandler.constructWeapon("Ripper");
public static Weapon CHAINSAW = WeaponsHandler.constructWeapon("Chainsaw");
public static Weapon BASEBALLBAT = WeaponsHandler.constructWeapon("Baseball Bat");
public static Weapon POWERFIST = WeaponsHandler.constructWeapon("Power Fist");
public static Weapon SUPERSLEDGE = WeaponsHandler.constructWeapon("Super Sledge");
public static Weapon PISTOL10MM = WeaponsHandler.constructWeapon("10mm Pistol");
public static Weapon HUNTINGRIFLE = WeaponsHandler.constructWeapon("Hunting Rifle");
public static Armor NOTHING = ArmorsHandler.constructArmor("Nothing");
public static Armor LEATHERARMOR = ArmorsHandler.constructArmor("Leather Armor");
public static Armor STURDYLEATHERARMOR = ArmorsHandler.constructArmor("Sturdy Leather Armor");
public static Armor RAIDERARMOR = ArmorsHandler.constructArmor("Raider Armor");
public static Armor METALARMOR = ArmorsHandler.constructArmor("Metal Armor");
public static Armor COMBATARMOR = ArmorsHandler.constructArmor("Combat Armor");
public static Armor CENTURIONARMOR = ArmorsHandler.constructArmor("Centurion Armor");
public static Armor NCRRANGERARMOR = ArmorsHandler.constructArmor("NCR Ranger Armor");
public static Armor T45POWERARMOR = ArmorsHandler.constructArmor("T-45 Power Armor");
public static Armor T60POWERARMOR = ArmorsHandler.constructArmor("T-60 Power Armor");
public static Armor T65POWERARMOR = ArmorsHandler.constructArmor("T-65 Power Armor");
public static Armor X01POWERARMOR = ArmorsHandler.constructArmor("X-01 Power Armor");
public static Armor APAMKIORPOWERARMOR = ArmorsHandler.constructArmor("APA MkI Power Armor");
public static Armor APAMKIIPOWERARMOR = ArmorsHandler.constructArmor("APA MkII Power Armor");
public static Armor RAIDERPOWERARMOR = ArmorsHandler.constructArmor("Raider Power Armor");
public static Armor ULTRACITEPOWERARMOR = ArmorsHandler.constructArmor("Ultracite Power Armor");
public static Armor T51POWERARMOR = ArmorsHandler.constructArmor("T-51 Power Armor");
public static Armor ENCLAVEUNIFORM = ArmorsHandler.constructArmor("Enclave Uniform");
public static Armor EXCAVATORPOWERARMOR = ArmorsHandler.constructArmor("Excavator Power Armor");
public static Player PLAYER = PlayerHandler.constructPlayer("none");
public static Item STIMPAK = ItemsHandler.constructItem("Stimpak");
public static AidModifier STIMPAK_M = AidModifierHandler.constructAidModifier("Stimpak");
}

View file

@ -1,6 +1,6 @@
package net.halfheart.ventricleengine;
import net.halfheart.ventricleengine.objects.AidModifier;
import net.halfheart.lonesomeroad.ID;
import net.halfheart.ventricleengine.objects.Player;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
@ -42,28 +42,14 @@ public class AidModifierHandler {
}
}
// Applies requested aid modifier to player
public static void applyAid(AidModifier modifier) {
if (modifier.stat.equals("hp")) {
char action = modifier.mod.charAt(0);
Player player = GameSpace.getInstance().getPlayer();
if (modifier.getStat().equals("hp")) {
char action = modifier.getMod().charAt(0);
switch (action) {
case '+' -> ID.PLAYER.hp = (short) (ID.PLAYER.hp + modifier.value);
case '+' -> player.setHp((short) (player.getHp() + modifier.getValue()));
}
}
}
// Removes requested aid modifier from player
public static void removeAid(AidModifier modifier) {
if (modifier.name.equals("Stimpak")) {
System.out.println("Invalid Operation: Tried to remove Stimpak modifier from player");
}
}
// Returns aidModifier from String of name
public static AidModifier findAid(String aidModifierName) {
return switch (aidModifierName) {
case "Stimpak" -> ID.STIMPAK_M;
default -> null;
};
}
}

View file

@ -1,7 +1,8 @@
package net.halfheart.ventricleengine;
import net.halfheart.ventricleengine.objects.Armor;
import net.halfheart.lonesomeroad.ID;
import org.json.*;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
@ -14,67 +15,42 @@ import java.util.Objects;
import java.util.stream.Collectors;
public class ArmorsHandler {
// Creates Armor object by parsing JSON
public static Armor constructArmor(String armorName) {
String filename = "/armors.json";
try (InputStream inputStream = WeaponsHandler.class.getResourceAsStream(filename)) {
String jsonText = new BufferedReader(
new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8))
.lines()
.collect(Collectors.joining("\n"));
try (InputStream inputStream = ItemsHandler.class.getResourceAsStream(filename); BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8))) {
String jsonText = reader.lines().collect(Collectors.joining("\n"));
JSONArray jsonArray = new JSONArray(jsonText);
JSONObject wantedItem = null;
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
if (item.opt("name").toString().equals(armorName)) {
wantedItem = item;
}
}
assert wantedItem != null;
JSONObject resistances = wantedItem.getJSONObject("resistances");
String name = wantedItem.opt("name").toString();
String description = wantedItem.opt("desc").toString();
String armorType = wantedItem.opt("type").toString();
String resUnit = wantedItem.opt("unit").toString();
List<Byte> resList = new ArrayList<>();
for (String key : resistances.keySet()) {
byte res = (byte) resistances.opt(key);
resList.add(res);
if (wantedItem == null) return null;
String name = wantedItem.getString("name");
String description = wantedItem.getString("description");
byte weight = (byte) wantedItem.getInt("weight");
short cost = (short) wantedItem.getInt("cost");
String type = wantedItem.getString("type");
String resUnit = wantedItem.getString("resUnit");
JSONArray resArray = wantedItem.getJSONArray("resistances");
List<Byte> resistances = new ArrayList<>();
for (int i = 0; i < resArray.length(); i++) {
resistances.add((byte) resArray.getInt(i));
}
byte weight = (byte) wantedItem.opt("weight");
short cost = (short) wantedItem.opt("cost");
return new Armor(name, description, armorType, resList, resUnit, cost, weight);
return new Armor(name, description, weight, cost, type, resistances, resUnit);
} catch (IOException e) {
throw new RuntimeException(e);
throw new RuntimeException("Could not load armor data", e);
}
}
// Returns Armor from String of name
public static Armor findArmor(String armorName) {
return switch (armorName) {
case "Nothing" -> ID.NOTHING;
case "Leather Armor" -> ID.LEATHERARMOR;
case "Sturdy Leather Armor" -> ID.STURDYLEATHERARMOR;
case "Raider Armor" -> ID.RAIDERARMOR;
case "Metal Armor" -> ID.METALARMOR;
case "Combat Armor" -> ID.COMBATARMOR;
case "Centurion Armor" -> ID.CENTURIONARMOR;
case "NCR Ranger Armor" -> ID.NCRRANGERARMOR;
case "T-45 Power Armor" -> ID.T45POWERARMOR;
case "T-60 Power Armor" -> ID.T60POWERARMOR;
case "T-65 Power Armor" -> ID.T65POWERARMOR;
case "X-01 Power Armor" -> ID.X01POWERARMOR;
case "APA MkI Power Armor" -> ID.APAMKIORPOWERARMOR;
case "APA MkII Power Armor" -> ID.APAMKIIPOWERARMOR;
case "Raider Power Armor" -> ID.RAIDERPOWERARMOR;
case "Ultracite Power Armor" -> ID.ULTRACITEPOWERARMOR;
case "T-51 Power Armor" -> ID.T51POWERARMOR;
case "Enclave Uniform" -> ID.ENCLAVEUNIFORM;
case "Excavator Power Armor" -> ID.EXCAVATORPOWERARMOR;
default -> null;
};
}
}

View file

@ -0,0 +1,52 @@
package net.halfheart.ventricleengine;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class AudioPlayer {
Long currentFrame;
Clip clip;
String status;
AudioInputStream audioInputStream;
static String fileName;
public AudioPlayer() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
audioInputStream = AudioSystem.getAudioInputStream(new File(System.getProperty("user.home")+"/.lonesomeroad/tracks/"+fileName).getAbsoluteFile());
clip = AudioSystem.getClip();
clip.open(audioInputStream);
}
public void play() {
clip.start();
status = "play";
}
public void pause() {
if (status.equals("paused"))
{
return;
}
this.currentFrame = this.clip.getMicrosecondPosition();
clip.stop();
status = "paused";
}
public void resume() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
if (status.equals("play")) {
return;
}
clip.close();
resetAudioStream();
clip.setMicrosecondPosition(currentFrame);
this.play();
}
public void resetAudioStream() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
audioInputStream = AudioSystem.getAudioInputStream(new File(System.getProperty("user.home")+"/.lonesomeroad/tracks/"+fileName).getAbsoluteFile());
clip.open(audioInputStream);
}
}

View file

@ -0,0 +1,19 @@
package net.halfheart.ventricleengine;
import net.halfheart.ventricleengine.objects.Player;
import lombok.Getter;
@Getter
public class GameSpace {
private static GameSpace instance;
public Player player;
public GameSpace() {
instance = this;
this.player = PlayerHandler.constructPlayer(null);
}
public static GameSpace getInstance() {
return instance;
}
}

View file

@ -1,10 +1,5 @@
package net.halfheart.ventricleengine;
import net.halfheart.lonesomeroad.ID;
import net.halfheart.ventricleengine.objects.Item;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@ -13,43 +8,44 @@ import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.stream.Collectors;
import org.json.JSONArray;
import org.json.JSONObject;
import net.halfheart.ventricleengine.objects.Consumable;
import net.halfheart.ventricleengine.objects.Item;
import net.halfheart.ventricleengine.objects.MiscItem;
public class ItemsHandler {
// Creates Item by parsing JSON
public static Item constructItem(String itemName) {
String filename = "/items.json";
try (InputStream inputStream = WeaponsHandler.class.getResourceAsStream(filename)) {
String jsonText = new BufferedReader(
new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8))
.lines()
.collect(Collectors.joining("\n"));
try (InputStream inputStream = ItemsHandler.class.getResourceAsStream(filename); BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8))) {
String jsonText = reader.lines().collect(Collectors.joining("\n"));
JSONArray jsonArray = new JSONArray(jsonText);
JSONObject wantedItem = null;
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
if (item.opt("name").toString().equals(itemName)) {
if (item.getString("name").equals(itemName)) {
wantedItem = item;
}
}
assert wantedItem != null;
String name = wantedItem.opt("name").toString();
String description = wantedItem.opt("desc").toString();
byte weight = (byte) wantedItem.opt("weight");
short cost = (short) wantedItem.opt("cost");
boolean consumable = (boolean) wantedItem.opt("consumable");
String aidModifier = wantedItem.opt("aidModifier").toString();
return new Item(name, description, weight, cost, consumable, aidModifier);
} catch (IOException e) {
throw new RuntimeException(e);
break;
}
}
// Returns Item from String of name
public static Item findItem(String itemName) {
return switch (itemName) {
case "Stimpak" -> ID.STIMPAK;
default -> null;
};
if (wantedItem == null) return null;
String name = wantedItem.getString("name");
String description = wantedItem.getString("desc");
byte weight = (byte) wantedItem.getInt("weight");
short cost = (short) wantedItem.getInt("cost");
if (wantedItem.optBoolean("consumable", false)) {
return new Consumable(name, description, weight, cost, wantedItem.getString("aidModifier"));
}
return new MiscItem(name, description, weight, cost);
} catch (IOException e) {
throw new RuntimeException("Failed to load items library", e);
}
}
}

View file

@ -1,138 +1,98 @@
package net.halfheart.ventricleengine;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import net.halfheart.ventricleengine.objects.*;
import org.json.*;
public class PlayerHandler {
// Creates Player object by parsing JSON
public static Player constructPlayer(String savePath) {
// "none" Used for creating a blank Player for character creation
if (savePath.equals("none")) {
String name = "No Player Loaded!";
byte strength = 0;
byte perception = 0;
byte endurance = 0;
byte charisma = 0;
byte intelligence = 0;
byte agility = 0;
byte luck = 0;
short caps = 0;
short pwMoney = 0;
short hpCap = 0;
short hp = 0;
short food = 0;
boolean isRadiated = false;
byte radPoints = 0;
int xp = 0;
short level = 0;
List<Weapon> weaponList = new ArrayList<>();
List<Armor> armorList = new ArrayList<>();
List<Item> itemList = new ArrayList<>();
List<AidModifier> aidList = new ArrayList<>();
return new Player(
name,
strength,
perception,
endurance,
charisma,
intelligence,
agility,
luck,
caps,
pwMoney,
hpCap,
hp,
food,
isRadiated,
radPoints,
xp,
level,
weaponList,
armorList,
itemList,
aidList
);
} else {
public static Player constructPlayer(String savePath) {
if (savePath == null) {
return createDefaultPlayer();
}
try {
String content = new String(Files.readAllBytes(Paths.get(savePath)));
JSONObject saveData = new JSONObject(content);
String name = saveData.opt("name").toString();
byte strength = (byte) saveData.opt("strength");
byte perception = (byte) saveData.opt("perception");
byte endurance = (byte) saveData.opt("endurance");
byte charisma = (byte) saveData.opt("charisma");
byte intelligence = (byte) saveData.opt("intelligence");
byte agility = (byte) saveData.opt("agility");
byte luck = (byte) saveData.opt("luck");
short caps = (short) saveData.opt("caps");
short pwMoney = (short) saveData.opt("pwMoney");
short hpCap = (short) saveData.opt("hpCap");
short hp = (short) saveData.opt("hp");
short food = (short) saveData.opt("food");
boolean isRadiated = (boolean) saveData.opt("isRadiated");
byte radPoints = (byte) saveData.opt("radPoints");
int xp = (int) saveData.opt("xp");
short level = (short) saveData.opt("level");
String name = saveData.getString("name");
byte strength = (byte) saveData.getInt("strength");
byte perception = (byte) saveData.getInt("perception");
byte endurance = (byte) saveData.getInt("endurance");
byte charisma = (byte) saveData.getInt("charisma");
byte intelligence = (byte) saveData.getInt("intelligence");
byte agility = (byte) saveData.getInt("agility");
byte luck = (byte) saveData.getInt("luck");
short caps = (short) saveData.getInt("caps");
short pwMoney = (short) saveData.getInt("pwMoney");
short hpCap = (short) saveData.getInt("hpCap");
short hp = (short) saveData.getInt("hp");
boolean isRadiated = saveData.getBoolean("isRadiated");
byte radPoints = (byte) saveData.getInt("radPoints");
int xp = saveData.getInt("xp");
short level = (short) saveData.getInt("level");
// 2. Build the Consolidated Inventory
List<Item> inventory = new ArrayList<>();
JSONObject weapons = saveData.getJSONObject("weapons");
JSONObject armors = saveData.getJSONObject("armors");
JSONObject items = saveData.getJSONObject("items");
JSONObject aidModifiers = saveData.getJSONObject("aidModifiers");
List<Weapon> weaponList = new ArrayList<>();
for (String key : weapons.keySet()) {
weaponList.add(WeaponsHandler.findWeapon(weapons.opt(key).toString()));
inventory.add(WeaponsHandler.constructWeapon(weapons.getString(key)));
}
List<Armor> armorList = new ArrayList<>();
JSONObject armors = saveData.getJSONObject("armors");
for (String key : armors.keySet()) {
armorList.add(ArmorsHandler.findArmor(armors.opt(key).toString()));
inventory.add(ArmorsHandler.constructArmor(armors.getString(key)));
}
List<Item> itemList = new ArrayList<>();
JSONObject items = saveData.getJSONObject("items");
for (String key : items.keySet()) {
itemList.add(ItemsHandler.findItem(items.opt(key).toString()));
inventory.add(ItemsHandler.constructItem(items.getString(key)));
}
// 3. Aid Modifiers
List<AidModifier> aidModifierList = new ArrayList<>();
JSONObject aidModifiers = saveData.getJSONObject("aidModifiers");
for (String key : aidModifiers.keySet()) {
aidModifierList.add(AidModifierHandler.findAid(items.opt(key).toString()));
aidModifierList.add(AidModifierHandler.constructAidModifier(aidModifiers.getString(key)));
}
Weapon equippedWeapon = WeaponsHandler.constructWeapon(saveData.getString("equippedWeapon"));
Armor equippedArmor = ArmorsHandler.constructArmor(saveData.getString("equippedArmor"));
return new Player(
name,
strength,
perception,
endurance,
charisma,
intelligence,
agility,
luck,
caps,
pwMoney,
hpCap,
hp,
food,
isRadiated,
radPoints,
xp,
level,
weaponList,
armorList,
itemList,
aidModifierList
name, strength, perception, endurance, charisma, intelligence, agility, luck,
caps, pwMoney, hpCap, hp, isRadiated, radPoints, xp, level,
inventory, aidModifierList, equippedWeapon, equippedArmor
);
} catch (FileNotFoundException e) {
System.out.println("Save file not found at path: "+savePath);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
System.err.println("Save file not found at path: " + savePath);
return null;
} catch (IOException e) {
throw new RuntimeException("Error reading save file", e);
}
}
private static Player createDefaultPlayer() {
List<Item> initialInventory = new ArrayList<>();
Weapon fists = WeaponsHandler.constructWeapon("Fists");
Armor skin = ArmorsHandler.constructArmor("Skin");
initialInventory.add(fists);
initialInventory.add(skin);
return new Player(
"No Player Loaded!", (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0,
(short)0, (short)0, (short)0, (short)0, false, (byte)0, 0, (short)0,
initialInventory, new ArrayList<>(), fists, skin
);
}
}

View file

@ -1,8 +1,8 @@
package net.halfheart.ventricleengine;
import net.halfheart.lonesomeroad.ID;
import net.halfheart.ventricleengine.objects.Weapon;
import org.json.*;
import net.halfheart.ventricleengine.objects.Weapon;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@ -12,65 +12,36 @@ import java.util.Objects;
import java.util.stream.Collectors;
public class WeaponsHandler {
// Creates Weapon object by parsing JSON
public static Weapon constructWeapon(String weaponName) {
String filename = "/weapons.json";
try (InputStream inputStream = WeaponsHandler.class.getResourceAsStream(filename)) {
String jsonText = new BufferedReader(
new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8))
.lines()
.collect(Collectors.joining("\n"));
try (InputStream inputStream = ItemsHandler.class.getResourceAsStream(filename); BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8))) {
String jsonText = reader.lines().collect(Collectors.joining("\n"));
JSONArray jsonArray = new JSONArray(jsonText);
JSONObject wantedItem = null;
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
if (item.opt("name").toString().equals(weaponName)) {
if (item.getString("name").equals(weaponName)) {
wantedItem = item;
break;
}
}
assert wantedItem != null;
String name = wantedItem.opt("name").toString();
String description = wantedItem.opt("desc").toString();
String dmgType = wantedItem.opt("type").toString();
String ammoType = wantedItem.opt("ammo").toString();
short damage = (short) wantedItem.opt("dmg");
short cost = (short) wantedItem.opt("cost");
byte weight = (byte) wantedItem.opt("weight");
return new Weapon(name, description, dmgType, ammoType, damage, cost, weight);
if (wantedItem == null) return null;
return new Weapon(
wantedItem.getString("name"),
wantedItem.getString("description"),
(byte) wantedItem.getInt("weight"),
(short) wantedItem.getInt("cost"),
wantedItem.getString("dmgType"),
wantedItem.getString("ammoType"),
(short) wantedItem.getInt("damage")
);
} catch (IOException e) {
throw new RuntimeException(e);
throw new RuntimeException("Failed to load weapons library", e);
}
}
// Finds Weapon from String of name
public static Weapon findWeapon(String weaponName) {
return switch (weaponName) {
case "Fists" -> ID.FISTS;
case "Combat Knife" -> ID.COMBATKNIFE;
case "Ripper" -> ID.RIPPER;
case "Chainsaw" -> ID.CHAINSAW;
case "Baseball Bat" -> ID.BASEBALLBAT;
case "Power Fist" -> ID.POWERFIST;
case "Super Sledge" -> ID.SUPERSLEDGE;
case "10mm Pistol" -> ID.PISTOL10MM;
case "Hunting Rifle" -> ID.HUNTINGRIFLE;
default -> null;
};
}
public static void fistCalc() {
switch (ID.PLAYER.strength){
case 0 -> {
ID.FISTS.description = ID.FISTS.description+"please don't.";
ID.FISTS.damage = -2;
}
case (1|2|3|4) -> ID.FISTS.description = ID.FISTS.description+"a last resort.";
case (5|6|7|8) -> ID.FISTS.description = ID.FISTS.description+"use cautiously.";
case (9|10) -> ID.FISTS.description = ID.FISTS.description+"a formidable weapon.";
}
}
}

View file

@ -0,0 +1,12 @@
package net.halfheart.ventricleengine;
import net.halfheart.ventricleengine.AudioPlayer;
public class Jukebox {
// Remember
// Music types:
// theme: game theme, credits theme, location theme, boss
// amb: ambience
// combat: combat tracks
// sfx: sound effects
}

View file

@ -1,17 +1,13 @@
package net.halfheart.ventricleengine.objects;
import lombok.Getter;
import lombok.AllArgsConstructor;
// AidModifiers are used to break down the JSON data into Java-readable components.
@Getter
@AllArgsConstructor
public class AidModifier {
public String name; // Name of the effect, seen in game
public String stat; // Stat that the modifier affects
public String mod; // Operation that the modifier is doing to the stat (e.g. * for multiplying)
public short value; // Value that the operation uses (e.g. 25 for +25 hp)
public AidModifier(String name, String stat, String mod, short value) {
this.name = name;
this.stat = stat;
this.mod = mod;
this.value = value;
}
private String name;
private String stat;
private String mod;
private short value;
}

View file

@ -1,32 +1,18 @@
package net.halfheart.ventricleengine.objects;
import lombok.Getter;
import java.util.List;
// Armor is used to represent each armor as a Java object with values
public class Armor {
public String name; // Name of the armor, seen in game
public String description; // Description seen in pip-boy
public String type; // Armor type, either skin, uarmor, armor, or parmor
public List<Byte> resistances; // A list of resistance byte values for each damage type
public String resUnit; // Unit the resistances use, either dt or dr for damage threshold and damage resistance
public short cost; // Buy/Sell price
public byte weight; // Weight of item in inventory
@Getter
public class Armor extends Item {
private String type;
private List<Byte> resistances;
private String resUnit;
public Armor(
String name,
String description,
String type,
List<Byte> resistances,
String resUnit,
short cost,
byte weight
)
{
this.name = name;
this.description = description;
public Armor(String name, String description, byte weight, short cost, String type, List<Byte> resistances, String resUnit) {
super(name, description, weight, cost);
this.type = type;
this.resistances = resistances;
this.resUnit = resUnit;
this.cost = cost;
this.weight = weight;
}
}

View file

@ -0,0 +1,18 @@
package net.halfheart.ventricleengine.objects;
import lombok.Getter;
@Getter
public class Consumable extends Item {
private String aidModifier;
public Consumable(
String name,
String description,
byte weight,
short cost,
String aidModifier
) {
super(name, description, weight, cost);
this.aidModifier = aidModifier;
}
}

View file

@ -1,28 +1,13 @@
package net.halfheart.ventricleengine.objects;
// Item is used to represent each armor as a Java object with values
public class Item {
public String name; // Name of item, seen in game
public String description; // Description seen in pip-boy
public byte weight; // Weight of item in inventory
public short cost; // Buy/Sell value of item
public boolean consumable; // Whether the item can be consumed
public String aidModifier; // Aid modifier that the item applies when consumed
import lombok.Getter;
import lombok.AllArgsConstructor;
public Item(
String name,
String description,
byte weight,
short cost,
boolean consumable,
String aidModifier
){
this.name = name;
this.description = description;
this.weight = weight;
this.cost = cost;
this.consumable = consumable;
this.aidModifier = aidModifier;
}
@Getter
@AllArgsConstructor
public abstract class Item {
private String name;
private String description;
private byte weight;
private short cost;
}

View file

@ -0,0 +1,7 @@
package net.halfheart.ventricleengine.objects;
public class MiscItem extends Item {
public MiscItem(String name, String description, byte weight, short cost) {
super(name, description, weight, cost); //
}
}

View file

@ -0,0 +1,24 @@
package net.halfheart.ventricleengine.objects;
import lombok.Getter;
import lombok.Setter;
import lombok.AllArgsConstructor;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
public class NPC {
private String name;
private String race;
private byte strength, perception, endurance, charisma, intelligence, agility, luck;
private short caps, pwMoney;
private short hpCap, hp;
private List<Item> inventory;
private List<AidModifier> aidModifiers;
private Weapon equippedWeapon;
private Armor equippedArmor;
private boolean canBarter;
}

View file

@ -1,82 +1,33 @@
package net.halfheart.ventricleengine.objects;
import lombok.Getter;
import lombok.Setter;
import lombok.AllArgsConstructor;
import java.util.List;
// Player is used to represent the save data values as a Java object
@Getter
@Setter
@AllArgsConstructor
public class Player {
public String name; // Name of player
// Next 7 lines: S.P.E.C.I.A.L. values of player
public byte strength;
public byte perception;
public byte endurance;
public byte charisma;
public byte intelligence;
public byte agility;
public byte luck;
private String name;
private byte strength, perception, endurance, charisma, intelligence, agility, luck;
private short caps, pwMoney;
private short hpCap, hp;
private boolean isRadiated;
private byte radPoints;
private int xp;
private short level;
public short caps; // Caps the player has, used for vendors
public short pwMoney; // Pre-War Money the player has, used in Enclave vendors
private List<Item> inventory;
private List<AidModifier> aidModifiers;
public short hpCap; // Player health point cap
public short hp; // Current player health
private Weapon equippedWeapon;
private Armor equippedArmor;
public short food; // Food the player has, eaten each walk cycle
public boolean isRadiated; // Whether the player is irradiated
// TODO: Decide function of radPoints
public byte radPoints; // Rad points player has
public int xp; // Current player xp
public short level; // Current level of player
public List<Weapon> weapons; // Weapons that the player has in inventory
public List<Armor> armors; // Armors that the player has in inventory
public List<Item> items; // Items that the player has in inventory
public List<AidModifier> aidModifiers; // Modifiers currently affecting player
public Player(
String name,
byte strength,
byte perception,
byte endurance,
byte charisma,
byte intelligence,
byte agility,
byte luck,
short caps,
short pwMoney,
short hpCap,
short hp,
short food,
boolean isRadiated,
byte radPoints,
int xp,
short level,
List<Weapon> weapons,
List<Armor> armors,
List<Item> items,
List<AidModifier> aidModifiers
)
{
this.name = name;
this.strength = strength;
this.perception = perception;
this.endurance = endurance;
this.charisma = charisma;
this.intelligence = intelligence;
this.agility = agility;
this.luck = luck;
this.caps = caps;
this.pwMoney = pwMoney;
this.hpCap = hpCap;
this.hp = hp;
this.food = food;
this.isRadiated = isRadiated;
this.radPoints = radPoints;
this.xp = xp;
this.level = level;
this.weapons = weapons;
this.armors = armors;
this.items = items;
this.aidModifiers = aidModifiers;
// Manual setter to override Lombok's default and enforce the HP Cap
public void setHp(short hp) {
if (hp > this.hpCap) this.hp = this.hpCap;
else if (hp < 0) this.hp = 0;
else this.hp = hp;
}
}

View file

@ -1,31 +1,17 @@
package net.halfheart.ventricleengine.objects;
// Weapon is used to represent each weapon as a Java object with values
public class Weapon {
public String name; // Name of weapon, seen in game
public String description; // Description of weapon, seen in pip-boy
public String dmgType; // Type of damage the weapon deals. Laser, Bash, Slash. etc.
public String ammoType; // Ammo the weapon uses. "none" for melee weapons
public short damage; // Damage the weapon deals
public short cost; // Buy/Sell value of weapon
public byte weight; // Weight of weapon in inventory
import lombok.Getter;
public Weapon(
String name,
String description,
String dmgType,
String ammoType,
short damage,
short cost,
byte weight
)
{
this.name = name;
this.description = description;
@Getter
public class Weapon extends Item {
private String dmgType;
private String ammoType;
private short damage;
public Weapon(String name, String description, byte weight, short cost, String dmgType, String ammoType, short damage) {
super(name, description, weight, cost);
this.dmgType = dmgType;
this.ammoType = ammoType;
this.damage = damage;
this.cost = cost;
this.weight = weight;
}
}

View file

View file

@ -1,6 +1,6 @@
[
{
"name": "Nothing",
"name": "Skin",
"desc": "Luckily you have skin, that's enough right?",
"type": "skin",
"resistances": {
@ -12,7 +12,8 @@
},
"unit": "dr",
"weight": 0,
"cost": -1
"cost": 0,
"immutable": true
},
{
"name": "Leather Armor",
@ -25,7 +26,8 @@
"plasma": 3},
"unit": "dr",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "Sturdy Leather Armor",
"desc": "A set of combat armor, better protection from laser and plasma weapons.",
@ -38,7 +40,8 @@
},
"unit": "dr",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "Raider Armor",
"desc": "A set of raider armor, good protection from ballistic damage.",
@ -51,7 +54,8 @@
},
"unit": "dr",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "Metal Armor" ,
"desc": "A set of raider armor, better protection from ballistic and slash damage.",
@ -64,7 +68,8 @@
},
"unit": "dr",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "Combat Armor",
"desc": "A set of combat armor, better protection from all damage types.",
@ -77,7 +82,8 @@
},
"unit": "dr",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "Centurion Armor",
"desc": "A set of Centurion armor, great protection from ballistic damage.",
@ -90,7 +96,8 @@
},
"unit": "dr",
"cost": 25,
"weight": 25
"weight": 25,
"immutable": false
},
{"name": "NCR Ranger Armor" ,
"desc": "A set of NCR Ranger armor, great protection from laser and plasma weapons",
@ -103,7 +110,8 @@
},
"unit": "dr",
"cost": 30,
"weight": 30
"weight": 30,
"immutable": false
},
{"name": "T-45 Power Armor",
"desc": "A set of T-45 Power Armor, protects against all damage types.",
@ -116,7 +124,8 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "T-60 Power Armor",
"desc": "A set of T-60 Power Armor, good protection from all damage types.",
@ -129,7 +138,9 @@
},
"unit": "dt",
"cost": 5,
"weight": 5}
"weight": 5,
"immutable": false
}
,
{"name": "T-65 Power Armor",
"desc": "A set of T-60 Power Armor, great protection from all damage types.",
@ -142,7 +153,8 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "X-01 Power Armor",
"desc": "X-01 Power Armor, good protection from energy damage.",
@ -155,7 +167,8 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "APA MkI Power Armor",
"desc": "APA MkI Power Armor, great protection from energy damage.",
@ -168,7 +181,8 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "APA MkII Power Armor",
"desc": "APA MkII Power Armor, excellent protection from energy damage.",
@ -181,7 +195,8 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "Raider Power Armor",
"desc": "Raider Power Armor, good protection from ballistic damage.",
@ -194,7 +209,8 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "Ultracite Power Armor",
"desc": "Ultracite Power Armor, great protection from ballistic damage.",
@ -207,7 +223,8 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "T-51 Power Armor",
"desc": "T-51 Power Armor, excellent protection from ballistic damage.",
@ -220,7 +237,8 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
},
{"name": "Enclave Uniform",
"desc": "Enclave uniform, standard issue",
@ -233,7 +251,8 @@
},
"unit": "dr",
"cost": 20,
"weight": 20
"weight": 20,
"immutable": false
},
{"name": "Excavator Power Armor",
"desc": "Excavator Power Armor, +25% Chance to find extra loot",
@ -246,6 +265,7 @@
},
"unit": "dt",
"cost": 5,
"weight": 5
"weight": 5,
"immutable": false
}
]

View file

@ -0,0 +1,9 @@
[
{
"RRC": {
"weapons" : [
]
}
}
]

View file

@ -5,6 +5,7 @@
"weight": 0,
"cost": 0,
"consumable": true,
"aidModifier": "food"
"aidModifier": "food",
"immutable": false
}
]

View file

@ -0,0 +1,8 @@
[
{
"title": "Main Title",
"filename": "maintitle.wav",
"type": "theme",
"area": "meta"
}
]

View file

@ -5,8 +5,9 @@
"type": "bash",
"ammo": "none",
"dmg": 2,
"cost": -1,
"weight": 0
"cost": 0,
"weight": 0,
"immutable": true
},
{
"name": "Combat Knife",
@ -15,7 +16,8 @@
"ammo": "none",
"dmg": 5,
"cost": 5,
"weight": 1
"weight": 1,
"immutable": false
},
{
"name": "Ripper",
@ -24,7 +26,8 @@
"ammo": "none",
"dmg": 5,
"cost": 5,
"weight": 1
"weight": 1,
"immutable": false
},
{
"name": "Chainsaw",
@ -33,7 +36,8 @@
"ammo": "none",
"dmg": 5,
"cost": 5,
"weight": 1
"weight": 1,
"immutable": false
},
{
"name": "Baseball Bat",
@ -42,7 +46,8 @@
"ammo": "none",
"dmg": 5,
"cost": 5,
"weight": 1
"weight": 1,
"immutable": false
},
{
"name": "Power Fist",
@ -51,7 +56,8 @@
"ammo": "none",
"dmg": 15,
"cost": 10,
"weight": 2
"weight": 2,
"immutable": false
},
{
"name": "Super Sledge",
@ -60,7 +66,8 @@
"ammo": "none",
"dmg": 30,
"cost": 10,
"weight": 15
"weight": 15,
"immutable": false
},
{
"name": "10mm Pistol",
@ -69,7 +76,8 @@
"ammo": "10",
"dmg": 10,
"cost": 10,
"weight": 2
"weight": 2,
"immutable": false
},
{
"name": "Hunting Rifle",
@ -78,6 +86,7 @@
"ammo": "308",
"dmg": 10,
"cost": 10,
"weight": 2
"weight": 2,
"immutable": false
}
]