add treasure system
This commit is contained in:
325
src/services/treasureData.ts
Normal file
325
src/services/treasureData.ts
Normal file
@ -0,0 +1,325 @@
|
||||
import { IndividualTreasureTable, HoardTresureTable } from './treasureService';
|
||||
|
||||
let individualTreasureData: IndividualTreasureTable[] = [
|
||||
{
|
||||
name: 'Individual Treasure: Challence 0-4',
|
||||
notes: '',
|
||||
tags: ['Individual Treasure', 'CR0','CR1','CR2', 'CR3', 'CR4', 'Challenge 0-4', 'treasure'],
|
||||
dice: [100],
|
||||
possibleCoinRewards: [
|
||||
{
|
||||
keys: [1,30],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'CP',
|
||||
rollCount: 5,
|
||||
diceType: 6,
|
||||
multiplier: 1,
|
||||
avg: 17
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [31,60],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'SP',
|
||||
rollCount: 4,
|
||||
diceType: 6,
|
||||
multiplier: 1,
|
||||
avg: 14
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [61,70],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'EP',
|
||||
rollCount: 3,
|
||||
diceType: 6,
|
||||
multiplier: 1,
|
||||
avg: 10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [71,95],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 3,
|
||||
diceType: 6,
|
||||
multiplier: 1,
|
||||
avg: 10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [96,100],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'PP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 1,
|
||||
avg: 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Individual Treasure: Challence 5-10',
|
||||
notes: '',
|
||||
tags: ['Individual Treasure', 'CR5','CR6','CR7', 'CR8', 'CR9', 'CR10', 'Challenge 5-10', 'treasure'],
|
||||
dice: [100],
|
||||
possibleCoinRewards: [
|
||||
{
|
||||
keys: [1,30],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'CP',
|
||||
rollCount: 4,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 1400
|
||||
},
|
||||
{
|
||||
type: 'EP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 35
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [31,60],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'SP',
|
||||
rollCount: 6,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 210
|
||||
},
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 70
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [61,70],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'EP',
|
||||
rollCount: 3,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 105
|
||||
},
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 70
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [71,95],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 4,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 140
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [96,100],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 70
|
||||
},
|
||||
{
|
||||
type: 'PP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 1,
|
||||
avg: 10
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Individual Treasure: Challence 11-16',
|
||||
notes: '',
|
||||
tags: ['Individual Treasure', 'CR11', 'CR12', 'CR13', 'CR14', 'CR15', 'CR16', 'Challenge 11-16', 'treasure'],
|
||||
dice: [100],
|
||||
possibleCoinRewards: [
|
||||
{
|
||||
keys: [1,20],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'SP',
|
||||
rollCount: 4,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 1400
|
||||
},
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 350
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [21,35],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'EP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 350
|
||||
},
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 350
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [36,75],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 700
|
||||
},
|
||||
{
|
||||
type: 'PP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 35
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [76,100],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 700
|
||||
},
|
||||
{
|
||||
type: 'EP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 10,
|
||||
avg: 70
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Individual Treasure: Challence 17+',
|
||||
notes: '',
|
||||
tags: ['Individual Treasure', 'CR17', 'CR18', 'CR19', 'CR20', 'CR21', 'CR22', 'Challenge 17+', 'treasure'],
|
||||
dice: [100],
|
||||
possibleCoinRewards: [
|
||||
{
|
||||
keys: [1,15],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'EP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 1000,
|
||||
avg: 7000
|
||||
},
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 8,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 2800
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [16,55],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 1000,
|
||||
avg: 3500
|
||||
},
|
||||
{
|
||||
type: 'PP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 350
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
keys: [56,100],
|
||||
coinCalc: [
|
||||
{
|
||||
type: 'GP',
|
||||
rollCount: 1,
|
||||
diceType: 6,
|
||||
multiplier: 1000,
|
||||
avg: 3500
|
||||
},
|
||||
{
|
||||
type: 'PP',
|
||||
rollCount: 2,
|
||||
diceType: 6,
|
||||
multiplier: 100,
|
||||
avg: 700
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
let hoardTreasureData: HoardTresureTable[] = [
|
||||
|
||||
];
|
||||
|
||||
export {
|
||||
individualTreasureData
|
||||
}
|
194
src/services/treasureService.ts
Normal file
194
src/services/treasureService.ts
Normal file
@ -0,0 +1,194 @@
|
||||
import { d } from './dice';
|
||||
import { individualTreasureData } from './treasureData';
|
||||
|
||||
class TreasureService {
|
||||
private individualRewardsTables: RandomIndividualTreasureTable[] = [];
|
||||
private tableByName: {[tableName: string]: RandomIndividualTreasureTable} = {};
|
||||
private tablesByTags: {[tagName: string]: RandomIndividualTreasureTable[]} = {};
|
||||
private tags: Set<string> = new Set();
|
||||
|
||||
constructor() {
|
||||
console.time('TreasureServiceStartup');
|
||||
for (let i in individualTreasureData) {
|
||||
let table = individualTreasureData[i];
|
||||
let randomTable: RandomIndividualTreasureTable = new RandomIndividualTreasureTable(table);
|
||||
this.individualRewardsTables.push(randomTable);
|
||||
this.tableByName[table.name] = randomTable;
|
||||
if (table.tags) {
|
||||
for (let j in table.tags) {
|
||||
let tag: string = table.tags[j];
|
||||
if (!this.tablesByTags[tag]) {
|
||||
this.tablesByTags[tag] = [];
|
||||
}
|
||||
this.tags.add(tag);
|
||||
this.tablesByTags[tag].push(randomTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
console.timeEnd('TreasureServiceStartup');
|
||||
}
|
||||
|
||||
public getTablesWithTag(tag: string) {
|
||||
return this.tablesByTags[tag];
|
||||
}
|
||||
|
||||
public getTable(name: string) {
|
||||
return this.tableByName[name];
|
||||
}
|
||||
|
||||
public getTags() {
|
||||
return this.tags;
|
||||
}
|
||||
|
||||
public searchForTable(search: string) {
|
||||
let answer = this.individualRewardsTables.filter((table: RandomIndividualTreasureTable) => {
|
||||
return table.name.toLowerCase().indexOf(search.toLowerCase()) !== -1 || table.getTags().join(' ').toLowerCase().indexOf(search.toLowerCase()) !== -1;
|
||||
}).map((table: RandomIndividualTreasureTable) => {
|
||||
let score = search.length / table.name.length;
|
||||
return {
|
||||
table: table,
|
||||
score: score
|
||||
};
|
||||
}).sort((a: {table: RandomIndividualTreasureTable, score: number}, b: {table: RandomIndividualTreasureTable, score: number}) => {
|
||||
return a.score - b.score;
|
||||
}).map((tableScore: {table: RandomIndividualTreasureTable, score: number}) => {
|
||||
return tableScore.table;
|
||||
});
|
||||
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
class RandomIndividualTreasureTable {
|
||||
public name: string;
|
||||
public dice: number[];
|
||||
private indexedResults: CoinRewards[] = [];
|
||||
private config: IndividualTreasureTable;
|
||||
|
||||
constructor(config: IndividualTreasureTable) {
|
||||
this.name = config.name;
|
||||
this.dice = config.dice;
|
||||
this.constructIndex(config.possibleCoinRewards);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public roll(input?: number) {
|
||||
let testRoll: number = this.getRoll();
|
||||
if (!this.isValidInput(testRoll)) {
|
||||
console.log(testRoll);
|
||||
debugger;
|
||||
}
|
||||
if (!input || !this.isValidInput(input)) {
|
||||
input = this.getRoll();
|
||||
}
|
||||
return this.indexedResults[input - 1];
|
||||
}
|
||||
|
||||
public getPossibleRewards() {
|
||||
return this.config.possibleCoinRewards;
|
||||
}
|
||||
|
||||
public getTags() {
|
||||
return this.config.tags || [];
|
||||
}
|
||||
|
||||
public getNotes() {
|
||||
return this.config.notes;
|
||||
}
|
||||
|
||||
private getRoll(): number {
|
||||
let answer: number = 0;
|
||||
for (let i in this.dice) {
|
||||
answer = answer + d(this.dice[i]);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
private isValidInput(input: number) {
|
||||
return typeof this.indexedResults[input - 1] !== 'undefined';
|
||||
}
|
||||
|
||||
private constructIndex(coinRewards: CoinRewards[]) {
|
||||
for (let resultIndex in coinRewards) {
|
||||
let keys: number[] = coinRewards[resultIndex].keys;
|
||||
for (let r = Math.min(...keys); r <= Math.max(...keys); r++) {
|
||||
this.indexedResults.push(coinRewards[resultIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ChallengeRating = '0-4' | '5-10' | '11-16' | '17+';
|
||||
|
||||
interface CoinResult {
|
||||
type: 'CP' | 'SP' | 'EP' | 'GP' | 'PP';
|
||||
count: number;
|
||||
}
|
||||
|
||||
interface CoinCalc {
|
||||
type: 'CP' | 'SP' | 'EP' | 'GP' | 'PP';
|
||||
rollCount: number;
|
||||
diceType: number;
|
||||
multiplier: number;
|
||||
avg: number;
|
||||
}
|
||||
|
||||
interface CoinRewards {
|
||||
keys: number[];
|
||||
coinCalc: CoinCalc[];
|
||||
}
|
||||
|
||||
interface GemArtCalc {
|
||||
tableName: string;
|
||||
rollCount: number;
|
||||
diceType: number;
|
||||
avg: number;
|
||||
}
|
||||
|
||||
interface GemArtResult {
|
||||
tableName: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
interface MagicItemCalc {
|
||||
tableName: string;
|
||||
rollCount: number;
|
||||
diceType: number;
|
||||
}
|
||||
|
||||
interface MagicItemResult {
|
||||
tableName: string;
|
||||
numberOfRoles: number;
|
||||
}
|
||||
|
||||
interface OtherRewards {
|
||||
keys: number[];
|
||||
gemArt: GemArtCalc;
|
||||
magicItem: MagicItemCalc[];
|
||||
}
|
||||
|
||||
interface IndividualTreasureTable {
|
||||
name: string;
|
||||
notes?: string;
|
||||
tags?: string[];
|
||||
dice: number[];
|
||||
possibleCoinRewards: CoinRewards[];
|
||||
}
|
||||
|
||||
interface HoardTresureTable {
|
||||
name: string;
|
||||
notes?: string;
|
||||
tags?: string[];
|
||||
dice: number[];
|
||||
coinRewards: CoinRewards;
|
||||
possibleRewards: OtherRewards[]
|
||||
}
|
||||
|
||||
const treasureService: TreasureService = new TreasureService();
|
||||
|
||||
export {
|
||||
HoardTresureTable,
|
||||
IndividualTreasureTable,
|
||||
RandomIndividualTreasureTable,
|
||||
treasureService,
|
||||
}
|
Reference in New Issue
Block a user