You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
6.7 KiB
310 lines
6.7 KiB
package tables
|
|
|
|
import (
|
|
"fmt"
|
|
"mazeratsgen/internal/data"
|
|
"mazeratsgen/internal/dice"
|
|
"strings"
|
|
)
|
|
|
|
type MonsterTable struct {
|
|
Roller *dice.Roller
|
|
}
|
|
|
|
type MonsterStat struct {
|
|
Value int
|
|
Qualifier string
|
|
}
|
|
|
|
type MonsterStats struct {
|
|
Health MonsterStat
|
|
Attack MonsterStat
|
|
Armor MonsterStat
|
|
STR MonsterStat
|
|
DEX MonsterStat
|
|
WIL MonsterStat
|
|
}
|
|
|
|
type Monster struct {
|
|
Base string
|
|
Stats MonsterStats
|
|
Feature string
|
|
Trait string
|
|
Ability string
|
|
Tactics string
|
|
Personality string
|
|
Weakness string
|
|
Seed int64
|
|
}
|
|
|
|
func (t *MonsterTable) Generate() Monster {
|
|
baseRoll, _ := t.Roller.Roll("1d6")
|
|
return Monster{
|
|
Base: t.Base(baseRoll[0]),
|
|
Stats: t.genStats(),
|
|
Feature: t.Feature(t.Roller.TableRoll()),
|
|
Trait: t.Trait(t.Roller.TableRoll()),
|
|
Ability: t.Ability(t.Roller.TableRoll()),
|
|
Tactics: t.Tactic(t.Roller.TableRoll()),
|
|
Personality: t.Personality(t.Roller.TableRoll()),
|
|
Weakness: t.Weakness(t.Roller.TableRoll()),
|
|
Seed: t.Roller.Seed,
|
|
}
|
|
}
|
|
|
|
func (t *MonsterTable) Template() string {
|
|
return strings.TrimSpace(`
|
|
Type: {{.Trait}} {{.Base}}
|
|
Stats:
|
|
Health: {{.Stats.Health.Value}} ({{.Stats.Health.Qualifier}})
|
|
Armor: {{.Stats.Armor.Value}} ({{.Stats.Armor.Qualifier}})
|
|
Attack: +{{.Stats.Attack.Value}} ({{.Stats.Attack.Qualifier}})
|
|
STR: +{{.Stats.STR.Value}} ({{.Stats.STR.Qualifier}})
|
|
DEX: +{{.Stats.DEX.Value}} ({{.Stats.DEX.Qualifier}})
|
|
WIL: +{{.Stats.WIL.Value}} ({{.Stats.WIL.Qualifier}})
|
|
Feature: {{.Feature}}
|
|
Ability: {{.Ability}}
|
|
Tactics: {{.Tactics}}
|
|
Personality: {{.Personality}}
|
|
Weakness: {{.Weakness}}
|
|
Seed: {{.Seed}}
|
|
`)
|
|
}
|
|
|
|
func (t MonsterTable) Weakness(roll [2]int) string {
|
|
magicTable := MagicTable{Roller: t.Roller}
|
|
treasureTable := TreasureTable{Roller: t.Roller}
|
|
switch roll {
|
|
case [2]int{3, 5}:
|
|
return magicTable.Insanity(t.Roller.TableRoll())
|
|
case [2]int{4, 4}:
|
|
return "Pick an existing NPC"
|
|
case [2]int{4, 6}:
|
|
return magicTable.PhysicalElement(t.Roller.TableRoll())
|
|
case [2]int{6, 2}:
|
|
return treasureTable.ValuableMaterial(t.Roller.TableRoll())
|
|
case [2]int{6, 4}:
|
|
return treasureTable.WeaponItem(t.Roller.TableRoll())
|
|
default:
|
|
return data.Tables.Monster.Weakness[roll[0]-1][roll[1]-1]
|
|
}
|
|
}
|
|
|
|
func (t MonsterTable) genStats() MonsterStats {
|
|
return MonsterStats{
|
|
Health: t.genHealth(),
|
|
Attack: t.genAttack(),
|
|
Armor: t.genArmor(),
|
|
STR: t.genSTR(),
|
|
DEX: t.genDEX(),
|
|
WIL: t.genWIL(),
|
|
}
|
|
}
|
|
|
|
func (t MonsterTable) genHealth() MonsterStat {
|
|
typeRoll, _ := t.Roller.Roll("1d5")
|
|
mStat := MonsterStat{}
|
|
switch typeRoll[0] {
|
|
case 1:
|
|
mStat.Qualifier = "Weak"
|
|
case 2:
|
|
mStat.Qualifier = "Typical"
|
|
case 3:
|
|
mStat.Qualifier = "Tough"
|
|
case 4:
|
|
mStat.Qualifier = "Hulking"
|
|
case 5:
|
|
mStat.Qualifier = "Colossal"
|
|
}
|
|
|
|
hpRoll, _ := t.Roller.Roll(fmt.Sprintf("%vd6", typeRoll[0]))
|
|
hp := 0
|
|
for _, hpDie := range hpRoll {
|
|
hp += hpDie
|
|
}
|
|
mStat.Value = hp
|
|
return mStat
|
|
}
|
|
|
|
func (t MonsterTable) genArmor() MonsterStat {
|
|
typeRoll, _ := t.Roller.Roll("1d5")
|
|
mStat := MonsterStat{}
|
|
switch typeRoll[0] {
|
|
case 1:
|
|
mStat.Qualifier = "Unarmored"
|
|
mStat.Value = 6
|
|
case 2:
|
|
mStat.Qualifier = "Light protection"
|
|
mStat.Value = 7
|
|
case 3:
|
|
mStat.Qualifier = "Moderate protection"
|
|
mStat.Value = 8
|
|
case 4:
|
|
mStat.Qualifier = "Heavy protection"
|
|
mStat.Value = 9
|
|
case 5:
|
|
mStat.Value = 10
|
|
mStat.Qualifier = "Nigh impervious"
|
|
}
|
|
|
|
return mStat
|
|
}
|
|
|
|
func (t MonsterTable) genAttack() MonsterStat {
|
|
typeRoll, _ := t.Roller.Roll("1d5")
|
|
mStat := MonsterStat{}
|
|
switch typeRoll[0] {
|
|
case 1:
|
|
mStat.Qualifier = "Untrained"
|
|
mStat.Value = 0
|
|
case 2:
|
|
mStat.Qualifier = "Trained"
|
|
mStat.Value = 1
|
|
case 3:
|
|
mStat.Qualifier = "Dangerous"
|
|
mStat.Value = 2
|
|
case 4:
|
|
mStat.Qualifier = "Masterful"
|
|
mStat.Value = 3
|
|
case 5:
|
|
mStat.Value = 4
|
|
mStat.Qualifier = "Lethal"
|
|
}
|
|
|
|
return mStat
|
|
}
|
|
|
|
func (t MonsterTable) genSTR() MonsterStat {
|
|
typeRoll, _ := t.Roller.Roll("1d5")
|
|
mStat := MonsterStat{}
|
|
switch typeRoll[0] {
|
|
case 1:
|
|
mStat.Qualifier = "Weak"
|
|
mStat.Value = 0
|
|
case 2:
|
|
mStat.Qualifier = "Average"
|
|
mStat.Value = 1
|
|
case 3:
|
|
mStat.Qualifier = "Strong"
|
|
mStat.Value = 2
|
|
case 4:
|
|
mStat.Qualifier = "Powerful"
|
|
mStat.Value = 3
|
|
case 5:
|
|
mStat.Value = 4
|
|
mStat.Qualifier = "Monstrous"
|
|
}
|
|
|
|
return mStat
|
|
}
|
|
|
|
func (t MonsterTable) genDEX() MonsterStat {
|
|
typeRoll, _ := t.Roller.Roll("1d5")
|
|
mStat := MonsterStat{}
|
|
switch typeRoll[0] {
|
|
case 1:
|
|
mStat.Qualifier = "Slow"
|
|
mStat.Value = 0
|
|
case 2:
|
|
mStat.Qualifier = "Average"
|
|
mStat.Value = 1
|
|
case 3:
|
|
mStat.Qualifier = "Nimble"
|
|
mStat.Value = 2
|
|
case 4:
|
|
mStat.Qualifier = "Swift"
|
|
mStat.Value = 3
|
|
case 5:
|
|
mStat.Value = 4
|
|
mStat.Qualifier = "Blurred"
|
|
}
|
|
|
|
return mStat
|
|
}
|
|
|
|
func (t MonsterTable) genWIL() MonsterStat {
|
|
typeRoll, _ := t.Roller.Roll("1d5")
|
|
mStat := MonsterStat{}
|
|
switch typeRoll[0] {
|
|
case 1:
|
|
mStat.Qualifier = "Dimwitted"
|
|
mStat.Value = 0
|
|
case 2:
|
|
mStat.Qualifier = "Average"
|
|
mStat.Value = 1
|
|
case 3:
|
|
mStat.Qualifier = "Clever"
|
|
mStat.Value = 2
|
|
case 4:
|
|
mStat.Qualifier = "Brilliant"
|
|
mStat.Value = 3
|
|
case 5:
|
|
mStat.Value = 4
|
|
mStat.Qualifier = "Genius"
|
|
}
|
|
|
|
return mStat
|
|
}
|
|
|
|
func (t MonsterTable) Base(roll int) string {
|
|
var base string
|
|
|
|
switch roll {
|
|
case 1, 2:
|
|
base = t.AerialAnimals(t.Roller.TableRoll())
|
|
case 3, 4:
|
|
base = t.TerrestrialAnimals(t.Roller.TableRoll())
|
|
case 5, 6:
|
|
base = t.AquaticAnimals(t.Roller.TableRoll())
|
|
}
|
|
|
|
return base
|
|
}
|
|
|
|
func (t MonsterTable) AerialAnimals(roll [2]int) string {
|
|
return data.Tables.Monster.Aerial[roll[0]-1][roll[1]-1]
|
|
}
|
|
|
|
func (t MonsterTable) TerrestrialAnimals(roll [2]int) string {
|
|
return data.Tables.Monster.Terrestrial[roll[0]-1][roll[1]-1]
|
|
}
|
|
|
|
func (t MonsterTable) AquaticAnimals(roll [2]int) string {
|
|
return data.Tables.Monster.Aquatic[roll[0]-1][roll[1]-1]
|
|
}
|
|
|
|
func (t MonsterTable) Tactic(roll [2]int) string {
|
|
return data.Tables.Monster.Tactics[roll[0]-1][roll[1]-1]
|
|
}
|
|
|
|
func (t MonsterTable) Feature(roll [2]int) string {
|
|
return data.Tables.Monster.Features[roll[0]-1][roll[1]-1]
|
|
}
|
|
|
|
func (t MonsterTable) Personality(roll [2]int) string {
|
|
return data.Tables.Monster.Personality[roll[0]-1][roll[1]-1]
|
|
}
|
|
|
|
func (t MonsterTable) Ability(roll [2]int) string {
|
|
magicTable := MagicTable{Roller: t.Roller}
|
|
switch roll {
|
|
case [2]int{2, 4}:
|
|
return magicTable.EtherealElement(t.Roller.TableRoll())
|
|
case [2]int{4, 5}:
|
|
return magicTable.PhysicalElement(t.Roller.TableRoll())
|
|
default:
|
|
return data.Tables.Monster.Abilities[roll[0]-1][roll[1]-1]
|
|
}
|
|
}
|
|
|
|
func (t MonsterTable) Trait(roll [2]int) string {
|
|
magicTable := MagicTable{Roller: t.Roller}
|
|
switch roll {
|
|
case [2]int{2, 3}:
|
|
return magicTable.EtherealElement(t.Roller.TableRoll())
|
|
case [2]int{5, 1}:
|
|
return magicTable.PhysicalElement(t.Roller.TableRoll())
|
|
default:
|
|
return data.Tables.Monster.Traits[roll[0]-1][roll[1]-1]
|
|
}
|
|
}
|
|
|