Initial Commit

This commit is contained in:
Emma Nora Theuer 2024-09-07 19:28:38 +02:00
parent 0730a10628
commit 4346715f39
4 changed files with 214 additions and 0 deletions

46
TextGame/Concept.org Normal file
View file

@ -0,0 +1,46 @@
#+title: Concept
#+author: Emma Nora Ada Theuer
* !!!!!MOST OF THIS IS CURRENTLY STILL SUBJECT TO CHANGE!!!!!
* Storyline
** So essentially, I have absolutely no idea.
* Implementation Details
** Technical foundation
*** Software details
+ Java 17, will potentially try to maintain compatibility with Java 8.
+ Lanterna (Curses) based TUI interface.
+ org.json based settings to maintain player position in the story, as well as player data before it's loaded into memory.
+ Most other mechanics should be mostly implemented barebones, to aid as a learning project.
+ Auto-Saving after every battle and main story moment, as well as a save option in hubs
*** Players, Enemies and Combat
**** The Player
+ Players can choose a name, or choose to forego a name.
+ The Player has basic RPG stats. in this case, for now: Health, Strength and Dexterity, Attunement, Mana and luck.
+ There is a fundamental Level System, where the Player can increase individual stats by one point for every level they reach.
+ The level system is XP-Based. XP is mostly gained by combat. Pursuing a passion or profession also can give XP. Important story events should also have large XP rewards.
+ There will be an underlying Benevolence/Malevolence system, where points are increasing or decreasing based on specific actions the player takes. It should always be a number. Ranges <=-5 are Malevolent, [-4; 4] is neutral and >=5 is benevolent (/NUMBERS ARE SUBJECT TO CHANGE/)
+ Players should have basic battle abilities, such as Attacking with the main weapon, magic, using an item and running from the battle.
+ Players have an inventory. It stores Armor and weapons, as well as consumables, collectibles and key items
+ Playerdata is stored in a JSON file. This file stores every stat of the player, including XP and benevolence, as well as the last finished mission and a Tally of all optional missions and bosses and the Player's name, or, if they don't have one, that they don't. This is also where the player's inventory is located.
+ Players should be mostly a single class. The actions the player can take in battle are defined within that class and HP is that way also stored in memory and can easily be safed into the save.json. For that purpose, players can have a maximum HP value and a current HP value. Through special story events, shield spells and other actions, the player's current HP can sometimes exceed their maximum HP. This would be indicated as "temporary HP". A player will always have their current HP Value set to the Maximum HP value after sleeping in a hub.
+ The combat system is D20 based.
+ Player Damage is calculated like in D&D. All weapons deal a flat amount of bonus damage. A 20 is a crit and a 1 is a crit fail.
+ D&Ds Armor Class model is transferred to this game.
**** Enemies
+ All enemies use an ABC.
+ Enemies should always drop some kind of currency or crafting material as well as XP.
+ Most enemies should be reusable and have simple movesets, that can still be varied. Normal enemies should normally be fought alone.
+ Boss enemies are a lot stronger, have unique movesets and are usually fought with a companion. Bosses should drop very large amounts of XP and currency and potentially Key items.
**** Combat
+ Combat is essentially a while (true) loop, that checks if either creature is on 0 HP after a turn, and if so, breaks and then proceeds appropriately.
+ Combat order is decided on initiative rolls. Inititive is a D20 rolls + DEX + Other modifiers, if applicable.
+ Combat mostly proceeds like in D&D.
+ Spells don't have range restraints.
+ Spells either hit a set amount of targets, all enemies, all allies, oneself, or all creatures on the battlefield, except oneself.
+ Every Spell will have an ABC
+ All weapons will be based on an ABC that implements an interface.

View file

@ -0,0 +1,94 @@
import java.util.Map;
interface Weapon {
Dice dice = new Dice();
// Retrieve the to-hit-bonus every time
int getHitBonus(int bonus);
// get the damage Bonus every time
int getDamageBonus(int bonus);
// get the weapon's range every time
int getRange(int range);
// Have the weapon roll for damange every
default int rollToHit(int bonus) {
int diceResult = dice.rollD20();
switch (diceResult) {
case 1:
return 0;
case 20:
return 100;
default:
return diceResult + bonus;
}
}
// Have the weapon role for damage
int rollDamage(int bonus);
}
abstract class Sword implements Weapon {
Map<String, Integer> requirements;
String infoDamageBonus;
int playerStrength;
int playerDex;
String type = "Melee";
String name;
String rarity;
int range;
int hitBonus;
int damageBonus;
@Override
public int getRange(int range){
return range;
}
public int getRange() {
return getRange(5);
}
@Override
public int getHitBonus(int bonus) {
return bonus;
}
public int getHitBonus(){
return getHitBonus(0);
}
@Override
public int getDamageBonus(int bonus) {
return bonus;
}
public int getDamageBonus(){
return getHitBonus(0);
}
}
abstract class Bow implements Weapon {
Map<String, Integer> requirements;
String infoDamageBonus;
int playerStrength;
int playerDex;
String type = "Ranged";
String name;
String rarity;
int range;
int hitBonus;
int damageBonus;
@Override
public int getRange(int range){
return range;
}
public int getRange() {
return getRange(300);
}
@Override
public int getHitBonus(int bonus) {
return bonus;
}
public int getHitBonus(){
return getHitBonus(0);
}
@Override
public int getDamageBonus(int bonus) {
return bonus;
}
public int getDamageBonus(){
return getHitBonus(0);
}
}

View file

@ -0,0 +1,25 @@
import java.util.concurrent.ThreadLocalRandom;
class Dice {
int rollD4() {
return ThreadLocalRandom.current().nextInt(1, 5);
}
int rollD6() {
return ThreadLocalRandom.current().nextInt(1, 7);
}
int rollD8() {
return ThreadLocalRandom.current().nextInt(1, 9);
}
int rollD10() {
return ThreadLocalRandom.current().nextInt(1, 11);
}
int rollD12() {
return ThreadLocalRandom.current().nextInt(1, 13);
}
int rollD20() {
return ThreadLocalRandom.current().nextInt(1, 21);
}
int rollD100() {
return ThreadLocalRandom.current().nextInt(1, 101);
}
}

View file

@ -0,0 +1,49 @@
import java.util.HashMap;
class Longbow extends Bow {
public Longbow(int distance, int strength, int dex) {
requirements = new HashMap<>();
requirements.put("Dex", 14);
requirements.put("Str", 8);
playerStrength = strength;
playerDex = dex;
infoDamageBonus = "0-2";
name = "Longbow";
rarity = "Common";
range = getRange(500);
hitBonus = getHitBonus();
damageBonus = getDamageBonus(distance);
}
@Override
public int getDamageBonus(int distance) {
if (playerDex < requirements.get("Dex") || playerStrength < requirements.get("Str")) {
return -20;
}
if (distance > 20 && distance <= 165) {
return 2;
}
else if (distance > 165 && distance <= 300) {
return 1;
}
else {
return 0;
}
}
@Override
public int rollToHit(int bonus) {
return dice.rollD20();
}
@Override
public int rollDamage(int bonus) {
int dieResult = dice.rollD10();
if (dieResult + bonus < 0) {
return 0;
} else {
return dieResult + bonus;
}
}
}