commit
924b605f6e
68 changed files with 9476 additions and 0 deletions
@ -0,0 +1 @@ |
||||
build/* |
@ -0,0 +1,21 @@ |
||||
FROM golang:alpine AS builder |
||||
|
||||
RUN apk add --no-cache make |
||||
|
||||
WORKDIR $GOPATH/src/ |
||||
COPY . . |
||||
|
||||
RUN make build |
||||
|
||||
RUN mkdir -p /dist |
||||
RUN cp -R build/dist/ /dist |
||||
|
||||
FROM alpine |
||||
|
||||
COPY --from=builder /dist/* /mazerats/ |
||||
|
||||
EXPOSE 8080 |
||||
|
||||
WORKDIR /mazerats |
||||
|
||||
CMD ["./mrg", "server"] |
@ -0,0 +1,16 @@ |
||||
ifndef $(GOPATH) |
||||
GOPATH=$(shell go env GOPATH)
|
||||
export GOPATH
|
||||
endif |
||||
|
||||
build: install_prerequisites bindata |
||||
$(GOPATH)/bin/swag init -o web/swagger
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./build/dist/mrg
|
||||
$(shell cp -r web ./build/dist/)
|
||||
|
||||
bindata: install_prerequisites |
||||
$(GOPATH)/bin/go-bindata -pkg bindata -o assets/bindata/bindata.go -prefix internal/data internal/data web
|
||||
|
||||
install_prerequisites: |
||||
go get -u github.com/swaggo/swag/cmd/swag
|
||||
go get -u github.com/go-bindata/go-bindata/...
|
@ -0,0 +1,21 @@ |
||||
# Maze Rats Generator |
||||
|
||||
Use this to generate Maze Rats things (see `mrg -h`). |
||||
|
||||
You can also run `mrg server` to create a web server with a REST API. |
||||
|
||||
Docs can be viewed at [http://localhost:8080](http://localhost:8080). |
||||
|
||||
## Building |
||||
|
||||
Run `make build` then copy `build/dist/` to where you want to execute. |
||||
|
||||
## Docker |
||||
|
||||
``` |
||||
docker build . -t yourorigin/mazerats:latest |
||||
|
||||
docker run --rm -it \ |
||||
-p 8080:8080 |
||||
- |
||||
|
@ -0,0 +1,10 @@ |
||||
Things I'd like to do/fix: |
||||
- `go get -u github.com/swaggo/swag/cmd/swag` in Docker |
||||
- Search for "existing" in returned table text and replace with generated things |
||||
- NOTE: Faction may be easiest |
||||
- Replace 1d6 rolls with helper |
||||
- Get rid of helpers.go |
||||
- Cross-platform shell in Makefile |
||||
- Figure out how to distribute web/ in binaryfile |
||||
- Add PORT env var/flag (super easy) |
||||
- Generate truly unique list of items (handle impossible requests, expensive computation) |
File diff suppressed because one or more lines are too long
@ -0,0 +1,118 @@ |
||||
package cmd |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/spf13/cobra" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/tables" |
||||
"time" |
||||
) |
||||
|
||||
var generateCmd = &cobra.Command{ |
||||
Use: "generate", |
||||
Short: "Generate various things", |
||||
} |
||||
|
||||
var generateNameCmd = &cobra.Command{ |
||||
Use: "name", |
||||
Short: "Generate a name", |
||||
Run: func(cmd *cobra.Command, args []string) { |
||||
n := tables.GenRandomName(flagSeed) |
||||
template := "{{.FullName}}" |
||||
output, err := buildOutput(n, template, flagFormat) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
fmt.Printf(output) |
||||
}, |
||||
} |
||||
|
||||
var generateCharCmd = &cobra.Command{ |
||||
Use: "character", |
||||
Short: "Generate a playable character", |
||||
Run: func(cmd *cobra.Command, args []string) { |
||||
t := tables.CharacterTable{Roller: dice.NewRoller(flagSeed)} |
||||
i := t.Generate() |
||||
template := t.Template() |
||||
output, err := buildOutput(i, template, flagFormat) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
fmt.Printf(output) |
||||
}, |
||||
} |
||||
|
||||
var generateMonsterCmd = &cobra.Command{ |
||||
Use: "monster", |
||||
Short: "Generate a monster", |
||||
Run: func(cmd *cobra.Command, args []string) { |
||||
t := tables.MonsterTable{Roller: dice.NewRoller(flagSeed)} |
||||
i := t.Generate() |
||||
template := t.Template() |
||||
output, err := buildOutput(i, template, flagFormat) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
fmt.Printf(output) |
||||
}, |
||||
} |
||||
|
||||
var generateCityCmd = &cobra.Command{ |
||||
Use: "city", |
||||
Short: "Generate a city", |
||||
Run: func(cmd *cobra.Command, args []string) { |
||||
t := tables.CityTable{Roller: dice.NewRoller(flagSeed)} |
||||
i := t.Generate() |
||||
template := t.Template() |
||||
output, err := buildOutput(i, template, flagFormat) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
fmt.Printf(output) |
||||
}, |
||||
} |
||||
|
||||
var generateSpellCmd = &cobra.Command{ |
||||
Use: "spell", |
||||
Short: "Generate a spell", |
||||
Run: func(cmd *cobra.Command, args []string) { |
||||
t := tables.MagicTable{Roller: dice.NewRoller(flagSeed)} |
||||
i := t.Generate() |
||||
template := t.Template() |
||||
output, err := buildOutput(i, template, flagFormat) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
fmt.Printf(output) |
||||
}, |
||||
} |
||||
|
||||
func buildOutput(i interface{}, template string, format string) (string, error) { |
||||
var output interface{} |
||||
var err error |
||||
if format == "json" { |
||||
output, err = tables.ConvertToJSON(i) |
||||
} else { |
||||
output, err = tables.ConvertToText(i, template) |
||||
} |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
return fmt.Sprintf("%s\n", output), nil |
||||
} |
||||
|
||||
var flagFormat string |
||||
var flagSeed int64 |
||||
|
||||
func init() { |
||||
rootCmd.AddCommand(generateCmd) |
||||
|
||||
generateCmd.PersistentFlags().StringVarP(&flagFormat, "format", "f", "text", `output format: "text", "json"`) |
||||
generateCmd.PersistentFlags().Int64VarP(&flagSeed, "seed", "s", time.Now().UnixNano(), "seed for randomness") |
||||
|
||||
generateCmd.AddCommand(generateCharCmd) |
||||
generateCmd.AddCommand(generateCityCmd) |
||||
generateCmd.AddCommand(generateMonsterCmd) |
||||
generateCmd.AddCommand(generateNameCmd) |
||||
generateCmd.AddCommand(generateSpellCmd) |
||||
} |
@ -0,0 +1,21 @@ |
||||
package cmd |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/spf13/cobra" |
||||
"os" |
||||
) |
||||
|
||||
var rootCmd = &cobra.Command{ |
||||
Use: "mrg [command]", |
||||
Short: "Generate Maze Rats things", |
||||
} |
||||
|
||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||
func Execute() { |
||||
if err := rootCmd.Execute(); err != nil { |
||||
fmt.Println(err) |
||||
os.Exit(1) |
||||
} |
||||
} |
@ -0,0 +1,61 @@ |
||||
package cmd |
||||
|
||||
import ( |
||||
"github.com/gorilla/mux" |
||||
"github.com/spf13/cobra" |
||||
"github.com/throttled/throttled" |
||||
"github.com/throttled/throttled/store/memstore" |
||||
"log" |
||||
"mazeratsgen/internal/handlers" |
||||
"net/http" |
||||
) |
||||
|
||||
var serverCmd = &cobra.Command{ |
||||
Use: "server", |
||||
Short: "Create a web server with REST API", |
||||
Run: startServer, |
||||
} |
||||
|
||||
func init() { |
||||
rootCmd.AddCommand(serverCmd) |
||||
} |
||||
|
||||
func startServer(cmd *cobra.Command, args []string) { |
||||
r := mux.NewRouter() |
||||
handlers.LoadHandlers(r) |
||||
|
||||
r.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("web/swagger")))) |
||||
|
||||
r.Use(loggingMiddleware) |
||||
log.Printf("Starting web server on 0.0.0.0:8080") |
||||
|
||||
store, err := memstore.New(65536) |
||||
if err != nil { |
||||
log.Fatal(err) |
||||
} |
||||
|
||||
// Maximum burst of 30 which refills at 5 tokens per minute.
|
||||
quota := throttled.RateQuota{MaxRate: throttled.PerMin(30), MaxBurst: 5} |
||||
|
||||
rateLimiter, err := throttled.NewGCRARateLimiter(store, quota) |
||||
if err != nil { |
||||
log.Fatal(err) |
||||
} |
||||
|
||||
httpRateLimiter := throttled.HTTPRateLimiter{ |
||||
RateLimiter: rateLimiter, |
||||
VaryBy: &throttled.VaryBy{Path: true}, |
||||
} |
||||
|
||||
log.Fatal(http.ListenAndServe(":8080", httpRateLimiter.RateLimit(r))) |
||||
} |
||||
|
||||
func loggingMiddleware(next http.Handler) http.Handler { |
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
||||
log.Printf( |
||||
"%s %s %s %s", |
||||
r.RemoteAddr, r.Method, r.URL, r.Header["User-Agent"], |
||||
) |
||||
next.ServeHTTP(w, r) |
||||
}) |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,544 @@ |
||||
<head> |
||||
<style> |
||||
ul { |
||||
list-style-type: none; |
||||
padding-left: 1em; |
||||
} |
||||
</style> |
||||
<script> |
||||
window.onload = function() { |
||||
function preventExpansion(elements) { |
||||
var fn = function(e) { |
||||
console.log(e.keyCode); |
||||
if(e.keyCode == 32){ |
||||
document.execCommand('insertHTML', false, ' '); |
||||
e.preventDefault(); |
||||
} |
||||
}; |
||||
|
||||
for (i = 0; i < elements.length; i++) { |
||||
elements[i].onkeyup = fn; |
||||
} |
||||
} |
||||
|
||||
preventExpansion(document.getElementsByTagName("SUMMARY")); |
||||
}; |
||||
</script> |
||||
</head> |
||||
|
||||
<body contenteditable="true"> |
||||
<!-- Cities --> |
||||
<details> |
||||
<summary>Cities</summary> |
||||
<ul> |
||||
<li> |
||||
{{- range .Cities}} |
||||
<details> |
||||
<summary>NAME_HERE: {{ .Theme }}</summary> |
||||
|
||||
<ul> |
||||
<li> |
||||
<details> |
||||
<summary>Events</summary> |
||||
<ul> |
||||
{{range $x := .Events }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>District Themes</summary> |
||||
<ul> |
||||
{{- range $x := .DistrictThemes }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Upper Class Buildings</summary> |
||||
<ul> |
||||
{{- range $x := .UpperClassBuildings }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Lower Class Buildings</summary> |
||||
<ul> |
||||
{{- range $x := .LowerClassBuildings }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Activities</summary> |
||||
<ul> |
||||
{{- range $x := .Activities }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Tactical Street Features</summary> |
||||
<ul> |
||||
{{- range $x := .TacticalStreetFeatures }}<li>{{ $x }}</li>{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Tactical Building Features</summary> |
||||
<ul> |
||||
{{- range $x := .TacticalBuildingFeatures }}<li>{{ $x }}</li>{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Factions</summary> |
||||
<ul> |
||||
{{- range $x := .Factions }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Faction Traits</summary> |
||||
<ul> |
||||
{{- range $x := .FactionTraits }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Faction Goals</summary> |
||||
<ul> |
||||
{{- range $x := .FactionGoals }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
{{- end }} |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
<!-- END Cities --> |
||||
|
||||
<!-- Wilds --> |
||||
<details> |
||||
<summary>Wilds</summary> |
||||
<ul> |
||||
<li> |
||||
{{- range .Wilds}} |
||||
<details> |
||||
<summary>{{ .Region }} with {{ .Landmark }}</summary> |
||||
<ul></li> |
||||
<p>Region: {{.Region}}</p> |
||||
<p>Landmark: {{.Landmark}}</p> |
||||
<p>Trait: {{.Trait}}</p> |
||||
<details> |
||||
<summary>Structures</summary> |
||||
<ul> |
||||
{{range $x := .Structures }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Discoveries</summary> |
||||
<ul> |
||||
{{range $x := .Discoveries }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Activities</summary> |
||||
<ul> |
||||
{{range $x := .Activities }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Wilderness Hazards</summary> |
||||
<ul> |
||||
{{range $x := .Hazards }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Edible Plants</summary> |
||||
<ul> |
||||
{{range $x := .EdiblePlants }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Poisonous Plants</summary> |
||||
<ul> |
||||
{{range $x := .PoisonousPlants }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Inns</summary> |
||||
<ul> |
||||
{{range $inn := .Inns }} |
||||
<li>{{ $inn.Name }} ({{ $inn.Quirk}})</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<ul></li> |
||||
</details> |
||||
{{- end }} |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
<!-- END Wilds --> |
||||
|
||||
<!-- Dungeons --> |
||||
<details> |
||||
<summary>Dungeons</summary> |
||||
<ul> |
||||
<li> |
||||
{{- range .Dungeons}} |
||||
<details> |
||||
<summary>{{ .Form }}</summary> |
||||
<ul></li> |
||||
<p>Entrance: {{.Entrance}}</p> |
||||
<p>Layout: {{.Layout}}</p> |
||||
<p>Ruination: {{.Ruination}}</p> |
||||
<p>Reward: {{.Reward}}</p> |
||||
<details> |
||||
<summary>Activities</summary> |
||||
<ul> |
||||
{{range $x := .Activities }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Rooms</summary> |
||||
<ul> |
||||
{{range $x := .Rooms }} |
||||
<li>{{ $x.Type }} - {{ $x.Detail }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Tricks</summary> |
||||
<ul> |
||||
{{range $x := .Tricks }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Hazards</summary> |
||||
<ul> |
||||
{{range $x := .Hazards }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Trap Effects</summary> |
||||
<ul> |
||||
{{range $x := .TrapEffects }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<details> |
||||
<summary>Trap Triggers</summary> |
||||
<ul> |
||||
{{range $x := .TrapTriggers }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
<ul> |
||||
</details> |
||||
<ul></li> |
||||
</details> |
||||
{{- end }} |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
<!-- END Dungeons --> |
||||
|
||||
<!-- Treasures --> |
||||
<details> |
||||
<summary>Treasures</summary> |
||||
<ul> |
||||
<li> |
||||
<details> |
||||
<summary>Misc Items</summary> |
||||
<ul><li> |
||||
{{- range $x := .Treasures.MiscItems }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
<details> |
||||
<summary>Worn Items</summary> |
||||
<ul><li> |
||||
{{- range $x := .Treasures.WornItems }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
<details> |
||||
<summary>Weapons</summary> |
||||
<ul><li> |
||||
{{- range $x := .Treasures.Weapons }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
<details> |
||||
<summary>Books</summary> |
||||
<ul><li> |
||||
{{- range $x := .Treasures.Books }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
<details> |
||||
<summary>Tools</summary> |
||||
<ul><li> |
||||
{{- range $x := .Treasures.Tools }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
<details> |
||||
<summary>Valuable Materials</summary> |
||||
<ul><li> |
||||
{{- range $x := .Treasures.ValuableMaterials }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
<details> |
||||
<summary>Magical Ingredients</summary> |
||||
<ul><li> |
||||
{{- range $x := .Treasures.MagicalIngredients }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
<details> |
||||
<summary>Treasures</summary> |
||||
<ul><li> |
||||
{{- range $x := .Treasures.Treasures }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
<details> |
||||
<summary>Potions</summary> |
||||
<ul><li> |
||||
{{- range $potion := .Treasures.Potions }} |
||||
<details> |
||||
<summary>Potion of {{ $potion.Effect }}</summary> |
||||
<ul><li> |
||||
<p>On Failure: {{ $potion.OnFailure }}</p> |
||||
<details> |
||||
<summary>Ingredients</summary> |
||||
<ul> |
||||
{{- range $x := $potion.Ingredients }} |
||||
<li>{{ $x }}</i> |
||||
{{- end }} |
||||
</ul> |
||||
</details> |
||||
</li></ul> |
||||
</details> |
||||
{{- end }} |
||||
</li></ul> |
||||
</details> |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
<!-- END Treasures --> |
||||
|
||||
<!-- Characters --> |
||||
<details> |
||||
<summary>Characters</summary> |
||||
<ul> |
||||
<li> |
||||
{{- range .Characters}} |
||||
<details> |
||||
<summary>{{ .Name }}</summary> |
||||
<ul> |
||||
<li> |
||||
<p>STR: +{{.STR}} DEX: +{{.DEX}} WIL: +{{.WIL}}</p> |
||||
<p>Max Health: {{.MaxHealth}}</p> |
||||
<p>Armor: 6 (plus Armor and/or Shield)</p> |
||||
<p>Feature: {{.Feature}}</p> |
||||
<p>Appearance: {{.Appearance}}</p> |
||||
<p>Physical Detail: {{.PhysicalDetail}}</p> |
||||
<p>Background: {{.Background}}</p> |
||||
<p>Clothing: {{.Clothing}}</p> |
||||
<p>Personality: {{.Personality}}</p> |
||||
<p>Mannerism: {{.Mannerism}}</p> |
||||
<p>Equipment:</p> |
||||
<ul> |
||||
{{- range $x := .Items }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
</ul> |
||||
<p>Combat Items</p> |
||||
<ul> |
||||
{{- range $x := .Weapons }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
</ul> |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
{{- end}} |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
<!-- END Characters --> |
||||
|
||||
<!-- NPCs --> |
||||
<details> |
||||
<summary>NPCs</summary> |
||||
<ul> |
||||
<li> |
||||
{{- range .NPCs}} |
||||
<details> |
||||
<summary>{{ .Name }}</summary> |
||||
<ul> |
||||
<li> |
||||
<p>Occupation: {{ .Occupation }}</p> |
||||
<p>Gender: {{ .Gender }}</p> |
||||
<p>Class: {{ .Class }}</p> |
||||
<p>Appearance: {{ .Appearance }}</p> |
||||
<p>Physical Detail: {{ .PhysicalDetail }}</p> |
||||
<p>Clothing: {{ .Clothing }}</p> |
||||
<p>Personality: {{ .Personality }}</p> |
||||
<p>Mannerism: {{ .Mannerism }}</p> |
||||
<p>Secret: {{ .Secret }}</p> |
||||
<p>Reputation: {{ .Reputation }}</p> |
||||
<p>Relationship: {{ .Relationship }}</p> |
||||
<p>Hobby: {{ .Hobby }}</p> |
||||
<p>Divine Domain: {{ .DivineDomain }}</p> |
||||
<p>After The Party: {{ .AfterTheParty }}</p> |
||||
<p>Relationship: {{ .Relationship }}</p> |
||||
<p>Assets:</p> |
||||
<ul> |
||||
{{- range $x := .Assets }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
</ul> |
||||
<p>Liabilities:</p> |
||||
<ul> |
||||
{{- range $x := .Liabilities }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
</ul> |
||||
<p>Goals:</p> |
||||
<ul> |
||||
{{- range $x := .Goals }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
</ul> |
||||
<p>Misfortunes:</p> |
||||
<ul> |
||||
{{- range $x := .Misfortunes }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
</ul> |
||||
<p>Missions:</p> |
||||
<ul> |
||||
{{- range $x := .Missions }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
</ul> |
||||
<p>Methods:</p> |
||||
<ul> |
||||
{{- range $x := .Methods }} |
||||
<li>{{ $x }}</li> |
||||
{{- end }} |
||||
</ul> |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
{{- end}} |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
<!-- END NPCs --> |
||||
|
||||
<!-- Magic --> |
||||
<details> |
||||
<summary>Magic</summary> |
||||
<ul> |
||||
<li> |
||||
<details> |
||||
<summary>Mutations</summary> |
||||
<ul> |
||||
{{- range $mutation := .MagicInfo.Mutations }} |
||||
<li> |
||||
{{ $mutation }} |
||||
</li> |
||||
{{- end }} |
||||
</ul> |
||||
</details> |
||||
<details> |
||||
<summary>Insanities</summary> |
||||
<ul> |
||||
{{- range $insanity := .MagicInfo.Insanities }} |
||||
<li> |
||||
{{ $insanity }} |
||||
</li> |
||||
{{- end }} |
||||
</ul> |
||||
</details> |
||||
<details> |
||||
<summary>Catastrophes</summary> |
||||
<ul> |
||||
{{- range $catastrophe := .MagicInfo.Catastrophes }} |
||||
<li> |
||||
{{ $catastrophe }} |
||||
</li> |
||||
{{- end }} |
||||
</ul> |
||||
</details> |
||||
</li> |
||||
</ul> |
||||
</details> |
||||
<!-- END Magic --> |
||||
|
||||
<!-- Monsters --> |
||||
<details> |
||||
<summary>Monsters</summary> |
||||
{{- range $monster := .Monsters }} |
||||
<ul> |
||||
<details> |
||||
<summary>{{ $monster.Trait }} {{ $monster.Base }} with {{ $monster.Feature }}</summary> |
||||
<li> |
||||
<ul> |
||||
<li> |
||||
<p>Base: {{ $monster.Base }}</p> |
||||
<p>Feature: {{ $monster.Feature }}</p> |
||||
<p>Trait: {{ $monster.Trait }}</p> |
||||
<p>Ability: {{ $monster.Ability }}</p> |
||||
<p>Tactics: {{ $monster.Tactics }}</p> |
||||
<p>Personality: {{ $monster.Personality }}</p> |
||||
<p>Weakness: {{ $monster.Weakness }}</p> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
</details> |
||||
</ul> |
||||
{{- end }} |
||||
</ul> |
||||
</details> |
||||
<!-- END Monsters --> |
||||
</body> |
||||
|
@ -0,0 +1,116 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"math/rand" |
||||
"mazeratsgen/internal/helpers" |
||||
"mazeratsgen/internal/tables" |
||||
"os" |
||||
"text/template" |
||||
"time" |
||||
) |
||||
|
||||
type MagicInfo struct { |
||||
Mutations []string |
||||
Insanities []string |
||||
Catastrophes []string |
||||
} |
||||
|
||||
type TreasuresInfo struct { |
||||
MiscItems []string |
||||
WornItems []string |
||||
Weapons []string |
||||
Books []string |
||||
Tools []string |
||||
MagicalIngredients []string |
||||
Treasures []string |
||||
Potions []tables.Potion |
||||
ValuableMaterials []string |
||||
} |
||||
|
||||
type Variables struct { |
||||
Characters []tables.Character |
||||
Cities []tables.City |
||||
MagicInfo MagicInfo |
||||
Monsters []tables.Monster |
||||
NPCs []tables.NPC |
||||
Wilds []tables.Wild |
||||
Dungeons []tables.Maze |
||||
Treasures TreasuresInfo |
||||
} |
||||
|
||||
func main() { |
||||
rand.Seed(time.Now().UnixNano()) |
||||
|
||||
var potions []tables.Potion |
||||
for i := 0; i < 10; i++ { |
||||
potions = append(potions, tables.GenPotion()) |
||||
} |
||||
|
||||
treasuresInfo := TreasuresInfo{ |
||||
MiscItems: helpers.GenUniqueItems(10, tables.TreasureTable{}.GenMiscItem), |
||||
WornItems: helpers.GenUniqueItems(10, tables.TreasureTable{}.GenWornItem), |
||||
Weapons: helpers.GenUniqueItems(10, tables.TreasureTable{}.GenWeaponItem), |
||||
Books: helpers.GenUniqueItems(10, tables.TreasureTable{}.GenBookSubject), |
||||
Tools: helpers.GenUniqueItems(10, tables.TreasureTable{}.GenToolItem), |
||||
ValuableMaterials: helpers.GenUniqueItems(10, tables.TreasureTable{}.GenValuableMaterial), |
||||
MagicalIngredients: helpers.GenUniqueItems(10, tables.TreasureTable{}.GenMagicalIngredient), |
||||
Treasures: helpers.GenUniqueItems(10, tables.GenTreasure), |
||||
Potions: potions, |
||||
} |
||||
|
||||
chars := []tables.Character{} |
||||
chars = append(chars, tables.GenCharacter("Upper Class", "Male")) |
||||
|
||||
cities := []tables.City{} |
||||
cities = append(cities, tables.GenCity()) |
||||
|
||||
magicInfo := MagicInfo{ |
||||
Mutations: helpers.GenUniqueItems(10, tables.MagicTable{}.GenMutation), |
||||
Insanities: helpers.GenUniqueItems(10, tables.MagicTable{}.GenInsanity), |
||||
Catastrophes: helpers.GenUniqueItems(10, tables.MagicTable{}.GenCatastrophe), |
||||
} |
||||
|
||||
monsters := []tables.Monster{} |
||||
monsters = append(monsters, tables.GenMonster()) |
||||
monsters = append(monsters, tables.GenMonster()) |
||||
monsters = append(monsters, tables.GenMonster()) |
||||
|
||||
// Civilized, Underworld, Wilderness
|
||||
npcs := []tables.NPC{} |
||||
npcs = append(npcs, tables.GenNPC()) |
||||
npcs = append(npcs, tables.GenNPC()) |
||||
npcs = append(npcs, tables.GenNPC()) |
||||
npcs = append(npcs, tables.GenNPC()) |
||||
npcs = append(npcs, tables.GenNPC()) |
||||
npcs = append(npcs, tables.GenNPC()) |
||||
|
||||
wilds := []tables.Wild{} |
||||
wilds = append(wilds, tables.GenWild()) |
||||
wilds = append(wilds, tables.GenWild()) |
||||
wilds = append(wilds, tables.GenWild()) |
||||
|
||||
dungeons := []tables.Maze{} |
||||
dungeons = append(dungeons, tables.GenMaze()) |
||||
dungeons = append(dungeons, tables.GenMaze()) |
||||
dungeons = append(dungeons, tables.GenMaze()) |
||||
|
||||
variables := Variables{ |
||||
Characters: chars, |
||||
Cities: cities, |
||||
MagicInfo: magicInfo, |
||||
Monsters: monsters, |
||||
NPCs: npcs, |
||||
Wilds: wilds, |
||||
Dungeons: dungeons, |
||||
Treasures: treasuresInfo, |
||||
} |
||||
|
||||
tmpl, err := template.ParseFiles(helpers.LocalFile("game.html")) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
err = tmpl.Execute(os.Stdout, variables) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,21 @@ |
||||
module mazeratsgen |
||||
|
||||
go 1.14 |
||||
|
||||
require ( |
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 |
||||
github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect |
||||
github.com/go-openapi/spec v0.19.8 // indirect |
||||
github.com/go-openapi/swag v0.19.9 // indirect |
||||
github.com/gorilla/mux v1.7.4 |
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect |
||||
github.com/mailru/easyjson v0.7.1 // indirect |
||||
github.com/spf13/cobra v1.0.0 |
||||
github.com/swaggo/swag v1.6.7 |
||||
github.com/throttled/throttled v2.2.4+incompatible |
||||
github.com/urfave/cli/v2 v2.2.0 // indirect |
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect |
||||
golang.org/x/text v0.3.3 // indirect |
||||
golang.org/x/tools v0.0.0-20200711155855-7342f9734a7d // indirect |
||||
gopkg.in/yaml.v2 v2.3.0 // indirect |
||||
) |
@ -0,0 +1,266 @@ |
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= |
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= |
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= |
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= |
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= |
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= |
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= |
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= |
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= |
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= |
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= |
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= |
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= |
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= |
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= |
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= |
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= |
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= |
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= |
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= |
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= |
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= |
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= |
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= |
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= |
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= |
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= |
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= |
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= |
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= |
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= |
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= |
||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= |
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= |
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= |
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= |
||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= |
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= |
||||
github.com/go-bindata/go-bindata v1.0.0 h1:DZ34txDXWn1DyWa+vQf7V9ANc2ILTtrEjtlsdJRF26M= |
||||
github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE= |
||||
github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= |
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= |
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= |
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= |
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= |
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= |
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= |
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= |
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= |
||||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= |
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= |
||||
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= |
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= |
||||
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= |
||||
github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= |
||||
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= |
||||
github.com/go-openapi/spec v0.19.8 h1:qAdZLh1r6QF/hI/gTq+TJTvsQUodZsM7KLqkAJdiJNg= |
||||
github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= |
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= |
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= |
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= |
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= |
||||
github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE= |
||||
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= |
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= |
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= |
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= |
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= |
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= |
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= |
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= |
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= |
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= |
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= |
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= |
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= |
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= |
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= |
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= |
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= |
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= |
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= |
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= |
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= |
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= |
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= |
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= |
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= |
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= |
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= |
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= |
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= |
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= |
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= |
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= |
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= |
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= |
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= |
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= |
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= |
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= |
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= |
||||
github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= |
||||
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= |
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= |
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= |
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= |
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= |
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= |
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= |
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= |
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= |
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= |
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= |
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= |
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= |
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= |
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= |
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= |
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= |
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= |
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= |
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= |
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= |
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= |
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= |
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= |
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= |
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= |
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= |
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= |
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= |
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= |
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= |
||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= |
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= |
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= |
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= |
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= |
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= |
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= |
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= |
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= |
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= |
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= |
||||
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI= |
||||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= |
||||
github.com/swaggo/swag v1.6.7 h1:e8GC2xDllJZr3omJkm9YfmK0Y56+rMO3cg0JBKNz09s= |
||||
github.com/swaggo/swag v1.6.7/go.mod h1:xDhTyuFIujYiN3DKWC/H/83xcfHp+UE/IzWWampG7Zc= |
||||
github.com/throttled/throttled v1.0.0 h1:GQ7a1ilkYMXnZ6V0EG7RiU3qHk1k/kpXO/aIQQXPfEQ= |
||||
github.com/throttled/throttled v2.2.4+incompatible h1:aVKdoH/qT5Mo1Lm/678OkX2pFg7aRpHlTn1tfgaSKxs= |
||||
github.com/throttled/throttled v2.2.4+incompatible/go.mod h1:0BjlrEGQmvxps+HuXLsyRdqpSRvJpq0PNIsOtqP9Nos= |
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= |
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= |
||||
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0= |
||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= |
||||
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI= |
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= |
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= |
||||
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= |
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= |
||||
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= |
||||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= |
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= |
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= |
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= |
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= |
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= |
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= |
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= |
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= |
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= |
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= |
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= |
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= |
||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= |
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= |
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= |
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= |
||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= |
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= |
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= |
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= |
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= |
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= |
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= |
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= |
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= |
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= |
||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SGrZkZixxWpwNCDiwJfh88= |
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= |
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
||||
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f h1:JcoF/bowzCDI+MXu1yLqQGNO3ibqWsWq+Sk7pOT218w= |
||||
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= |
||||
golang.org/x/tools v0.0.0-20200711155855-7342f9734a7d h1:F3OmlXCzYtG9YE6tXDnUOlJBzVzHF8EcmZ1yTJlcgIk= |
||||
golang.org/x/tools v0.0.0-20200711155855-7342f9734a7d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= |
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= |
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= |
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= |
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= |
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= |
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= |
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= |
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= |
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= |
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= |
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= |
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= |
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= |
@ -0,0 +1,66 @@ |
||||
{ |
||||
"appearance": [ |
||||
["Aquiline", "Athletic", "Barrel-Chested", "Boney", "Brawny", "Brutish"], |
||||
["Bullnecked", "Chiseled", "Coltish", "Corpulent", "Craggy", "Delicate"], |
||||
["Furrowed", "Gaunt", "Gorgeous", "Grizzled", "Haggard", "Handsome"], |
||||
["Hideous", "Lanky", "Pudgy", "Ripped", "Rosy", "Scrawny"], |
||||
["Sinewy", "Slender", "Slumped", "Solid", "Square-Jawed", "Statuesque"], |
||||
["Towering", "Trim", "Weathered", "Willowy", "Wiry", "Wrinkled"] |
||||
], |
||||
"clothing": [ |
||||
["Antique", "Battle-torn", "Bedraggled", "Blood-stained", "Ceremonial", "Dated"], |
||||
["Decaying", "Eccentric", "Elegant", "Embroidered", "Exotic", "Fashionable"], |
||||
["Flamboyant", "Food-stained", "Formal", "Frayed", "Frumpy", "Garish"], |
||||
["Grimy", "Haute couture", "Lacey", "Livery", "Mud-stained", "Ostentatious"], |
||||
["Oversized", "Patched", "Patterned", "Perfumed", "Practical", "Rumpled"], |
||||
["Sigils", "Singed", "Tasteless", "Undersized", "Wine-stained", "Worn out"] |
||||
], |
||||
"background": [ |
||||
["Alchemist", "Begger-prince", "Blackmailer", "Bounty-hunter", "Chimney sweep", "Coin-clipper"], |
||||
["Contortionist", "Counterfeiter", "Cultist", "Cutpurse", "Debt-collector", "Deserter"], |
||||
["Fence", "Fortuneteller", "Galley slave", "Gambler", "Gravedigger", "Headsman"], |
||||
["Hedge knight", "Highwayman", "Housebreaker", "Kidnapper", "Mad prophet", "Mountebank"], |
||||
["Peddler", "Pit-fighter", "Poisoner", "Rat-catcher", "Scrivener", "Sellsword"], |
||||
["Slave", "Smuggler", "Street performer", "Tatooist", "Urchin", "Usurer"] |
||||
], |
||||
"items": [ |
||||
["Animal Scent", "Bear Trap", "Bedroll", "Caltrops", "Chain (10 ft.)", "Chalk"], |
||||
["Chisel", "Crowbar", "Fishing Net", "Glass Marbles", "Glue", "Grappling Hook"], |
||||
["Grease", "Hacksaw", "Hammer", "Hand drill", "Horn", "Iron spikes"], |
||||
["Iron tongs", "Lantern and Oil", "Large Sack", "Lockpicks (3)", "Manacles", "Medicine (3)"], |
||||
["Metal file", "Rations (3)", "Rope (50 ft.)", "Steel wire", "Shovel", "Steel mirror"], |
||||
["Ten Foot Pole", "Tinderbox", "Torch", "Vial of Acid", "Vial of Poison", "Waterskin"] |
||||
], |
||||
"mannerism": [ |
||||
["Anecdotes", "Breathy", "Chuckles", "Clipped", "Cryptic", "Deep voice"], |
||||
["Drawl", "Enunciates", "Flowery speech", "Gravelly voice", "High formal", "Hypnotic"], |
||||
["Interrupts", "Laconic", "Laughs", "Long pauses", "Melodious", "Monotone"], |
||||
["Mumbles", "Narrates", "Overly casual", "Quaint sayings", "Rambles", "Random facts"], |
||||
["Rapid-fire", "Rhyming", "Robotic", "Slow speech", "Speechifies", "Squeky"], |
||||
["Street slang", "Stutters", "Talks to self", "Trails off", "Very loud", "Whispers"] |
||||
], |
||||
"personality": [ |
||||
["Bitter", "Brave", "Cautious", "Chipper", "Contrary", "Cowardly"], |
||||
["Cunning", "Driven", "Entitled", "Gregarious", "Grumpy", "Heartless"], |
||||
["Honor-bound", "Hotheaded", "Inquisitive", "Irascible", "Jolly", "Know-it-all"], |
||||
["Lazy", "Loyal", "Menacing", "Mopey", "Nervous", "Protective"], |
||||
["Righteous", "Rude", "Sarcastic", "Savage", "Scheming", "Serene"], |
||||
["Spacey", "Stoic", "Stubborn", "Stuck-up", "Suspicious", "Wisecracking"] |
||||
], |
||||
"physical_detail": [ |
||||
["Acid scars", "Battle scars", "Birthmark", "Braided hair", "Brand mark", "Broken nose"], |
||||
["Bronze skinned", "Burn scars", "Bushy eyebrows", "Curly hair", "Dark skinned", "Dreadlocks"], |
||||
["Exotic accent", "Flogging scars", "Freckles", "Gold tooth", "Hoarse voice", "Huge beard"], |
||||
["Long hair", "Matted hair", "Missing ear", "Missing teeth", "Mustache", "Muttonchops"], |
||||
["Nine fingers", "Oiled hair", "One-eyed", "Pale skinned", "Piercings", "Ritual scars"], |
||||
["Sallow skin", "Shaved head", "Sunburned", "Tangled hair", "Tatoos", "Topnot"] |
||||
], |
||||
"feat": [ |
||||
"A +1 to all attack rolls", |
||||
"A single spell slot", |
||||
"Briarborn (Advantage on tracking, foraging, survival)", |
||||
"Fingersmith (Advantage on tinkering and picking locks or pockets)", |
||||
"Roofrunner (Advantage on climbing, leaping, or balancing)", |
||||
"Shadowjack (Advantage on moving silently or hiding in shadows)" |
||||
] |
||||
} |
@ -0,0 +1,98 @@ |
||||
{ |
||||
"city_themes": [ |
||||
["EXTERNAL","Aristocracy","Art","Bureaucracy","Castes","Catacombs"], |
||||
["EXTERNAL","EXTERNAL","Crime families","Cruelty","EXTERNAL","EXTERNAL"], |
||||
["EXTERNAL","Festivals","Feuds","Intrigue","Theme","Martial law"], |
||||
["Meritocracy","EXTERNAL","Opulence","EXTERNAL","Pilgrimages","Piracy"], |
||||
["Plutocracy","Poverty","Rituals","Slavery","Spices","Theocracy"], |
||||
["Thievery","Trade","Tyranny","EXTERNAL","Wizardry","Xenophobia"] |
||||
], |
||||
"city_events": [ |
||||
["Assassination","Carnival","Conscription","Coronation","Coup","Cult activity"], |
||||
["Curfew","Discovery","Earthquake","EXTERNAL","Fashion trend","Fire"], |
||||
["Flood","Heavy fog","Heavy taxes","Holy day","Hysteria","Inquisition"], |
||||
["Insurrection","Invasion","Jailbreak","Mass eviction","Mass pardon","Negotiations"], |
||||
["Plague","Proclamation","Prohibition","Public games","Refugees","Rioting"], |
||||
["Roundup","Scandal","Serial killer","Shortage","Tournament","Trial"] |
||||
], |
||||
"district_themes": [ |
||||
["Catacombs","EXTERNAL","Construction","Crafts","Criminality","Culture"], |
||||
["Dining","Education","Entertainment","Finance","Foreigners","Ghettoes"], |
||||
["Government","Graveyards","Green space","Industrialization","Judgement","Livestock"], |
||||
["EXTERNAL","Marketplace","Memorials","Military","Opulence","Pollution"], |
||||
["Poverty","Punishment","Religion","Science","Trade","Trash"], |
||||
["EXTERNAL","EXTERNAL","Vices","EXTERNAL","Wizardry","Wonders"] |
||||
], |
||||
"upper_class_buildings": [ |
||||
["Academy","Alchemist","Archive","Art dealer","Barber","Bookbinder"], |
||||
["Bookseller","Castle","Clockmaker","Clothier","Courthouse","Furrier"], |
||||
["Gallery","Garden","Haberdashery","Jeweler","Law office","Locksmith"], |
||||
["Lounge","Manor","Museum","Observatory","Opera house","Park"], |
||||
["Physician","Printer","Public baths","Restaurant","Salon","Stables"], |
||||
["Taxidermist","Temple","Tobacconist","Townhouse","Winery","Zoo"] |
||||
], |
||||
"lower_class_buildings": [ |
||||
["Apothecary","Asylum","Baker","Brewery","Butcher","Candlemaker"], |
||||
["Catacombs","Cheesemaker","Criminal den","Curiosity shop","Dock","Fighting pit"], |
||||
["Forge","Fortuneteller","Gambling hall","Leatherworks","Marketplace","Mason"], |
||||
["Mill","Moneylender","Orphanage","Outfitter","Prison","Sewers"], |
||||
["Shipyards","Shrine","Stockyard","Stonecarver","Tattooist","Tavern"], |
||||
["Theater","Veterinarian","Warehouse","Watchtower","Weaver","Workshop"] |
||||
], |
||||
"city_activities": [ |
||||
["Abduct","Beg","Brawl","Burgle","Celebrate","Chase"], |
||||
["Construct","Cook","Dance","Duel","EXTERNAL","Execute"], |
||||
["Extinguish","Extort","Follow","Gamble","Haul","Interrogate"], |
||||
["Marry","EXTERNAL","Mourn","Party","Patrol","Perform"], |
||||
["Play","Preach","Process","Proclaim","Protest","Release"], |
||||
["Repair","Riot","Rob","Search","Sell","EXTERNAL"] |
||||
], |
||||
"building_rooms": [ |
||||
["Arboretum","Atrium","Attic","Aviary","Ballroom","Baths"], |
||||
["Bed chamber","Cabinet","Chapel","Cloakroom","Dining room","Dressing room"], |
||||
["EXTERNAL","Garden","Garret","Greenhouse","Junk room","Kitchen"], |
||||
["Larder","Library","Map room","Menagerie","Mews","Nursery"], |
||||
["Pantry","Parlor","Privy","Root cellar","Saucery","Scullery"], |
||||
["Smoking room","Spicery","Still room","Study","Trophy room","Wardrobe"] |
||||
], |
||||
"tactical_street_features": [ |
||||
["Arcade","Awnings","Balconies","Barricades","Bridge","Canal"], |
||||
["Carriages","Catwalks","EXTERNAL","Climbable walls","Clotheslines","Crowd"], |
||||
["Dead end","Dense fog","Downpour","EXTERNAL","Flooding","Food stalls"], |
||||
["Fountain","Gates","Ladders","Livestock","Muddy","Overgrown"], |
||||
["Roof access","Roof gardens","Sewer access","Sinkhole","Slick","Steep roofs"], |
||||
["Steep streets","Steps","Torn up street","Vermin swarms","Well","EXTERNAL"] |
||||
], |
||||
"tactical_building_features": [ |
||||
["EXTERNAL","Balconies","Basement access","Brightly lit","Broken furniture","Broken glass"], |
||||
["Cabinets","Carpeted floors","Chandeliers","Crawlspaces","Drain pipes","Dumbwaiters"], |
||||
["Echoing marble","Hanging chains","Huge fireplace","Narrow ledges","Open windows","Ornate weapons"], |
||||
["Overgrown","Patrols","Piles of trash","Pillars","Rotting ceiling","Rotting floors"], |
||||
["Rotting walls","Screens","Servant passages","Sewer access","Shadowy alcoves","Skylights"], |
||||
["Spyholes","Staircases","Tall bookshelves","Unlit","Watchdogs","Window drapes"] |
||||
], |
||||
"factions": [ |
||||
["Art movement","Beggar's guild","Black market","Brotherhood","City guard","Conspiracy"], |
||||
["Craft guild","Crime family","Crime ring","Dark cult","Explorer's club","Free company"], |
||||
["Gourmand club","Heist crew","Heretical sect","High council","Hired killers","Local militia"], |
||||
["National church","Noble house","Outlander clan","Outlaw gang","Political party","Religious order"], |
||||
["Religious sect","Resistance","Royal army","Royal house","Scholar's circle","Secret society"], |
||||
["Spy network","Street artists","Street gang","Street musicians","Theater troupe","Trade company"] |
||||
], |
||||
"faction_traits": [ |
||||
["Bankrupt","Bureaucratic","Charitable","Confused","Connected","Corrupt"], |
||||
["Decadent","Decaying","Delusional","Divided","Dwindling","Efficient"], |
||||
["Esoteric","Expanding","Hunted","Incompetent","Incorruptible","Insane"], |
||||
["Insular","Manipulative","Martial","EXTERNAL","Pious","Popular"], |
||||
["Righteous","Ruthless","Secret","Subversive","Suppressed","Threatened"], |
||||
["Thriving","Unpopular","Up-and-coming","Wealthy","Well-prepared","Xenophobic"] |
||||
], |
||||
"faction_goals": [ |
||||
["Advise leader","Avoid detection","Awaken being","Collect artifacts","Construct base","EXTERNAL"], |
||||
["Control politics","Create artifact","EXTERNAL","EXTERNAL","Defend borders","Defend leader"], |
||||
["Destroy artifacts","Destroy being","Destroy villain","Enforce law","Enrich members","Entertain"], |
||||
["Exchange goods","Hear rumors","Indulge tastes","EXTERNAL","Map the wild","Overthrow order"], |
||||
["Preserve lineage","Preserve lore","Produce goods","Promote arts","Promote craft","Purge traitors"], |
||||
["Sell services","Share knowledge","Spread beliefs","Summon evil","Survive","Transport goods"] |
||||
] |
||||
} |
@ -0,0 +1,209 @@ |
||||
package data |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"log" |
||||
"mazeratsgen/assets/bindata" |
||||
) |
||||
|
||||
type tableStruct struct { |
||||
Character characterTable |
||||
City cityTable |
||||
Magic magicTable |
||||
Maze mazeTable |
||||
Monster monsterTable |
||||
NPC npcTable |
||||
Treasure treasureTable |
||||
Wild wildTable |
||||
} |
||||
|
||||
var Tables = tableStruct{ |
||||
Character: CharacterTable(), |
||||
City: CityTable(), |
||||
Magic: MagicTable(), |
||||
Maze: MazeTable(), |
||||
Monster: MonsterTable(), |
||||
NPC: NPCTable(), |
||||
Treasure: TreasureTable(), |
||||
Wild: WildTable(), |
||||
} |
||||
|
||||
type characterTable struct { |
||||
Appearance [][]string `json:"appearance"` |
||||
Clothing [][]string `json:"clothing"` |
||||
Background [][]string `json:"background"` |
||||
Items [][]string `json:"items"` |
||||
Mannerism [][]string `json:"mannerism"` |
||||
Personality [][]string `json:"personality"` |
||||
PhysicalDetail [][]string `json:"physical_detail"` |
||||
Feat []string `json:"feat"` |
||||
} |
||||
|
||||
type cityTable struct { |
||||
CityThemes [][]string `json:"city_themes"` |
||||
CityEvents [][]string `json:"city_events"` |
||||
DistrictThemes [][]string `json:"district_themes"` |
||||
UpperClassBuildings [][]string `json:"upper_class_buildings"` |
||||
LowerClassBuildings [][]string `json:"lower_class_buildings"` |
||||
CityActivities [][]string `json:"city_activities"` |
||||
BuildingRooms [][]string `json:"building_rooms"` |
||||
TacticalStreetFeatures [][]string `json:"tactical_street_features"` |
||||
TacticalBuildingFeatures [][]string `json:"tactical_building_features"` |
||||
Factions [][]string `json:"factions"` |
||||
FactionTraits [][]string `json:"faction_traits"` |
||||
FactionGoals [][]string `json:"faction_goals"` |
||||
} |
||||
|
||||
type magicTable struct { |
||||
PhysicalEffects [][]string `json:"physical_effects"` |
||||
PhysicalElements [][]string `json:"physical_elements"` |
||||
PhysicalForms [][]string `json:"physical_forms"` |
||||
EtherealEffects [][]string `json:"ethereal_effects"` |
||||
EtherealElements [][]string `json:"ethereal_elements"` |
||||
EtherealForms [][]string `json:"ethereal_forms"` |
||||
Mutations [][]string `json:"mutations"` |
||||
Insanities [][]string `json:"insanities"` |
||||
Catastrophes [][]string `json:"catastrophes"` |
||||
} |
||||
|
||||
type mazeTable struct { |
||||
DungeonEntrances [][]string `json:"dungeon_entrances"` |
||||
DungeonForms [][]string `json:"dungeon_forms"` |
||||
DungeonLayout [][]string `json:"dungeon_layout"` |
||||
DungeonRuinations [][]string `json:"dungeon_ruinations"` |
||||
DungeonRewards [][]string `json:"dungeon_rewards"` |
||||
DungeonActivities [][]string `json:"dungeon_activities"` |
||||
DungeonRooms [][]string `json:"dungeon_rooms"` |
||||
DungeonRoomDetails [][]string `json:"dungeon_room_details"` |
||||
DungeonTricks [][]string `json:"dungeon_tricks"` |
||||
DungeonHazards [][]string `json:"dungeon_hazards"` |
||||
TrapEffects [][]string `json:"trap_effects"` |
||||
TrapTriggers [][]string `json:"trap_triggers"` |
||||
} |
||||
|
||||
type monsterTable struct { |
||||
Aerial [][]string `json:"aerial"` |
||||
Terrestrial [][]string `json:"terrestrial"` |
||||
Aquatic [][]string `json:"aquatic"` |
||||
Features [][]string `json:"features"` |
||||
Traits [][]string `json:"traits"` |
||||
Abilities [][]string `json:"abilities"` |
||||
Tactics [][]string `json:"tactics"` |
||||
Personality [][]string `json:"personality"` |
||||
Weakness [][]string `json:"weakness"` |
||||
} |
||||
|
||||
type npcTable struct { |
||||
CivilizedNPCs [][]string `json:"civilized_npcs"` |
||||
UnderworldNPCs [][]string `json:"underworld_npcs"` |
||||
WildernessNPCs [][]string `json:"wilderness_npcs"` |
||||
FemaleNames [][]string `json:"female_names"` |
||||
MaleNames [][]string `json:"male_names"` |
||||
UpperClassSurnames [][]string `json:"upper_class_surnames"` |
||||
LowerClassSurnames [][]string `json:"lower_class_surnames"` |
||||
Assets [][]string `json:"assets"` |
||||
Liabilities [][]string `json:"liabilities"` |
||||
NPCGoals [][]string `json:"npc_goals"` |
||||
Misfortunes [][]string `json:"misfortunes"` |
||||
Missions [][]string `json:"missions"` |
||||
Methods [][]string `json:"methods"` |
||||
Appearances [][]string `json:"appearances"` |
||||
PhysicalDetails [][]string `json:"physical_details"` |
||||
Clothing [][]string `json:"clothing"` |
||||
Personalities [][]string `json:"personalities"` |
||||
Mannerisms [][]string `json:"mannerisms"` |
||||
Secrets [][]string `json:"secrets"` |
||||
Reputations [][]string `json:"reputations"` |
||||
Hobbies [][]string `json:"hobbies"` |
||||
Relationships [][]string `json:"relationships"` |
||||
DivineDomains [][]string `json:"divine_domains"` |
||||
AfterTheParty [][]string `json:"after_the_party"` |
||||
} |
||||
|
||||
type treasureTable struct { |
||||
MiscItems [][]string `json:"misc_items"` |
||||
WornItems [][]string `json:"worn_items"` |
||||
WeaponItems [][]string `json:"weapon_items"` |
||||
BookSubjects [][]string `json:"book_subjects"` |
||||
ToolItems [][]string `json:"tool_items"` |
||||
Potions [][]string `json:"potions"` |
||||
MagicalIngredients [][]string `json:"magical_ingredients"` |
||||
TreasureItems [][]string `json:"treasure_items"` |
||||
TreasureTraits [][]string `json:"treasure_traits"` |
||||
ValuableMaterials [][]string `json:"valuable_materials"` |
||||
} |
||||
|
||||
type wildTable struct { |
||||
WildernessRegions [][]string `json:"wilderness_regions"` |
||||
WildernessRegionTraits [][]string `json:"wilderness_region_traits"` |
||||
WildernessLandmarks [][]string `json:"wilderness_landmarks"` |
||||
WildernessStructures [][]string `json:"wilderness_structures"` |
||||
WildernessDiscoveries [][]string `json:"wilderness_discoveries"` |
||||
WildernessActivities [][]string `json:"wilderness_activities"` |
||||
WildernessHazards [][]string `json:"wilderness_hazards"` |
||||
EdiblePlants [][]string `json:"edible_plants"` |
||||
PoisonousPlants [][]string `json:"poisonous_plants"` |
||||
InnAdjectives [][]string `json:"inn_adjectives"` |
||||
InnNouns [][]string `json:"inn_nouns"` |
||||
InnQuirks [][]string `json:"inn_quirks"` |
||||
} |
||||
|
||||
func CharacterTable() characterTable { |
||||
var table characterTable |
||||
unmarshalTable("character.json", &table) |
||||
return table |
||||
} |
||||
|
||||
func CityTable() cityTable { |
||||
var table cityTable |
||||
unmarshalTable("city.json", &table) |
||||
return table |
||||
} |
||||
|
||||
func MagicTable() magicTable { |
||||
var table magicTable |
||||
unmarshalTable("magic.json", &table) |
||||
return table |
||||
} |
||||
|
||||
func MazeTable() mazeTable { |
||||
var table mazeTable |
||||
unmarshalTable("maze.json", &table) |
||||
return table |
||||
} |
||||
|
||||
func MonsterTable() monsterTable { |
||||
var table monsterTable |
||||
unmarshalTable("monster.json", &table) |
||||
return table |
||||
} |
||||
|
||||
func NPCTable() npcTable { |
||||
var table npcTable |
||||
unmarshalTable("npc.json", &table) |
||||
return table |
||||
} |
||||
|
||||
func TreasureTable() treasureTable { |
||||
var table treasureTable |
||||
unmarshalTable("treasure.json", &table) |
||||
return table |
||||
} |
||||
|
||||
func WildTable() wildTable { |
||||
var table wildTable |
||||
unmarshalTable("wild.json", &table) |
||||
return table |
||||
} |
||||
|
||||
func unmarshalTable(path string, table interface{}) { |
||||
asset, err := bindata.Asset(path) |
||||
if err != nil { |
||||
log.Fatal(err) |
||||
} |
||||
|
||||
err = json.Unmarshal(asset, &table) |
||||
if err != nil { |
||||
log.Fatal(err) |
||||
} |
||||
} |
@ -0,0 +1,74 @@ |
||||
{ |
||||
"physical_effects": [ |
||||
["Animating","Attracting","Binding","Blossoming","Consuming","Creeping"], |
||||
["Crushing","Diminishing","Dividing","Duplicating","Enveloping","Expanding"], |
||||
["Fusing","Grasping","Hastening","Hindering","Illuminating","Imprisoning"], |
||||
["Levitating","Opening","Petrifying","Phasing","Piercing","Pursuing"], |
||||
["Reflecting","Regenerating","Rending","Repelling","Resurrecting","Screaming"], |
||||
["Sealing","Shapeshifting","Shielding","Spawning","Transmuting","Transporting"] |
||||
], |
||||
"physical_elements": [ |
||||
["Acid","Amber","Bark","Blood","Bone","Brine"], |
||||
["Clay","Crow","Crystal","Ember","Flash","Fungus"], |
||||
["Glass","Honey","Ice","Insect","Wood","Lava"], |
||||
["Moss","Obsidian","Oil","Poison","Rat","Salt"], |
||||
["Sand","Sap","Serpent","Slime","Stone","Tar"], |
||||
["Thorn","Vine","Water","Wine","Wood","Worm"] |
||||
], |
||||
"physical_forms": [ |
||||
["Altar","Armor","Arrow","Beast","Blade","Cauldron"], |
||||
["Chain","Chariot","Claw","Cloak","Colossus","Crown"], |
||||
["Elemental","Eye","Fountain","Gate","Golem","Hammer"], |
||||
["Horn","Key","Mask","Monolith","Pit","Prison"], |
||||
["Sentinel","Servant","Shield","Spear","Steed","Swarm"], |
||||
["Tentacle","Throne","Torch","Trap","Wall","Web"] |
||||
], |
||||
"ethereal_effects": [ |
||||
["Avenging","Banishing","Bewildering","Blinding","Charming","Communicating"], |
||||
["Compelling","Concealing","Deafening","Deceiving","Deciphering","Disguising"], |
||||
["Dispelling","Emboldening","Encoding","Energizing","Enlightening","Enraging"], |
||||
["Excruciating","Foreseeing","Intoxicating","Maddening","Mesmerizing","Mindreading"], |
||||
["Nullifying","Paralyzing","Revealing","Revolting","Scrying","Silencing"], |
||||
["Soothing","Summoning","Terrifying","Warding","Wearying","Withering"] |
||||
], |
||||
"ethereal_elements": [ |
||||
["Ash","Chaos","Distortion","Dream","Dust","Echo"], |
||||
["Ectoplasm","Fire","Fog","Ghost","Harmony","Heat"], |
||||
["Light","Lightening","Memory","Mind","Mutation","Negation"], |
||||
["Plague","Plasma","Probability","Rain","Rot","Shadow"], |
||||
["Smoke","Snow","Soul","Star","Stasis","Steam"], |
||||
["Thunder","Time","Void","Warp","Whisper","Wind"] |
||||
], |
||||
"ethereal_forms": [ |
||||
["Aura","Beacon","Beam","Blast","Blob","Bolt"], |
||||
["Bubble","Call","Cascade","Circle","Cloud","Coil"], |
||||
["Cone","Cube","Dance","Disk","Field","Form"], |
||||
["Gaze","Loop","Moment","Nexus","Portal","Pulse"], |
||||
["Pyramid","Ray","Shard","Sphere","Spray","Storm"], |
||||
["Swarm","Torrent","Touch","Vortex","Wave","Word"] |
||||
], |
||||
"mutations": [ |
||||
["Ages","Attracts birds","Child-form","Corpulence","Covered in hair","EXTERNAL"], |
||||
["EXTERNAL","EXTERNAL","EXTERNAL","EXTERNAL","EXTERNAL","EXTERNAL"], |
||||
["Cyclops","Extra arms","Extra eyes","Extra legs","Forked tongue","Gender swap"], |
||||
["Hunchback","EXTERNAL","Long arms","Lose all hair","Loses teeth","EXTERNAL"], |
||||
["EXTERNAL","No eyes","No mouth","EXTERNAL","Second face","Sheds skin"], |
||||
["Shrinks","Shrivels","Skin boils","Slime trail","Translucent skin","Weeps blood"] |
||||
], |
||||
"insanities": [ |
||||
["Always lies","Always polite","EXTERNAL","Cannot count","Cannot lie","Faceblind"], |
||||
["Fears birds","Fears blood","Fears books","Fears darkness","Fears fire","Fears gold"], |
||||
["Fears horses","Fears iron","Fears music","Fears own hand","Fears PC","Fears rain"], |
||||
["Fears rivers","Fears silence","Fears sleep","Fears sunlight","Fears the moon","Fears trees"], |
||||
["EXTERNAL","'Gorgeous'","Hates violence","'Invisible'","'Invulnerable'","EXTERNAL"], |
||||
["'EXTERNAL'","'EXTERNAL'","Must sing","EXTERNAL","Says thoughts","See dead people"] |
||||
], |
||||
"catastrophes": [ |
||||
["All iron rusts","Animals die","EXTERNAL","Birds attack","City appears","Deadly fog"], |
||||
["Dream plague","Endless night","Endless rain","Endless storm","Endless twilight","Endless winter"], |
||||
["Fae return","Forest appears","Forgetfulness","Graves open","Lamentations","Maggots"], |
||||
["EXTERNAL","EXTERNAL","Mass slumber","Meteor strike","Mirrors speak","No stars"], |
||||
["Outsider enters","People shrink","People vanish","Plants wither","Portal opens","Rifts open"], |
||||
["Shadows speak","Space distorts","Stones speak","Total silence","Tower appears","Water to blood"] |
||||
] |
||||
} |
@ -0,0 +1,98 @@ |
||||
{ |
||||
"dungeon_entrances": [ |
||||
["All libraries","Beaver dam","Behind waterfall","Chalk rectangle","Chest bottom ","Chimney"], |
||||
["Cupboard","Dolmen shadow","Down a well","Fiery pit","Fog road","Forest spring "], |
||||
["Giant book","Gypsy wagon","Hollow tree","Huge keyhole","Iron maiden","Living tattoo"], |
||||
["Magic painting","Man-shape hole","Maze potion","Mirror","Monster mouth","Monster wound"], |
||||
["Narrow alley","Rain door","Sewer grate","Sudden rift","Tidal cave","Towertop"], |
||||
["Tree roots","Under the bed","Unfolded map","Up a tree","Whirlpool","Wine barrel"] |
||||
], |
||||
"dungeon_forms": [ |
||||
["Arena","Asylum","Aviary","Bank","Baths","Body"], |
||||
["EXTERNAL","Casino","Catacombs","Cave","Court","EXTERNAL"], |
||||
["Room","Garden","Hideout","Hotel","EXTERNAL","Laboratory"], |
||||
["Library","Market","Mine","Monastery","Museum","Nursery"], |
||||
["Orphanage","Palace","Prison","Sewer","Ship","Slave pit"], |
||||
["Temple","Theater","EXTERNAL","University","Vault","Zoo"] |
||||
], |
||||
"dungeon_layout": [ |
||||
["Ant colony","Central hub","Claustrophobic","Crisscrossing","Curved","Disorienting"], |
||||
["Galleria","Geometric","Gonzo","Haphazard","Highly regular","Honeycomb"], |
||||
["Intertwined","Isolated wings","Layered","Linear","Loops","Many corridors"], |
||||
["Mazes","Mix of layouts","Multiple hubs","No corridors","Open plan","Open voids"], |
||||
["Organic","Oversized","Recursive","Repetitive","Sprawling","Suspended"], |
||||
["Symbol shape","Tall and narrow","Themed zones","Vertical","Winding","Ziggurat"] |
||||
], |
||||
"dungeon_ruinations": [ |
||||
["Arcane disaster","Army invasion","Cannibalism","Civil war","Collapse","Crystal growth"], |
||||
["Curse","Degeneration","Earthquake","Eruption","Evil unearthed","Experiments"], |
||||
["Explosion","Famine","Fire","Flooding","Fungus","Haunting"], |
||||
["Ice","EXTERNAL","Lava flow","Magical sleep ","Melted","Monster attack"], |
||||
["EXTERNAL","Outsider attack","Overgrowth","Petrification ","Plague","Planar overlay"], |
||||
["Poison gas","Resources gone","Revolt","Risen dead","Too many traps","War"] |
||||
], |
||||
"dungeon_rewards": [ |
||||
["Ancient lore","Animal ally","Army","Blessing","Blueprints","Cultural artifact"], |
||||
["Enemy weakness","Faction ally","Forewarning","Guide","Holy relic","Influential ally"], |
||||
["Instructions","Jewels","Key","Lost formula","Machine","EXTERNAL"], |
||||
["Magical ally","Map","Marital ally","Masterpiece","EXTERNAL","Oracle"], |
||||
["Piles of loot","Planar portal","Prophecy","Renown","Spell","Transformation"], |
||||
["Transport","EXTERNAL","Uncovered plot","EXTERNAL","Vision","Weapon"] |
||||
], |
||||
"dungeon_activities": [ |
||||
["Besiege","Capture","EXTERNAL","Collect","Construct","Control"], |
||||
["Deliver","Demolish","Escape","Feed","Fortify","Guard monster"], |
||||
["Hide","Hunt","Loot","Map","Mine","EXTERNAL"], |
||||
["Negotiate","Patrol","Perform ritual","Purge","Question","Raid"], |
||||
["Repair","Rescue","Research","Revive","Riddle","Scavenge"], |
||||
["Seize","Tunnel","Unearth","Vandalize","EXTERNAL","Worship"] |
||||
], |
||||
"dungeon_rooms": [ |
||||
["Armory","Banquet hall","Barracks","EXTERNAL","Catacombs","Cavern"], |
||||
["Chasm","Courtyard","Crypt","Dormitory","Fighting pit","Forge"], |
||||
["Fountain","Gate house","Guard room","Kennel","EXTERNAL","Laboratory"], |
||||
["Mess hall","Mine shaft","Museum","Oubliette","Pool","Prison"], |
||||
["Record room","Shrine","Slaughterhouse","Stables","Storeroom","Throneroom"], |
||||
["Torture room","Treasury","EXTERNAL","Vault","Well","Workshop"] |
||||
], |
||||
"dungeon_room_details": [ |
||||
["Bas-relief","Blood trail","Bones","Chains","Chalk marks","Claw marks"], |
||||
["Corpses","Cracked beams","Crumbling walls","Decaying food ","Decaying nest ","Dripping water"], |
||||
["Fading murals","Faint breeze","Faint footsteps","Fallen pillars","Fungus","Furniture"], |
||||
["Graffiti","Mosaics","Recent repairs","Rotting books","Rubble","Shed skin"], |
||||
["Slime trails","Spider webs","Stalactites","Stench","Smoke stains","Thick dust"], |
||||
["Torn clothes","Tree roots","Unusual smell","Vibrations","Vines","Whispers"] |
||||
], |
||||
"dungeon_tricks": [ |
||||
["Absorption","Activation","Animation","Blessings","Communication","Confusion"], |
||||
["Consumption","Creation","Curses","Deception","Duplication","EXTERNAL"], |
||||
["Exchange","Imprisonment","Instructions","Interrogation","Mind-control","EXTERNAL"], |
||||
["Mood-alteration","Nullification","EXTERNAL","Planeshift","Protection","Rejuvenation"], |
||||
["Release","Reversal","Rotation","Scrying","Size-alteration","Summoning"], |
||||
["Theft","Time-alteration","Transformation","Transmutation","Transportation","Wonder"] |
||||
], |
||||
"dungeon_hazards": [ |
||||
["Acid drip","Bloodsuckers","Cave-in","Choking dust","Crude oil","Crystal shards"], |
||||
["Deafening noise","Dense fog","Ensnaring vines","Fallen floor","Flooding","Freezing"], |
||||
["Geysers","Magma","Magnetic field","Mud flow","Narrow ledge","Narrow passage"], |
||||
["Poison goo","Poison plants","Precipice","Quicksand","Radiation","Rockslide"], |
||||
["Rotten ceiling","Rotten floor","Sinkhole","Slippery slope","Spider webs","Spores"], |
||||
["Steam vents","Strong winds","Tar pit","Tight passage","Toppling object","Toxic fumes"] |
||||
], |
||||
"trap_effects": [ |
||||
["Acid pool","Adhesive","Alarm","Armor melts","Bear trap","Blinding spray"], |
||||
["Blunt pendulum","Boiling tar","Collapsing floor","Crocodile pit","Crushing walls","Deep pit"], |
||||
["Falling cage","Falling ceiling","Fills with sand","Flooding","Giant magnet","Hard vacuum"], |
||||
["Lava flow","Lightning","Living statues","Missile fire","Monster freed","Net trap"], |
||||
["Pendulum blade","Poison gas","Poison needle","Quicksand","Rage gas","Rolling boulder"], |
||||
["Room freezes","Room on fire","Sleeping gas","Spiked pit","Tombs open","Wall spikes"] |
||||
], |
||||
"trap_triggers": [ |
||||
["Blow","Break","Burn","Choice","Countdown","Darkness"], |
||||
["Drain","Eat","Insert","Kill","Knock","Light"], |
||||
["Magic","Melody","Noise","Open","Phrase","Pour"], |
||||
["Press","Proximity","Pull","Read","Reflect","Release"], |
||||
["Remove","Retrieve","Rudeness","Shut","Sit","Sleep"], |
||||
["Slide","Touch","Turn","Unbalance","Unearth","Write"] |
||||
] |
||||
} |
@ -0,0 +1,74 @@ |
||||
{ |
||||
"aerial": [ |
||||
["Albatross", "Bat", "Beetle", "Bird of Paradise", "Butterfly", "Condor"], |
||||
["Crane", "Crow", "Dragonfly", "Eagle", "Falcon", "Firefly"], |
||||
["Flamingo", "Fly", "Flying Squirrel", "Goose", "Gull", "Hummingbird"], |
||||
["Kingfisher", "Locust", "Magpie", "Mantis", "Mockingbird", "Mosquito"], |
||||
["Moth", "Owl", "Parrot", "Peacock", "Pelican", "Pteranodon"], |
||||
["Rooster", "Sparrow", "Swan", "Vulture", "Wasp", "Woodpecker"] |
||||
], |
||||
"terrestrial": [ |
||||
["Ant", "Ape", "Armadillo", "Badger", "Bear", "Boar"], |
||||
["Caterpillar", "Centipede", "Chameleon", "Cockroach", "Deer", "Elephant"], |
||||
["Ferret", "Fox", "Giraffe", "Goat", "Horse", "Human"], |
||||
["Mole", "Ostrich", "Ox", "Porcupine", "Rabbit", "Raccoon"], |
||||
["Rat", "Rhinoceros", "Scorpion", "Sheep", "Slug", "Snail"], |
||||
["Snake", "Spider", "Squirrel", "Tiger", "Wolf", "Wolverine"] |
||||
], |
||||
"aquatic": [ |
||||
["Alligator", "Amoeba", "Anglerfish", "Beaver", "Clam", "Crab"], |
||||
["Dolphin", "Eel", "Frog", "Hippopotamus", "Jellyfish", "Leech"], |
||||
["Lobster", "Manatee", "Manta Ray", "Muskrat", "Narwhal", "Newt"], |
||||
["Octopus", "Otter", "Penguin", "Platypus", "Pufferfish", "Salamander"], |
||||
["Sea Anemone", "Sea Urchin", "Seahorse", "Seal", "Shark", "Shrimp"], |
||||
["Squid", "Swordfish", "Tadpole", "Turtle", "Walrus", "Whale"] |
||||
], |
||||
"features": [ |
||||
["Antlers", "Beak", "Carapace", "Claws", "Compound eyes", "Eye Stalks"], |
||||
["Fangs", "Fins", "Fur", "Gills", "Hooves", "Horns"], |
||||
["Legless", "Long tongue", "Many-eyed", "Many-limbed", "Mucus", "Pincers"], |
||||
["Plates", "Plumage", "Proboscis", "Scales", "Segments", "Shaggy hair"], |
||||
["Shell", "Spikes", "Spinnerets", "Spines", "Stinger", "Suction cups"], |
||||
["Tail", "Talons", "Tentacles", "Trunk", "Tusks", "Wings"] |
||||
], |
||||
"traits": [ |
||||
["Amphibious", "Bloated", "Brittle", "Cannibal", "Clay-like", "Colossal"], |
||||
["Crystalline", "Decaying", "EXTERNAL", "Ethereal", "Ever-young", "Eyeless"], |
||||
["Fearless", "Fluffy", "Fungal", "Gelatinous", "Geometric", "Hardened"], |
||||
["Illusory", "Intelligent", "Iridescent", "Luminous", "Many-headed", "Mechanical"], |
||||
["EXTERNAL", "Planar", "Reflective", "Rubbery", "Shadowy", "Sharp"], |
||||
["Skeletal", "Slimy", "Sticky", "Stinking", "Tiny", "Translucent"] |
||||
], |
||||
"abilities": [ |
||||
["Absorbing", "Acid blood", "Anti-magic", "Blinding", "Breath weapon", "Camouflaging"], |
||||
["Duplicating", "Electric", "Entangling", "EXTERNAL", "Exploding", "Flying"], |
||||
["Gaze weapon", "Hypnotizing", "Impervious", "Invisible", "Life-draining", "Magnetic"], |
||||
["Mimicking", "Mind-Reading", "Paralyzing", "Phasing", "EXTERNAL", "Poisonous"], |
||||
["Radioactive", "Reflective", "Regenerating", "Shapeshifting", "Spell-casting", "Stealthy"], |
||||
["Strangling", "Super-strength", "Telekinetic", "Teleporting", "Vampiric", "Wall-Crawling"] |
||||
], |
||||
"tactics": [ |
||||
["Ambush", "Call for support", "Capture", "Charge", "Climb foes", "Compel worship"], |
||||
["Create barrier", "Deceive", "Demand duel", "Disorient", "Encircle", "Evade"], |
||||
["Gang up", "Gather strength", "Go berserk", "Harry", "Hurl foes", "Immobilize"], |
||||
["Manipulate", "Mock", "Monologue", "Order minion", "Protect leader", "Protect self"], |
||||
["Scatter foes", "Stalk", "Steal from", "Swarm", "Target insolent", "Target leader"], |
||||
["Target nearest", "Target richest", "Target strongest", "Target weakest", "Toy with", "Use terrain"] |
||||
], |
||||
"personality": [ |
||||
["Alien", "Aloof", "Bored", "Cautious", "Cowardly", "Curious"], |
||||
["Devious", "Distractible", "Educated", "Embittered", "Envious", "Erudite"], |
||||
["Fanatical", "Forgetful", "Generous", "Hateful", "Honorable", "Humble"], |
||||
["Jaded", "Jovial", "Legalistic", "Manipulative", "Megalomaniac", "Melancholy"], |
||||
["Meticulous", "Mystical", "Obsessive", "Out of Touch", "Paranoid", "Polite"], |
||||
["Psychopathic", "Sophisticated", "Touchy", "Unimpressed", "Vain", "Xenophobic"] |
||||
], |
||||
"weakness": [ |
||||
["Bells", "Birdsong", "Children", "Cold", "Cold Iron", "Competition"], |
||||
["Conversation", "Deformity", "Flattery", "Flowers", "Gifts", "Gold"], |
||||
["Heat", "Holy Icon", "Holy Water", "Home Cooking", "EXTERNAL", "Mirrors"], |
||||
["Mistletoe", "Moonlight", "Music", "EXTERNAL", "Phylactery", "EXTERNAL"], |
||||
["Puzzles", "Riddles", "Rituals", "Silver", "Sunlight", "Tears"], |
||||
["True Name", "EXTERNAL", "Weak Spot", "EXTERNAL", "Wine", "Wormwood"] |
||||
] |
||||
} |
@ -0,0 +1,194 @@ |
||||
{ |
||||
"civilized_npcs": [ |
||||
["Acolyte","Actor","Apothecary","Baker","Barber","Blacksmith"], |
||||
["Brewer","Bureaucrat","Butcher","Carpenter","Clockmaker","Courier"], |
||||
["Courtier","Diplomat","Fishmonger","Guard","Haberdasher","Innkeeper"], |
||||
["Item-seller","Jeweler","Knight","Locksmith","Mason","Miller"], |
||||
["Musician","Noble","Painter","Priest","Scholar","Scribe"], |
||||
["Sculptor","Shipwright","Soldier","Tailor","Taxidermist","Wigmaker"] |
||||
], |
||||
"underworld_npcs": [ |
||||
["Alchemist","Beggar-prince","Blackmailer","Bounty-hunter","Chimney sweep","Coin-clipper"], |
||||
["Contortionist","Counterfeiter","Cultist","Cutpurse","Debt-collector","Deserter"], |
||||
["Fence","Fortuneteller","Galley slave","Gambler","Gravedigger","Headsman"], |
||||
["Hedge knight","Highwayman","Housebreaker","Kidnapper","Mad prophet","Mountebank"], |
||||
["Peddler","Pit-fighter","Poisoner","Rat-catcher","Scrivener","Sellsword"], |
||||
["Slave","Smuggler","Street performer","Tattooist","Urchin","Usurer"] |
||||
], |
||||
"wilderness_npcs": [ |
||||
["Apiarist","Bandit","Caravan Guard","Caravaneer","Druid","Exile"], |
||||
["Explorer","Farmer","Fisherman","Forager","Fugitive","Hedge wizard"], |
||||
["Hermit","Hunter","Messenger","Minstrel","Monk","Monster hunter"], |
||||
["Outlander","Tinker","Pilgrim","Poacher","Raider","Ranger"], |
||||
["Sage","Scavenger","Scout","Shepherd","Seer","Surveyor"], |
||||
["Tinker","Tomb raider","Trader","Trapper","Witch","Woodcutter"] |
||||
], |
||||
"female_names": [ |
||||
["Adelaide","Alma","Barsaba","Beatrix","Bianca","Cleopha"], |
||||
["Clover","Constance","Damaris","Daphne","Demona","Elsbeth"], |
||||
["Esme","Fern","Hester","Hippolyta","Jessamine","Jilly"], |
||||
["Morgot","Minerva","Nerissa","Odette","Olga","Orchid"], |
||||
["Pepper","Phoebe","Piety","Poppy","Silence","Sybil"], |
||||
["Trillby","Tuesday","Ursula","Vivian","Wendy","Zora"] |
||||
], |
||||
"male_names": [ |
||||
["Balthazar","Basil","Bertram","Blaxton","Chadwick","Clovis"], |
||||
["Destrian","Ellis","Erasmus","Faustus","Finn","Fitzhugh"], |
||||
["Florian","Fox","Godwin","Hannibal","Jasper","Jiles"], |
||||
["Jules","Leopold","Merrick","Mortimer","Ogden","Orion"], |
||||
["Oswald","Percival","Peregrine","Quentin","Redmaine","Reinhold"], |
||||
["Silas","Stilton","Stratford","Tenpiece","Waverly","Webster"] |
||||
], |
||||
"upper_class_surnames": [ |
||||
["Belvedere","Bithesea","Calaver","Carvolo","De Rippe","Droll"], |
||||
["Dunlow","Edevane","Erelong","Febland","Fernsby","Fisk"], |
||||
["Gastrell","Girdwood","Gorgon","Grimeson","Gruger","Hitheryon"], |
||||
["La Marque","Malmora","Miter","Oblington","Onymous","Phillifent"], |
||||
["Protendorfer","Romatet","Rothery","Shorbeck","Slora","Southark"], |
||||
["","","","","",""] |
||||
], |
||||
"lower_class_surnames": [ |
||||
["Barrow","Beetleman","Berrycloth","Birdwhistle","Bobich","Chips"], |
||||
["Coffin","Crumpling","Culpepper","Dankwork","Digworthy","Dreggs"], |
||||
["Gimble","Graveworm","Greelish","Hardwick","Hatman","Hovel"], |
||||
["Knibbs","Midnighter","Needle","Nethercoat","Pestle","Relish"], |
||||
["Rumbold","Rummage","Sallow","Saltmarsh","Silverless","Skitter"], |
||||
["Slee","Slitherly","Stoker","Tarwater","Tumbler","Villin"] |
||||
], |
||||
"assets": [ |
||||
["Authority","Avoids detection","Calls in favors","Charming","Cooks the books","Erases evidence"], |
||||
["Excellent liar","Extremely rich","EXTERNAL","EXTERNAL","Feared","Fortified base"], |
||||
["Gorgeous","Hears rumors","Huge family","Huge library","Impersonator","Interrogator"], |
||||
["Knows a guy","Knows a way in","Launder money","Learned","Local celebrity", "Local knowledge"], |
||||
["Loyal henchman","Middling oracle","Nothing to lose","Owns the guards","Powerful spouse","Procures gear"], |
||||
["Pulls the string","Secret lab","Sells contraband","Smuggles goods","Spy network","War hero"] |
||||
], |
||||
"liabilities": [ |
||||
["Addiction","Alcoholic","Corrupt ally","Coward","Decadent","Forbidden love"], |
||||
["Gambler","Glutton","Greedy","Heretic","Huge debts","Imposter"], |
||||
["EXTERNAL","Jealous","Leave evidence","Many enemies","Misinformed","Money trail"], |
||||
["Narcissist","Needs medicine","OCD","Paranoid","Partier", "Poor equipment"], |
||||
["Protective","Scandalous","Softhearted","Strict routines","Superstitious","Suspicious"], |
||||
["Temper","Trusting","Vulnerable base","Wanted","Weak-willed","Wildly despised"] |
||||
], |
||||
"npc_goals": [ |
||||
["A better life","Acceptance","EXTERNAL","EXTERNAL","EXTERNAL","EXTERNAL"], |
||||
["Enlightenment","Fame","EXTERNAL","Freedom","Glory","EXTERNAL"], |
||||
["Infamy","Infiltrate FACTION","Justice","EXTERNAL","EXTERNAL","Learning"], |
||||
["EXTERNAL","Love","Mastery","Power","Read location", "EXTERNAL"], |
||||
["Resolve dispute","EXTERNAL","Reveal a secret","Revenge","EXTERNAL","Serve a deity"], |
||||
["Serve evil","EXTERNAL","Serve ideology","Serve leader","Serve the needy","Wealth"] |
||||
], |
||||
"misfortunes": [ |
||||
["Abandoned","Addicted","Arrested","Blackmailed","Burgled","Challenged"], |
||||
["Condemned","Crippled","Cursed","Defrauded","Demoted","Depressed"], |
||||
["Discredited","Dismissed","Disowned","Exiled","Famished","Forgotten"], |
||||
["Framed","Haunted","Humiliated","Impoverished","Kidnapped", "Lost"], |
||||
["Mobbed","Mutilated","Overworked","Poisoned","Pursued","Rejected"], |
||||
["Replaced","Robbed","Sick","Sued","Suspected","Transformed"] |
||||
], |
||||
"missions": [ |
||||
["Apprehend","Assassinate","Blackmail","Burgle","Chart","Convince"], |
||||
["Deface","Defraud","Deliver","Destroy","Discredit","Escort"], |
||||
["Exfiltrate","Extort","Follow","Frame","Impersonate","Impress"], |
||||
["Infiltrate","Interrogate","Investigate","Kidnap","Locate", "Plant"], |
||||
["Protect","Raid","Replace","Retrieve","Rob","Ruin"], |
||||
["Sabotage","Smuggle","Surveil","Take Over","Terrorize","Threaten"] |
||||
], |
||||
"methods": [ |
||||
["Alchemy","Blackmail","Bluster","Bribery","Bullying","Bureaucracy"], |
||||
["Charm","Commerce","Cronies","Debate","Deceit","Deduction"], |
||||
["Eloquence","Espionage","Fast-talking","Favors","Hard Work","Humour"], |
||||
["Investigation","Legal maneuvers","Manipulation","Misdirection","Money","Nagging"], |
||||
["Negotiation","Persistence","Piety","Preparation","Quick Wit","Research"], |
||||
["Rumors","Sabotage","Teamwork","Theft","Threats","Violence"] |
||||
], |
||||
"appearances": [ |
||||
["Aquiline","Athletic","Barrel-Chested","Boney","Brawny","Brutish"], |
||||
["Bullnecked","Chiseled","Coltish","Corpulent","Craggy","Delicate"], |
||||
["Furrowed","Gaunt","Gorgeous","Grizzled","Haggard","Handsome"], |
||||
["Hideous","Lanky","Pudgy","Ripped","Rosy","Scrawny"], |
||||
["Sinewy","Slender","Slumped","Solid","Square-Jawed","Statuesque"], |
||||
["Towering","Trim","Weathered","Willowy","Wiry","Wrinkled"] |
||||
], |
||||
"physical_details": [ |
||||
["Acid scars","Battlescars","Birthmark","Braided hair","Brand mark","Broken nose"], |
||||
["Bronze skinned","Burn cars","Bushy eyebrows","Curly hair","Dark skinned","Dreadlocks"], |
||||
["Exotic accent","Flogging scars","Freckles","Gold tooth","Hoarse voice","Huge beard"], |
||||
["Long hair","Matted hair","Missing ear","Missing teeth","Mustache","Muttonchops"], |
||||
["Nine fingers","Oiled hair","One-eyed","Pale skinned","Piercings","Ritual scars"], |
||||
["Sallow skin","Shaved head","Sunburned","Tangled hair","Tattoos","Topknot"] |
||||
], |
||||
"clothing": [ |
||||
["Antique","Battle-torn","Bedraggled","Blood-stained","Ceremonial","Dated"], |
||||
["Decaying","Eccentric","Elegant","Embroidered","Exotic","Fashionable"], |
||||
["Flamboyant","Food-stained","Formal","Frayed","Frumpy","Garish"], |
||||
["Grimy","Haute couture","Lacey","Livery","Mud-stained","Ostentatious"], |
||||
["Oversized","Patched","Patterned","Perfumed","Practical","Rumpled"], |
||||
["Sigils","Singed","Tasteless","Undersized","Wine-stained","Worn out"] |
||||
], |
||||
"personalities": [ |
||||
["Antique","Battle-torn","Bedraggled","Blood-stained","Ceremonial","Dated"], |
||||
["Decaying","Eccentric","Elegant","Embroidered","Exotic","Fashionable"], |
||||
["Flamboyant","Food-stained","Formal","Frayed","Frumpy","Garish"], |
||||
["Grimy","Haute couture","Lacey","Livery","Mud-stained","Ostentatious"], |
||||
["Oversized","Patched","Patterned","Perfumed","Practical","Rumpled"], |
||||
["Sigils","Singed","Tasteless","Undersized","Wine-stained","Worn out"] |
||||
], |
||||
"mannerisms": [ |
||||
["Anecdotes","Breathy","Chuckles","Clipped","Cryptic","Deep voice"], |
||||
["Drawl","Enunciates","Flowery speech","Gravelly voice","Highly formal","Hypnotic"], |
||||
["Interrupts","Laconic","Laughs","Long pauses","Melodious","Monotone"], |
||||
["Mumbles","Narrates","Overly casual","Quaint sayings","Rambles","Random facts"], |
||||
["Rapid-fire","Rhyming","Robotic","Slow speech","Speechifies","Squeaky"], |
||||
["Street slang","Stutters","Talks to self","Trails off","Very loud","Whispers"] |
||||
], |
||||
"secrets": [ |
||||
["Addicted","Artificial","Assassin","Bankrupt","Beholden","Counterspy"], |
||||
["Cultist","Demigod","Evil lineage","Exile","Fence","Fugitive"], |
||||
["Ghost","Has a child","Heretic","High born","Huge fortune","Illusion"], |
||||
["Insurrectionist","Low born","Married","Mind-controlled","EXTERNAL","Monster hunter"], |
||||
["Non-human","EXTERNAL","Polygamist","Protects relic","Scandalous birth","Secret police"], |
||||
["Serial killer","Smuggler","Spy","Time traveler","Transformed","War criminal"] |
||||
], |
||||
"reputations": [ |
||||
["Ambitious","Authoritative","Boor","Borrower","Celebrity","Charitable"], |
||||
["Cheat","Dangerous","Entertainer","Gossip","Hardworking","Holy"], |
||||
["Honest","Hypochondriac","Idiot","Influential","Layabout","Leader"], |
||||
["Misanthrope","Miser","Neighborly","Nutjob","Obnoxious","Overeducated"], |
||||
["Partier","Pious","Proper","Prophet of doom","Repulsive","Respected"], |
||||
["Riffraff","Scandalous","Slime ball","Terrifying","Weirdo","Wise"] |
||||
], |
||||
"hobbies": [ |
||||
["Archaeology","Art collecting","Bad fiction","Calligraphy","Card games","Clockwork"], |
||||
["Collecting cats","Cuisine","Dark lore","Dog breeding","Embroidery","Exercise"], |
||||
["Falconry","Fashion","Fishing","Foreign cultures","Gardening","History"], |
||||
["Horseracing","Hunting","Instrument","Knitting","Lawn games","Mountaineering"], |
||||
["Opera","Painting","Poetry","Puzzle-solving","Riddling","Science"], |
||||
["Sculpture","Sketching","Smoking","Theater","Weaving","Whiskey"] |
||||
], |
||||
"relationships": [ |
||||
["Adviser","Blackmailer","Business partner","Business rival","Buyer","Captor"], |
||||
["Client","Confidant","Debtor","Disciple","Guardian","Henchman"], |
||||
["Idol","Informant","Master","Mentor","Nemesis","Offspring"], |
||||
["Parent","Patron","Political rival","Prisoner","Protégé","Quarry"], |
||||
["Right hand","Romantic rival","Servant","Sibling","Social rival","Spouse"], |
||||
["Stalker","Suitor","Supplicant","Supplier","Sweetheart","Unrequited love"] |
||||
], |
||||
"divine_domains": [ |
||||
["EXTERNAL","Balance","Betrayal","Chance","Chaos","Conquest"], |
||||
["Cycles","Death","Destiny","Dreams","EXTERNAL","Gateways"], |
||||
["Judgement","Love","Memory","Monsters","Moon","Motherhood"], |
||||
["EXTERNAL","Oaths","Order","Plague","Purification","Reason"], |
||||
["Schemes","Secrets","Storms","Summer","Sun","The Forge"], |
||||
["The Sea","The Wild","Time","Underworld","Wealth","Winter"] |
||||
], |
||||
"after_the_party": [ |
||||
["Absurd boasts","Adopted a child","Awarded medal","Bought the inn","Cursed","Duel scheduled"], |
||||
["Elected to office","Given a quest","Got married","In a coffin","In love","In the stocks"], |
||||
["Inconvenient pet","Insulted a noble","Insulted FACTION","Joined a cult","Letter of thanks","Lost"], |
||||
["Lost at gambling","Lost reputation","New identity","New tattoo","Poisoned","Recruited"], |
||||
["Robbed","Roof on fire","Shanghaied","Sick","Signed contract","Someone died"], |
||||
["Spilled secrets","Started a cult","Swindled","Thrown in jail","Unruly mob","Wrong clothes"] |
||||
] |
||||
} |
@ -0,0 +1,82 @@ |
||||
{ |
||||
"misc_items": [ |
||||
["Bowl","Brass bell","Brooch","Carved figurine","Cup","Deck of cards"], |
||||
["Drawing","Foreign coin","Game piece","Glass eye","Glass jar","Hair comb"], |
||||
["Handkerchief","Hinged box","Hourglass","Human tooth","Hunting horn","Loaded dice"], |
||||
["Long fork","Numbered key","Oil lamp","Old doll","Paint pot","Pencil"], |
||||
["Purse","Quill pen","Salve","Scissors","Scroll","Sealed letter"], |
||||
["Sewing needle","Shaving razor","Silver button","Skull","Tobacco pipe","Wine bottle"] |
||||
], |
||||
"worn_items": [ |
||||
["Belt","Blouse","Boots","Bracelet","Breastplate","Brigandine"], |
||||
["Cincture","Cloak","Coat","Dress","Earring","Eyepatch"], |
||||
["Gauntlets","Glove","Gown","Hat","Helmet","Hose"], |
||||
["Leather armor","Locket","Mail Shirt","Mask","Necklace","Padded armor"], |
||||
["Plate mail","Ring","Robe","Sandals","Scarf","Shirt"], |
||||
["Shoes","Skirt","Slippers","Socks","Trousers","Veil"] |
||||
], |
||||
"weapon_items": [ |
||||
["Arming sword","Backsword","Battleaxe","Blowpipe","Claymore","Club"], |
||||
["Crossbow","Cutlass","Dagger","Flail","Flanged mace","Glaive"], |
||||
["Halberd","Hammer","Hatchet","Horsebow","Hunting knife","Lance"], |
||||
["Longbow","Longsword","Mace","Maul","Morningstar","Pike"], |
||||
["Scimitar","Shortbow","Sickle","Sling","Spear","Staff"], |
||||
["Stake","Stiletto","Throwing axe","Warhammer","Warpick","Whip"] |
||||
], |
||||
"book_subjects": [ |
||||
["Alchemy","Art","Astrology","Blackmail","Charts & maps","Conspiracies"], |
||||
["Cookbook","Criminals","Divination","Etiquette","Fashion","Genealogy"], |
||||
["Hagiography","History","Journal","Language","Laws","Letters"], |
||||
["Lost empires","Lost places","Love poems","Monsters","Mythology","Odd customs"], |
||||
["Oratory","Propaganda","Prophecies","Siegecraft","Songs","State secrets"], |
||||
["Sword fighting","Theology","Treasures","War chronicle","Who's who","Witch-hunting"] |
||||
], |
||||
"tool_items": [ |
||||
["Acid flask","Bear trap","Bellows","Bolt-cutters","Chain","Chisel"], |
||||
["Crowbar","Door ram","Ear trumpet","Fire oil","Fishing hook","Goggles"], |
||||
["Grappling hook","Grease","Hacksaw","Hammer","Hand drill","Lantern"], |
||||
["Lens","Lock/key","Lockpicks","Manacles","Metal file","Mortar/pestle"], |
||||
["Needle","Pickaxe","Pitchfork","Pliers","Pole","Pulleys"], |
||||
["Rope","Scissors","Shovel","Spikes","Steel wire","Tongs"] |
||||
], |
||||
"potions": [ |
||||
["EXTERNAL","Body swap","Camouflage","Control animals","EXTERNAL","Cure affliction"], |
||||
["Detect evil","Detect gold","Detect hidden","Direction sense","EXTERNAL","EXTERNAL"], |
||||
["Extra arm","Flight","Ghost-speech","Heat vision","EXTERNAL","Invulnerable"], |
||||
["EXTERNAL","Magic immunity","Mirror image","EXTERNAL","EXTERNAL","EXTERNAL"], |
||||
["EXTERNAL","Night vision","EXTERNAL","Restore health","Speed","Stretchy"], |
||||
["Super-jump","Super-strength","Telekinesis","Tongues","Water-breathing","Water-walking"] |
||||
], |
||||
"magical_ingredients": [ |
||||
["Ancient liquor","EXTERNAL","Blind eye","Boiled cat","EXTERNAL","Bottled fog"], |
||||
["Coffin nail","Corpse's hair","Crossroad dust","Cultist entrails","EXTERNAL","Exotic spice"], |
||||
["Killer's hand","King's tooth","Last breath","Liar's tongue","Plant","Lodestone"], |
||||
["Monk's vow","EXTERNAL","Newborn's cry","Oil portrait","EXTERNAL","EXTERNAL"], |
||||
["EXTERNAL","Pyre ember","Queen bee","Queen's blood","Ship's barnacle","Star-metal"], |
||||
["Thief's finger","Tomb flower","EXTERNAL","Wedding ring","Widow's tears","Wizard skull"] |
||||
], |
||||
"treasure_items": [ |
||||
["Alchemy recipe","Amulet","Astrolabe","Blueprints","Calligraphy","Carpet"], |
||||
["Compass","Contract","Crown","Crystal","Deed","Embroidery"], |
||||
["Fine china","Fine liquor","Instrument","Magical book","Microscope","Music box"], |
||||
["Orrery","Painting","Perfume","Prayer book","Printing block","Rare textile"], |
||||
["Royal robes","Saint's relic","Scrimshaw","Sextant","Sheet music","Signet ring"], |
||||
["Silverware","Spices","Spyglass","Tapestry","Telescope","Treasure map"] |
||||
], |
||||
"treasure_traits": [ |
||||
["Altered","Ancient","Blessed","Bulky","Compact","Consumable"], |
||||
["Cultural value","Cursed","Damaged","Disguised","Draws enemies","EXTERNAL"], |
||||
["EXTERNAL","Embellished","Encoded","Exotic","Extra-planar","Famous"], |
||||
["Forbidden","Fragile","Heavy","Immovable","Impracticable","Indestructible"], |
||||
["Intelligent","Masterwork","Military value","Non-human","Owned","Partial"], |
||||
["Political value","Religious value","Repaired","Royal","Toxic","Vile"] |
||||
], |
||||
"valuable_materials": [ |
||||
["Alabaster","Amber","Aquamarine","Azurite","Beryl","Black Pearl"], |
||||
["Bloodstone","Bone China","Chalcedony","Cinnabar","Coral","Diamond"], |
||||
["Ebony", "Emerald", "Fire Agate","Garnet","Gold","Ivory"], |
||||
["Jade","Jasper","Jet","Lapis Lazuli","Malachite","Moonstone"], |
||||
["Onyx","Opal","Pearl","Platinum","Porcelain","Ruby"], |
||||
["Sapphire","Serpentine","Silver","Star Iron","Topaz","Turquoise"] |
||||
] |
||||
} |
@ -0,0 +1,98 @@ |
||||
{ |
||||
"wilderness_regions": [ |
||||
["Ashy","Badlands","Bay","Beach","Delta","Desert"], |
||||
["Dry lands","Dune sea","Dust bowl","Fjords","Flood lands","Foothills"], |
||||
["Forest","Glaciers","Heath","Highlands","Hills","Ice fields"], |
||||
["Jungle","Lowlands","Mesas","Moor","Mountains","Petrified forest"], |
||||
["Plains","Rainforest","Riverlands","Salt pan","Savanna","Steppe"], |
||||
["Taiga","Thickets","Tundra","Volcanic plain","Wetlands","Woodlands"] |
||||
], |
||||
"wilderness_landmarks": [ |
||||
["Bog","Boulder field","Butte","Cave","Cliff","Crag"], |
||||
["Crater","Creek","Crossing","Ditch","Field","Forest"], |
||||
["Grove","Hill","Hollow","Hot springs","Lair","Lake"], |
||||
["Lakebed","Marsh","Mesa","Moor","Pass","Pit"], |
||||
["Pond","Rapids","Ravine","Ridge","Rise","River"], |
||||
["Rockslide","Spring","Swamp","Thickets","Valley","Waterfall"] |
||||
], |
||||
"wilderness_structures": [ |
||||
["Altar","Aqueduct","Bandit’s camp","Battlefield","Bonfire","Bridge"], |
||||
["Cairn","Crossroads","Crypt","Dam","Dungeon","Farm"], |
||||
["Ford","Fortress","Gallows","Graveyard","Hedge","Hunter’s camp"], |
||||
["Inn","Lumber camp","Mine","Monastery","Monument","Orchard"], |
||||
["Outpost","Pasture","Ruin","Seclusion","Shack","Shrine"], |
||||
["Standing stone","Temple","Village","Wall","Watchtower","Waystone"] |
||||
], |
||||
"wilderness_region_traits": [ |
||||
["Ashen","Blasted","Blighted","Broken","Consuming","Corrupted"], |
||||
["Creeping","Desolate","EXTERNAL","Eternal","EXTERNAL","Forsaken"], |
||||
["Frozen","Haunted","Howling","Jagged","Lonely","Misty"], |
||||
["Perilous","Petrified","Phantasmal","Ravenous","Savage","Shadowy"], |
||||
["Shifting","Shivering","Sinister","Sinking","Smoldering","Sweltering"], |
||||
["Thorny","Thundering","Torrential","EXTERNAL","Wandering","Withered"] |
||||
], |
||||
"wilderness_discoveries": [ |
||||
["Blood stains","Bones","Broken weapons","Burrow","EXTERNAL","EXTERNAL"], |
||||
["Cut ropes","Dead animal","EXTERNAL","Food scraps","Grave marker","Human corpse"], |
||||
["EXTERNAL","EXTERNAL","Magical effect","Map","Message","Migration"], |
||||
["EXTERNAL","Nest","Portal","Resources","Rift","Strange plant"], |
||||
["EXTERNAL","Supplies","Torn flag","Tracks","Trap","Treasure cache"], |
||||
["EXTERNAL","EXTERNAL","EXTERNAL","EXTERNAL","EXTERNAL","Wizard fight"] |
||||
], |
||||
"wilderness_activities": [ |
||||
["Ambush","Argue","Birth","Build","Bury","Capture"], |
||||
["EXTERNAL","Convene","Demolish","Die","Duel","EXTERNAL"], |
||||
["Eat","Excavate","Feast","Felling","Fish","Flee"], |
||||
["Forage","Hunt","March","Raid","Rescue","Rest"], |
||||
["Sacrifice","Scout","Sing","Skin","Skirmish","Slay"], |
||||
["Sleep","Swim","Track","Trap","Wander","Worship"] |
||||
], |
||||
"wilderness_hazards": [ |
||||
["Avalanche","Blizzard","Brushfire","Cloudburst","Cyclone","Dense fog"], |
||||
["Downpour","Drizzle","Dust storm","Earthquake","Eruption","Flooding"], |
||||
["Forest fire","Hail","Heat wave","Hurricane","Ice storm","Light mist"], |
||||
["Locust swarm","Magma flow","Meteor strike","Monsoon","Mudflow","Mudslide"], |
||||
["Predator","Quicksand","Rain of frogs","Rockslide","Sandstorm","Sleet"], |
||||
["Snow","Stampede","Thunderstorm","Tsunami","Whirlpool","Windstorm"] |
||||
], |
||||
"edible_plants": [ |
||||
["Acorns","Apples","Asparagus","Blackberries","Blueberries","Carrots"], |
||||
["Cattail","Cherries","Chickweed","Chicory","Clover","Dandelion"], |
||||
["Dead-nettle","Elderberries","Fireweed","Gooseberries","Hazelnuts","Henbit"], |
||||
["Hickory nuts","Honeysuckle","Leeks","Milk thistle","Mint","Mulberries"], |
||||
["Mushrooms","Mustard","Onion","Pecans","Persimmons","Raspberries"], |
||||
["Strawberries","Walnuts","Watercress","Wild garlic","Wild grapes","Wood sorrel"] |
||||
], |
||||
"poisonous_plants": [ |
||||
["Angel’s trumpet","Baneberry","Belladona","Black truffle","Bleeding heart","Celandine"], |
||||
["Cocklebur","Columbine","Crowncup","Death cap","Dumbcane","Foxglove"], |
||||
["Hemlock","Hogweed","Holly","Horse chestnut","Hyacinth","Ivy"], |
||||
["Jessamine","Kudu","Larkspur","Mandrake","Mangrove","Mistletoe"], |
||||
["Moonflower","Nightshade","Oleander","Ragwort","Reindeer lichen","Snakeweed"], |
||||
["Spindle","Stinkhorn","Waxcap","Wine-Cap","Wolfsbane","Wormwood"] |
||||
], |
||||
"inn_adjectives": [ |
||||
["Bellowing","Blazing","Bleak","Blessed","Bloody","Crimson"], |
||||
["Cunning","Copper","Dancing","Dead","Drunken","Flying"], |
||||
["Ghastly","Golden","Helpful","Hideous","Howling","Hungry"], |
||||
["Moldy","Muttering","Nimble","Oozing","Petrified","Prancing"], |
||||
["Romantic","Salty","Singing","Shivering","Shrieking","Silver"], |
||||
["Smoking","Thirsty","Wicked","Tipsy","Whistling","Wanton"] |
||||
], |
||||
"inn_nouns": [ |
||||
["Axe","Barrel","Bear","Bell","Boot","Bowl"], |
||||
["Bucket","Candle","Cock","Cow","Dragon","Egg"], |
||||
["Elephant","Flea","Fork","Giant","Griffin","Hart"], |
||||
["Hog","Hound","Lamb","Lion","Mackerel","Maid"], |
||||
["Monk","Moon","Pipe","Prince","Rat","Skull"], |
||||
["Spoon","Star","Swan","Sword","Whale","Wife"] |
||||
], |
||||
"inn_quirks": [ |
||||
["100 years in past","Always night","Animal fights","Bard duels","Bigger inside","Black market"], |
||||
["Brand new","Cannibals","EXTERNAL","Constant party","Dancing contest","Dead drop"], |
||||
["EXTERNAL","Expensive","EXTERNAL","EXTERNAL","Famous chef","Fey patrons"], |
||||
["Fight club","Five floors","Ghost staff","Haunted","Hideout","EXTERNAL"], |
||||
["Magic sword","Magically moves","Mercs for hire","EXTERNAL","Preaching","Secure storage"], |
||||
["Staff are kids","Talking painting","Underground","VIP lounge","Voice in well","Women only"] |
||||
] |
||||
} |
@ -0,0 +1,104 @@ |
||||
package dice |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"math/rand" |
||||
"regexp" |
||||
"strconv" |
||||
"strings" |
||||
) |
||||
|
||||
type diceRequest struct { |
||||
count int |
||||
diceType int |
||||
} |
||||
|
||||
type DiceRoller interface { |
||||
Roll(request string) ([]int, error) |
||||
TableRoll() [2]int |
||||
} |
||||
|
||||
type Roller struct { |
||||
Rand *rand.Rand |
||||
Seed int64 |
||||
DiceRoller |
||||
} |
||||
|
||||
func NewRoller(seed int64) *Roller { |
||||
return &Roller{ |
||||
Rand: rand.New(rand.NewSource(seed)), |
||||
Seed: seed, |
||||
} |
||||
} |
||||
|
||||
// RollToJSON takes a []int and returns JSON with those ints in "results"
|
||||
func RollToJSON(rolls []int) ([]byte, error) { |
||||
result := struct { |
||||
Results []int `json:"results"` |
||||
}{ |
||||
Results: rolls, |
||||
} |
||||
|
||||
jsonResults, err := json.Marshal(result) |
||||
if err != nil { |
||||
return []byte{}, err |
||||
} |
||||
|
||||
return jsonResults, nil |
||||
} |
||||
|
||||
// RollToText takes a []int and returns them a spaced separated string
|
||||
func RollToText(rolls []int) string { |
||||
results := []string{} |
||||
for _, r := range rolls { |
||||
results = append(results, strconv.Itoa(r)) |
||||
} |
||||
response := strings.Join(results, " ") |
||||
response = response + "\n" |
||||
return response |
||||
} |
||||
|
||||
// Roll takes a string in the format of "XdY" and returns []int for its results
|
||||
func (r *Roller) Roll(request string) ([]int, error) { |
||||
var result []int |
||||
|
||||
diceRequest, err := parseRoll(request) |
||||
if err != nil { |
||||
return result, err |
||||
} |
||||
|
||||
for i := 1; i <= diceRequest.count; i++ { |
||||
result = append(result, r.Rand.Intn(diceRequest.diceType)+1) |
||||
} |
||||
|
||||
return result, nil |
||||
} |
||||
|
||||
// TableRoll returns a roll used for selecting an item on a Maze Rats table
|
||||
func (r *Roller) TableRoll() [2]int { |
||||
result, _ := r.Roll("2d6") |
||||
return [2]int{result[0], result[1]} |
||||
} |
||||
|
||||
func parseRoll(request string) (diceRequest, error) { |
||||
regexString := "[1-9][0-9]*d[1-9]+" |
||||
diceRegEx := regexp.MustCompile(regexString) |
||||
correctRequest := diceRegEx.Match([]byte(request)) |
||||
if !correctRequest { |
||||
errMsg := fmt.Sprintf("Must pass string matching '%v' "+ |
||||
"you passed '%v'", |
||||
regexString, request) |
||||
return diceRequest{}, errors.New(errMsg) |
||||
} |
||||
|
||||
var parsedRequest []string = strings.Split(request, "d") |
||||
count, _ := strconv.Atoi(parsedRequest[0]) |
||||
diceType, _ := strconv.Atoi(parsedRequest[1]) |
||||
|
||||
return diceRequest{ |
||||
count: count, |
||||
diceType: diceType, |
||||
}, nil |
||||
} |
@ -0,0 +1,52 @@ |
||||
package dice |
||||
|
||||
import ( |
||||
"errors" |
||||
"reflect" |
||||
"testing" |
||||
) |
||||
|
||||
func TestRoll(t *testing.T) { |
||||
roller := NewRoller(1) |
||||
result, err := roller.Roll("2d6") |
||||
if err != nil { |
||||
t.Error(err) |
||||
} |
||||
|
||||
if !reflect.DeepEqual(result, []int{6, 4}) { |
||||
t.Errorf("Expected roll to equal [6, 4], but got %#v", result) |
||||
} |
||||
} |
||||
|
||||
func TestRollToJSON(t *testing.T) { |
||||
r := NewRoller(1) |
||||
roll, _ := r.Roll("2d6") |
||||
result, err := RollToJSON(roll) |
||||
if err != nil { |
||||
t.Error(err) |
||||
} |
||||
expectedResult := `{"results":[6,4]}` |
||||
if !reflect.DeepEqual([]byte(expectedResult), result) { |
||||
t.Errorf("Expected '%v', but got '%v'", string(expectedResult), string(result)) |
||||
} |
||||
} |
||||
|
||||
func TestParseRoll(t *testing.T) { |
||||
_, err := parseRoll("1e6") |
||||
expectedMsg := "Must pass string matching '[1-9][0-9]*d[1-9]+' you passed '1e6'" |
||||
expectedError := errors.New(expectedMsg) |
||||
if err.Error() != expectedError.Error() { |
||||
t.Errorf("Expected error message: %v; got: %v", expectedError, err) |
||||
} |
||||
|
||||
result, err := parseRoll("2d10") |
||||
if err != nil { |
||||
t.Errorf("Expected 'parseRoll(\"2d10\")' to not error, got %v", err) |
||||
} |
||||
if result.count != 2 { |
||||
t.Errorf("Expected 'result.count' to equal '2'; got: %v", result.count) |
||||
} |
||||
if result.diceType != 10 { |
||||
t.Errorf("Expected 'result.count' to equal '10'; got: %v", result.count) |
||||
} |
||||
} |
@ -0,0 +1,41 @@ |
||||
package handlers |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/gorilla/mux" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/tables" |
||||
"net/http" |
||||
"strconv" |
||||
"time" |
||||
) |
||||
|
||||
// @Summary Generate a player character
|
||||
// @Tags character
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/generate/character [get]
|
||||
// @Success 200 {object} tables.Character
|
||||
func GenCharacter(w http.ResponseWriter, r *http.Request) { |
||||
t := tables.CharacterTable{Roller: dice.NewRoller(time.Now().UnixNano())} |
||||
WriteResponse(w, r, t.Generate(), t.Template()) |
||||
} |
||||
|
||||
// @Summary Generate a specific player character using a seed
|
||||
// @Tags character
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/character/{seed} [get]
|
||||
// @Param seed path int64 true "Int64"
|
||||
// @Success 200 {object} tables.Character
|
||||
func Character(w http.ResponseWriter, r *http.Request) { |
||||
vars := mux.Vars(r) |
||||
seed, err := strconv.ParseInt(vars["seed"], 10, 64) |
||||
if err != nil { |
||||
w.Write([]byte(fmt.Sprintf("Unable to parse '%v' as Int64", vars["seed"]))) |
||||
return |
||||
} |
||||
|
||||
t := tables.CharacterTable{Roller: dice.NewRoller(seed)} |
||||
WriteResponse(w, r, t.Generate(), t.Template()) |
||||
} |
@ -0,0 +1,41 @@ |
||||
package handlers |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/gorilla/mux" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/tables" |
||||
"net/http" |
||||
"strconv" |
||||
"time" |
||||
) |
||||
|
||||
// @Summary Generate a city
|
||||
// @Tags city
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/generate/city [get]
|
||||
// @Success 200 {object} tables.City
|
||||
func GenCity(w http.ResponseWriter, r *http.Request) { |
||||
t := tables.CityTable{Roller: dice.NewRoller((time.Now().UnixNano()))} |
||||
WriteResponse(w, r, t.Generate(), t.Template()) |
||||
} |
||||
|
||||
// @Summary Generate a specific city using a seed
|
||||
// @Tags city
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/city/{seed} [get]
|
||||
// @Param seed path int64 true "Int64"
|
||||
// @Success 200 {object} tables.City
|
||||
func City(w http.ResponseWriter, r *http.Request) { |
||||
vars := mux.Vars(r) |
||||
seed, err := strconv.ParseInt(vars["seed"], 10, 64) |
||||
if err != nil { |
||||
w.Write([]byte(fmt.Sprintf("Unable to parse '%v' as Int64", vars["seed"]))) |
||||
return |
||||
} |
||||
|
||||
t := tables.CityTable{Roller: dice.NewRoller(seed)} |
||||
WriteResponse(w, r, t.Generate(), t.Template()) |
||||
} |
@ -0,0 +1,31 @@ |
||||
package handlers |
||||
|
||||
import ( |
||||
"github.com/gorilla/mux" |
||||
"mazeratsgen/internal/dice" |
||||
"net/http" |
||||
"time" |
||||
) |
||||
|
||||
// @Summary Roll some dice
|
||||
// @Tags dice
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/roll/{xdy} [get]
|
||||
// @Param xdy path string true "Roll in xdy format (e.g. 1d6)"
|
||||
// @Success 200
|
||||
func Roll(w http.ResponseWriter, r *http.Request) { |
||||
vars := mux.Vars(r) |
||||
roller := dice.NewRoller(time.Now().UnixNano()) |
||||
response, err := roller.Roll(vars["xdy"]) |
||||
if err != nil { |
||||
w.WriteHeader(http.StatusInternalServerError) |
||||
// TODO: Return json error
|
||||
w.Write([]byte(err.Error())) |
||||
return |
||||
} |
||||
|
||||
template := "{{ range . }}{{ . }}\n{{end}}" |
||||
|
||||
WriteResponse(w, r, response, template) |
||||
} |
@ -0,0 +1,58 @@ |
||||
package handlers |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/gorilla/mux" |
||||
"mazeratsgen/internal/tables" |
||||
"net/http" |
||||
) |
||||
|
||||
func LoadHandlers(r *mux.Router) { |
||||
r.HandleFunc("/api/generate/name", GenName) |
||||
r.HandleFunc("/api/generate/spell", GenSpell) |
||||
|
||||
r.HandleFunc("/api/generate/monster", GenMonster) |
||||
r.HandleFunc("/api/monster/{seed}", Monster) |
||||
|
||||
r.HandleFunc("/api/generate/character", GenCharacter) |
||||
r.HandleFunc("/api/character/{seed}", Character) |
||||
|
||||
r.HandleFunc("/api/generate/city", GenCity) |
||||
r.HandleFunc("/api/city/{seed}", City) |
||||
|
||||
r.HandleFunc("/api/roll/{xdy}", Roll) |
||||
} |
||||
|
||||
func WriteResponse(w http.ResponseWriter, r *http.Request, i interface{}, t string) { |
||||
var response interface{} |
||||
var err error |
||||
if r.Header.Get("Accept") == "text/plain" { |
||||
w.Header().Set("Content-Type", "text/plain") |
||||
response, err = tables.ConvertToText(i, t) |
||||
if err != nil { |
||||
// TODO: Return json error
|
||||
w.WriteHeader(http.StatusInternalServerError) |
||||
w.Write([]byte(err.Error())) |
||||
return |
||||
} |
||||
} else { |
||||
w.Header().Set("Content-Type", "application/json") |
||||
response, err = tables.ConvertToJSON(i) |
||||
if err != nil { |
||||
// TODO: Return json error
|
||||
w.WriteHeader(http.StatusInternalServerError) |
||||
w.Write([]byte(err.Error())) |
||||
return |
||||
} |
||||
} |
||||
w.WriteHeader(http.StatusOK) |
||||
switch response.(type) { |
||||
case []byte: |
||||
w.Write(response.([]byte)) |
||||
case string: |
||||
w.Write([]byte(response.(string))) |
||||
default: |
||||
err := fmt.Sprintf("Error writing response, '%v' not handled", response) |
||||
w.Write([]byte(err)) |
||||
} |
||||
} |
@ -0,0 +1,41 @@ |
||||
package handlers |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/gorilla/mux" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/tables" |
||||
"net/http" |
||||
"strconv" |
||||
"time" |
||||
) |
||||
|
||||
// @Summary Generate a monster
|
||||
// @Tags monster
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/generate/monster [get]
|
||||
// @Success 200 {object} tables.Monster
|
||||
func GenMonster(w http.ResponseWriter, r *http.Request) { |
||||
t := tables.MonsterTable{Roller: dice.NewRoller(time.Now().UnixNano())} |
||||
WriteResponse(w, r, t.Generate(), t.Template()) |
||||
} |
||||
|
||||
// @Summary Generate a specific monster using a seed
|
||||
// @Tags monster
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/monster/{seed} [get]
|
||||
// @Param seed path int64 true "Int64"
|
||||
// @Success 200 {object} tables.Monster
|
||||
func Monster(w http.ResponseWriter, r *http.Request) { |
||||
vars := mux.Vars(r) |
||||
seed, err := strconv.ParseInt(vars["seed"], 10, 64) |
||||
if err != nil { |
||||
w.Write([]byte(fmt.Sprintf("Unable to parse '%v' as Int64", vars["seed"]))) |
||||
return |
||||
} |
||||
|
||||
t := tables.MonsterTable{Roller: dice.NewRoller(seed)} |
||||
WriteResponse(w, r, t.Generate(), t.Template()) |
||||
} |
@ -0,0 +1,20 @@ |
||||
package handlers |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/tables" |
||||
"net/http" |
||||
"strings" |
||||
"time" |
||||
) |
||||
|
||||
// @Summary Generate a character name
|
||||
// @Tags character
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/generate/name [get]
|
||||
// @Success 200
|
||||
func GenName(w http.ResponseWriter, r *http.Request) { |
||||
n := tables.GenRandomName(time.Now().UnixNano()) |
||||
template := strings.TrimSpace("{{.FullName}}") |
||||
WriteResponse(w, r, n, template) |
||||
} |
@ -0,0 +1,19 @@ |
||||
package handlers |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/tables" |
||||
"net/http" |
||||
"time" |
||||
) |
||||
|
||||
// @Summary Generate a spell
|
||||
// @Tags magic
|
||||
// @Produce application/json, text/plain
|
||||
// @Method GET
|
||||
// @Router /api/generate/spell [get]
|
||||
// @Success 200
|
||||
func GenSpell(w http.ResponseWriter, r *http.Request) { |
||||
t := tables.MagicTable{Roller: dice.NewRoller(time.Now().UnixNano())} |
||||
WriteResponse(w, r, t.Generate(), t.Template()) |
||||
} |
@ -0,0 +1,37 @@ |
||||
package helpers |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/dice" |
||||
"path" |
||||
"runtime" |
||||
) |
||||
|
||||
func LocalFile(filepath string) string { |
||||
_, thisFile, _, _ := runtime.Caller(1) |
||||
return path.Join(path.Dir(thisFile), filepath) |
||||
} |
||||
|
||||
type genFunc func([2]int) string |
||||
|
||||
func GenUniqueItems(total int, fn genFunc, seed int64) []string { |
||||
roller := dice.NewRoller(seed) |
||||
items := []string{} |
||||
|
||||
// Generate initial items
|
||||
for i := 0; i <= total; i++ { |
||||
items = append(items, fn(roller.TableRoll())) |
||||
} |
||||
|
||||
// Walk items and check if they match any other item. If they do then replace
|
||||
// it with a fresh item. This doesn't guarantee unique items, but prevents
|
||||
// Denial of Service attacks (a bit)
|
||||
for i, item := range items { |
||||
for x := 0; x < len(items); x++ { |
||||
if items[x] == item { |
||||
items[i] = fn(roller.TableRoll()) |
||||
break |
||||
} |
||||
} |
||||
} |
||||
return items |
||||
} |
@ -0,0 +1,164 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
data "mazeratsgen/internal/data" |
||||
dice "mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/helpers" |
||||
"strings" |
||||
) |
||||
|
||||
type CharacterTable struct { |
||||
Roller *dice.Roller |
||||
} |
||||
|
||||
// charAbilities holds values related to character stats
|
||||
type charAbilities struct { |
||||
STR int |
||||
DEX int |
||||
WIL int |
||||
} |
||||
|
||||
type CharacterStats struct { |
||||
MaxHealth int `json:"max_health"` |
||||
Armor int `json:"armor"` |
||||
STR int `json:"str"` |
||||
DEX int `json:"dex"` |
||||
WIL int `json:"wil"` |
||||
} |
||||
|
||||
type Character struct { |
||||
Name string `json:"name"` |
||||
Stats CharacterStats |
||||
Feature string `json:"feature"` |
||||
Weapons []string `json:"weapons"` |
||||
Items []string `json:"items"` |
||||
Appearance string `json:"appearance"` |
||||
PhysicalDetail string `json:"physical_detail"` |
||||
Background string `json:"background"` |
||||
Clothing string `json:"clothing"` |
||||
Personality string `json:"personality"` |
||||
Mannerism string `json:"mannerism"` |
||||
Seed int64 |
||||
} |
||||
|
||||
func (t *CharacterTable) Generate() Character { |
||||
abilityRoll, _ := t.Roller.Roll("1d6") |
||||
abilites := t.Abilities(abilityRoll[0]) |
||||
|
||||
classRoll, _ := t.Roller.Roll("1d2") |
||||
var class string |
||||
if classRoll[0] == 1 { |
||||
class = "Upperclass" |
||||
} else { |
||||
class = "Lowerclass" |
||||
} |
||||
|
||||
genderRoll, _ := t.Roller.Roll("1d2") |
||||
var gender string |
||||
if genderRoll[0] == 1 { |
||||
gender = "Male" |
||||
} else { |
||||
gender = "Female" |
||||
} |
||||
|
||||
result, _ := t.Roller.Roll("1d6") |
||||
featureRoll := result[0] |
||||
|
||||
return Character{ |
||||
Name: GenName(class, gender, t.Roller.Seed).FullName, |
||||
Stats: CharacterStats{ |
||||
Armor: 6, |
||||
MaxHealth: t.MaxHealth(), |
||||
STR: abilites.STR, |
||||
DEX: abilites.DEX, |
||||
WIL: abilites.WIL, |
||||
}, |
||||
Feature: t.Feat(featureRoll), |
||||
Weapons: helpers.GenUniqueItems(2, TreasureTable{Roller: t.Roller}.WeaponItem, t.Roller.Seed), |
||||
Items: helpers.GenUniqueItems(6, t.Item, t.Roller.Seed), |
||||
Appearance: t.Appearance(t.Roller.TableRoll()), |
||||
PhysicalDetail: t.PhysicalDetail(t.Roller.TableRoll()), |
||||
Background: t.Background(t.Roller.TableRoll()), |
||||
Clothing: t.Clothing(t.Roller.TableRoll()), |
||||
Personality: t.Personality(t.Roller.TableRoll()), |
||||
Mannerism: t.Mannerism(t.Roller.TableRoll()), |
||||
Seed: t.Roller.Seed, |
||||
} |
||||
} |
||||
|
||||
func (t CharacterTable) Template() string { |
||||
return strings.TrimSpace(` |
||||
Name: {{.Name}} |
||||
Feature: {{.Feature}} |
||||
Background: {{.Background}} |
||||
Stats: |
||||
Health: {{.Stats.MaxHealth}} |
||||
Armor: {{.Stats.Armor}} (+1 for shield, +1 for light armor, +2 for heavy armor) |
||||
STR: {{.Stats.STR}} (Used for raw power, stamina, or physical resilience) |
||||
DEX: {{.Stats.DEX}} (Used for speed, agility, or precision) |
||||
WIL: {{.Stats.WIL}} (Used for force of personality, perception, or willpower) |
||||
Appearance: {{.Appearance}} |
||||
Physical Detail: {{.PhysicalDetail}} |
||||
Clothing: {{.Clothing}} |
||||
Personality: {{.Personality}} |
||||
Mannerism: {{.Mannerism}} |
||||
Items: |
||||
{{- range $item := .Items }} |
||||
{{$item}} |
||||
{{- end}} |
||||
Seed: {{ .Seed }} |
||||
`) |
||||
} |
||||
|
||||
// GenAbilities will return a STR/DEX/WIL for a character
|
||||
func (t CharacterTable) Abilities(roll int) charAbilities { |
||||
stats := [6][3]int{ |
||||
[3]int{2, 1, 0}, |
||||
[3]int{2, 0, 1}, |
||||
[3]int{1, 2, 0}, |
||||
[3]int{0, 2, 1}, |
||||
[3]int{1, 0, 2}, |
||||
[3]int{0, 1, 2}, |
||||
} |
||||
|
||||
return charAbilities{ |
||||
STR: stats[roll-1][0], |
||||
DEX: stats[roll-1][1], |
||||
WIL: stats[roll-1][2], |
||||
} |
||||
} |
||||
|
||||
// GenMaxHealth is silly, it's always 4 for level 1 characters
|
||||
func (t CharacterTable) MaxHealth() int { return 4 } |
||||
|
||||
func (t CharacterTable) Feat(roll int) string { |
||||
return data.Tables.Character.Feat[roll-1] |
||||
} |
||||
|
||||
func (t CharacterTable) Appearance(roll [2]int) string { |
||||
return data.Tables.Character.Appearance[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t CharacterTable) Background(roll [2]int) string { |
||||
return data.Tables.Character.Background[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t CharacterTable) Clothing(roll [2]int) string { |
||||
return data.Tables.Character.Clothing[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t CharacterTable) Item(roll [2]int) string { |
||||
return data.Tables.Character.Items[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t CharacterTable) Personality(roll [2]int) string { |
||||
return data.Tables.Character.Personality[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t CharacterTable) PhysicalDetail(roll [2]int) string { |
||||
return data.Tables.Character.PhysicalDetail[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t CharacterTable) Mannerism(roll [2]int) string { |
||||
return data.Tables.Character.Mannerism[roll[0]-1][roll[1]-1] |
||||
} |
@ -0,0 +1,81 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"reflect" |
||||
"strings" |
||||
"testing" |
||||
) |
||||
|
||||
func TestGenCharacter(t *testing.T) { |
||||
t.Parallel() |
||||
char := GenCharacter(1) |
||||
tests := []struct { |
||||
field string |
||||
actual interface{} |
||||
expected interface{} |
||||
}{ |
||||
{field: "Name", actual: char.Name, expected: "Vivian Villin"}, |
||||
{field: "Stats.MaxHealth", actual: char.Stats.MaxHealth, expected: 4}, |
||||
{field: "Stats.Armor", actual: char.Stats.Armor, expected: 6}, |
||||
{field: "Stats.STR", actual: char.Stats.STR, expected: 0}, |
||||
{field: "Stats.DEX", actual: char.Stats.DEX, expected: 1}, |
||||
{field: "Stats.WIL", actual: char.Stats.WIL, expected: 2}, |
||||
{field: "Feature", actual: char.Feature, expected: "Shadowjack (Advantage on moving silently or hiding in shadows)"}, |
||||
{field: "Weapons", actual: char.Weapons, expected: []string{"Warhammer", "Whip"}}, |
||||
{field: "Items", actual: char.Items, expected: []string{"Vial of Acid", "Waterskin", "Chisel", "Fishing Net", "Metal file", "Hacksaw"}}, |
||||
{field: "Appearance", actual: char.Appearance, expected: "Bullnecked"}, |
||||
{field: "PhysicalDetail", actual: char.PhysicalDetail, expected: "Bushy eyebrows"}, |
||||
{field: "Background", actual: char.Background, expected: "Peddler"}, |
||||
{field: "Clothing", actual: char.Clothing, expected: "Food-stained"}, |
||||
{field: "Personality", actual: char.Personality, expected: "Cowardly"}, |
||||
{field: "Mannerism:", actual: char.Mannerism, expected: "Robotic"}, |
||||
} |
||||
for _, sTest := range tests { |
||||
// https://github.com/golang/go/wiki/CommonMistakes#using-reference-to-loop-iterator-variable
|
||||
sTest := sTest |
||||
|
||||
t.Run("Character."+sTest.field, func(t *testing.T) { |
||||
t.Parallel() |
||||
if !reflect.DeepEqual(sTest.actual, sTest.expected) { |
||||
t.Errorf("Expected %#v to equal %#v", sTest.actual, sTest.expected) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
var expectedText = strings.TrimSpace(` |
||||
Name: Vivian Villin |
||||
Feature: Shadowjack (Advantage on moving silently or hiding in shadows) |
||||
Background: Peddler |
||||
Stats: |
||||
Health: 4 |
||||
Armor: 6 (+1 for shield, +1 for light armor, +2 for heavy armor) |
||||
STR: 0 (Used for raw power, stamina, or physical resilience) |
||||
DEX: 1 (Used for speed, agility, or precision) |
||||
WIL: 2 (Used for force of personality, perception, or willpower) |
||||
Appearance: Bullnecked |
||||
Physical Detail: Bushy eyebrows |
||||
Clothing: Food-stained |
||||
Personality: Cowardly |
||||
Mannerism: Robotic |
||||
Items: |
||||
Vial of Acid |
||||
Waterskin |
||||
Chisel |
||||
Fishing Net |
||||
Metal file |
||||
Hacksaw |
||||
`) |
||||
|
||||
func TestCharacterToText(t *testing.T) { |
||||
t.Parallel() |
||||
char := GenCharacter(1) |
||||
result, err := CharacterToText(char) |
||||
if err != nil { |
||||
t.Error(err) |
||||
} |
||||
|
||||
if result != expectedText { |
||||
t.Errorf("Exected following to be equal:\n%#v\n%#v", result, expectedText) |
||||
} |
||||
} |
@ -0,0 +1,274 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/data" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/helpers" |
||||
"strings" |
||||
) |
||||
|
||||
type CityTable struct { |
||||
Roller *dice.Roller |
||||
} |
||||
|
||||
type Building struct { |
||||
Type string |
||||
Rooms []string |
||||
TacticalFeature string |
||||
} |
||||
|
||||
type Faction struct { |
||||
Type string |
||||
Trait string |
||||
Goal string |
||||
} |
||||
|
||||
type City struct { |
||||
Theme string |
||||
Events []string |
||||
DistrictThemes []string |
||||
Activities []string |
||||
TacticalStreetFeatures []string |
||||
UpperClassBuildings []Building |
||||
LowerClassBuildings []Building |
||||
Factions []Faction |
||||
Seed int64 |
||||
} |
||||
|
||||
func (t *CityTable) Generate() City { |
||||
upperClassBuildings := []Building{} |
||||
|
||||
// Future Jerry...the weird for loops here are to add noise to seed
|
||||
// This will break if more than 6 rooms are needed
|
||||
|
||||
for i := 0; i < 3; i++ { |
||||
tempRoller := dice.NewRoller(t.Roller.Seed + int64(i)) |
||||
tempTable := CityTable{Roller: tempRoller} |
||||
upperClassBuildings = append(upperClassBuildings, tempTable.UpperClassBuilding(tempRoller.TableRoll())) |
||||
} |
||||
|
||||
lowerClassBuildings := []Building{} |
||||
for i := 4; i < 7; i++ { |
||||
tempRoller := dice.NewRoller(t.Roller.Seed + int64(i)) |
||||
tempTable := CityTable{Roller: tempRoller} |
||||
lowerClassBuildings = append(lowerClassBuildings, tempTable.LowerClassBuilding(tempRoller.TableRoll())) |
||||
} |
||||
|
||||
return City{ |
||||
Theme: t.CityTheme(t.Roller.TableRoll()), |
||||
Events: helpers.GenUniqueItems(3, t.CityEvent, t.Roller.Seed), |
||||
DistrictThemes: helpers.GenUniqueItems(3, t.DistrictTheme, t.Roller.Seed), |
||||
UpperClassBuildings: upperClassBuildings, |
||||
LowerClassBuildings: lowerClassBuildings, |
||||
Activities: helpers.GenUniqueItems(3, t.CityActivity, t.Roller.Seed), |
||||
TacticalStreetFeatures: helpers.GenUniqueItems(3, t.TacticalStreetFeature, t.Roller.Seed), |
||||
Factions: []Faction{ |
||||
t.GenFaction(t.Roller.TableRoll()), |
||||
t.GenFaction(t.Roller.TableRoll()), |
||||
}, |
||||
Seed: t.Roller.Seed, |
||||
} |
||||
} |
||||
|
||||
func (t *CityTable) Template() string { |
||||
return strings.TrimSpace(` |
||||
Theme: {{.Theme}} |
||||
Events: |
||||
{{- range $event := .Events}} |
||||
{{$event}} |
||||
{{- end}} |
||||
District Themes: |
||||
{{- range $theme := .DistrictThemes}} |
||||
{{$theme}} |
||||
{{- end}} |
||||
Upper Class Buildings: |
||||
{{- range $building := .UpperClassBuildings}} |
||||
{{$building.Type}}: |
||||
Tactical Feature: {{$building.TacticalFeature}} |
||||
Rooms: |
||||
{{- range $room := $building.Rooms}} |
||||
{{$room}} |
||||
{{- end}} |
||||
{{- end}} |
||||
Lower Class Buildings: |
||||
{{- range $building := .LowerClassBuildings}} |
||||
{{$building.Type}}: |
||||
Tactical Feature: {{$building.TacticalFeature}} |
||||
Rooms: |
||||
{{- range $room := $building.Rooms}} |
||||
{{$room}} |
||||
{{- end}} |
||||
{{- end}} |
||||
Activities: |
||||
{{- range $activity := .Activities }} |
||||
{{$activity}} |
||||
{{- end}} |
||||
Tactical Street Features: |
||||
{{- range $feature := .TacticalStreetFeatures }} |
||||
{{$feature}} |
||||
{{- end}} |
||||
Factions: |
||||
{{- range $faction := .Factions }} |
||||
{{$faction.Type}}: |
||||
Trait: {{$faction.Trait}} |
||||
Goal: {{$faction.Goal}} |
||||
{{- end}} |
||||
Seed: {{.Seed}} |
||||
`) |
||||
} |
||||
|
||||
func (t *CityTable) CityTheme(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{1, 1}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return MonsterTable{Roller: t.Roller}.Base(roll[0]) |
||||
case [2]int{2, 1}: |
||||
return t.CityActivity(t.Roller.TableRoll()) |
||||
case [2]int{2, 2}: |
||||
return t.CityEvent(t.Roller.TableRoll()) |
||||
case [2]int{2, 5}: |
||||
return t.DistrictTheme(t.Roller.TableRoll()) |
||||
case [2]int{2, 6}: |
||||
return NPCTable{Roller: t.Roller}.DivineDomain(t.Roller.TableRoll()) |
||||
case [2]int{3, 1}: |
||||
return t.GenFaction(t.Roller.TableRoll()).Type |
||||
case [2]int{3, 5}: |
||||
return t.LowerClassBuilding(t.Roller.TableRoll()).Type |
||||
case [2]int{4, 2}: |
||||
return "Pick an existing NPC" |
||||
case [2]int{4, 4}: |
||||
return MagicTable{Roller: t.Roller}.PhysicalElement(t.Roller.TableRoll()) |
||||
case [2]int{6, 4}: |
||||
return t.UpperClassBuilding(t.Roller.TableRoll()).Type |
||||
default: |
||||
return data.Tables.City.CityThemes[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t *CityTable) CityEvent(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{1, 4}: |
||||
return t.GenFaction(t.Roller.TableRoll()).Type |
||||
default: |
||||
return data.Tables.City.CityEvents[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t *CityTable) DistrictTheme(roll [2]int) string { |
||||
npcTable := NPCTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{1, 2}: |
||||
return npcTable.CivilizedNPC(t.Roller.TableRoll()) |
||||
case [2]int{4, 1}: |
||||
return t.LowerClassBuilding(t.Roller.TableRoll()).Type |
||||
case [2]int{6, 1}: |
||||
return npcTable.UnderworldNPC(t.Roller.TableRoll()) |
||||
case [2]int{6, 2}: |
||||
return t.UpperClassBuilding(t.Roller.TableRoll()).Type |
||||
case [2]int{6, 4}: |
||||
return npcTable.WildernessNPC(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.City.DistrictThemes[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) GenBuilding(roll int) Building { |
||||
if roll <= 3 { |
||||
return t.LowerClassBuilding(t.Roller.TableRoll()) |
||||
} |
||||
return t.UpperClassBuilding(t.Roller.TableRoll()) |
||||
} |
||||
|
||||
func (t CityTable) UpperClassBuilding(roll [2]int) Building { |
||||
return Building{ |
||||
Type: data.Tables.City.UpperClassBuildings[roll[0]-1][roll[1]-1], |
||||
TacticalFeature: t.TacticalBuildingFeature(t.Roller.TableRoll()), |
||||
Rooms: helpers.GenUniqueItems(3, t.BuildingRoom, t.Roller.Seed), |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) LowerClassBuilding(roll [2]int) Building { |
||||
return Building{ |
||||
Type: data.Tables.City.LowerClassBuildings[roll[0]-1][roll[1]-1], |
||||
TacticalFeature: t.TacticalBuildingFeature(t.Roller.TableRoll()), |
||||
Rooms: helpers.GenUniqueItems(3, t.BuildingRoom, t.Roller.Seed), |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) BuildingRoom(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{3, 1}: |
||||
return MazeTable{Roller: t.Roller}.DungeonRoom(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.City.BuildingRooms[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) TacticalStreetFeature(roll [2]int) string { |
||||
mazeTable := MazeTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{2, 3}: |
||||
return t.CityActivity(t.Roller.TableRoll()) |
||||
case [2]int{3, 4}: |
||||
return mazeTable.DungeonActivity(t.Roller.TableRoll()) |
||||
case [2]int{6, 6}: |
||||
return WildTable{Roller: t.Roller}.WildernessActivity(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.City.TacticalStreetFeatures[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) TacticalBuildingFeature(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{1, 1}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return MonsterTable{Roller: t.Roller}.Base(roll[0]) + "Nests" |
||||
default: |
||||
return data.Tables.City.TacticalBuildingFeatures[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) FactionTrait(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{4, 4}: |
||||
return NPCTable{Roller: t.Roller}.Personality(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.City.FactionTraits[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) GenFaction(roll [2]int) Faction { |
||||
return Faction{ |
||||
Type: data.Tables.City.Factions[roll[0]-1][roll[1]-1], |
||||
Trait: t.FactionTrait(t.Roller.TableRoll()), |
||||
Goal: t.FactionGoal(t.Roller.TableRoll()), |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) FactionGoal(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{1, 6}: |
||||
return "Control " + t.GenFaction(t.Roller.TableRoll()).Type |
||||
case [2]int{2, 3}: |
||||
return "Kill a specific monster" |
||||
case [2]int{2, 4}: |
||||
return "Defeat " + t.GenFaction(t.Roller.TableRoll()).Type |
||||
case [2]int{4, 4}: |
||||
return "Infiltrate " + t.GenFaction(t.Roller.TableRoll()).Type |
||||
default: |
||||
return data.Tables.City.FactionGoals[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t CityTable) CityActivity(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{2, 5}: |
||||
return MazeTable{Roller: t.Roller}.DungeonActivity(t.Roller.TableRoll()) |
||||
case [2]int{4, 2}: |
||||
return NPCTable{Roller: t.Roller}.Mission(t.Roller.TableRoll()) |
||||
case [2]int{6, 6}: |
||||
return WildTable{Roller: t.Roller}.WildernessActivity(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.City.CityActivities[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
@ -0,0 +1,23 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/dice" |
||||
"testing" |
||||
) |
||||
|
||||
func TestCityTableGenMethods(t *testing.T) { |
||||
roller := dice.NewRoller(1) |
||||
table := CityTable{Roller: roller} |
||||
table.CityTheme(roller.TableRoll()) |
||||
table.CityEvent(roller.TableRoll()) |
||||
table.DistrictTheme(roller.TableRoll()) |
||||
table.UpperClassBuilding(roller.TableRoll()) |
||||
table.LowerClassBuilding(roller.TableRoll()) |
||||
table.CityActivity(roller.TableRoll()) |
||||
table.BuildingRoom(roller.TableRoll()) |
||||
table.TacticalStreetFeature(roller.TableRoll()) |
||||
table.TacticalBuildingFeature(roller.TableRoll()) |
||||
table.GenFaction(roller.TableRoll()) |
||||
table.FactionTrait(roller.TableRoll()) |
||||
table.FactionGoal(roller.TableRoll()) |
||||
} |
@ -0,0 +1,154 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/data" |
||||
"mazeratsgen/internal/dice" |
||||
) |
||||
|
||||
type MagicTable struct { |
||||
Roller *dice.Roller |
||||
} |
||||
|
||||
func (t MagicTable) Generate() interface{} { |
||||
return t.Spell(t.Roller.TableRoll()) |
||||
} |
||||
|
||||
func (t MagicTable) Template() string { |
||||
return "{{ . }}" |
||||
} |
||||
|
||||
func (t MagicTable) Spell(roll [2]int) string { |
||||
switch roll[0] { |
||||
case 1: |
||||
if roll[1] <= 3 { |
||||
return t.PhysicalEffect(t.Roller.TableRoll()) + " " + t.PhysicalForm(t.Roller.TableRoll()) |
||||
} |
||||
return t.EtherealElement(t.Roller.TableRoll()) + " " + t.PhysicalForm(t.Roller.TableRoll()) |
||||
case 2: |
||||
if roll[1] <= 3 { |
||||
return t.PhysicalEffect(t.Roller.TableRoll()) + " " + t.EtherealForm(t.Roller.TableRoll()) |
||||
} |
||||
return t.EtherealElement(t.Roller.TableRoll()) + " " + t.EtherealForm(t.Roller.TableRoll()) |
||||
case 3: |
||||
if roll[1] <= 3 { |
||||
return t.EtherealEffect(t.Roller.TableRoll()) + " " + t.PhysicalForm(t.Roller.TableRoll()) |
||||
} |
||||
return t.PhysicalEffect(t.Roller.TableRoll()) + " " + t.EtherealElement(t.Roller.TableRoll()) |
||||
case 4: |
||||
if roll[1] <= 3 { |
||||
return t.EtherealEffect(t.Roller.TableRoll()) + " " + t.EtherealForm(t.Roller.TableRoll()) |
||||
} |
||||
return t.PhysicalEffect(t.Roller.TableRoll()) + " " + t.EtherealElement(t.Roller.TableRoll()) |
||||
case 5: |
||||
if roll[1] <= 3 { |
||||
return t.PhysicalElement(t.Roller.TableRoll()) + " " + t.PhysicalForm(t.Roller.TableRoll()) |
||||
} |
||||
return t.EtherealEffect(t.Roller.TableRoll()) + " " + t.PhysicalElement(t.Roller.TableRoll()) |
||||
default: |
||||
if roll[1] <= 3 { |
||||
return t.PhysicalElement(t.Roller.TableRoll()) + " " + t.EtherealForm(t.Roller.TableRoll()) |
||||
} |
||||
return t.EtherealEffect(t.Roller.TableRoll()) + " " + t.EtherealElement(t.Roller.TableRoll()) |
||||
} |
||||
} |
||||
|
||||
func (t MagicTable) Element(roll int) string { |
||||
if roll <= 3 { |
||||
return t.PhysicalElement(t.Roller.TableRoll()) |
||||
} |
||||
return t.EtherealElement(t.Roller.TableRoll()) |
||||
} |
||||
|
||||
func (t MagicTable) Effect(roll int) string { |
||||
if roll <= 3 { |
||||
return t.PhysicalEffect(t.Roller.TableRoll()) |
||||
} |
||||
return t.EtherealEffect(t.Roller.TableRoll()) |
||||
} |
||||
|
||||
func (t MagicTable) PhysicalEffect(roll [2]int) string { |
||||
return data.Tables.Magic.PhysicalEffects[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MagicTable) PhysicalElement(roll [2]int) string { |
||||
return data.Tables.Magic.PhysicalElements[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MagicTable) PhysicalForm(roll [2]int) string { |
||||
return data.Tables.Magic.PhysicalForms[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MagicTable) EtherealEffect(roll [2]int) string { |
||||
return data.Tables.Magic.EtherealEffects[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MagicTable) EtherealElement(roll [2]int) string { |
||||
return data.Tables.Magic.EtherealElements[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MagicTable) EtherealForm(roll [2]int) string { |
||||
return data.Tables.Magic.EtherealForms[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MagicTable) Mutation(roll [2]int) string { |
||||
monTable := MonsterTable{Roller: t.Roller} |
||||
baseRoll, _ := t.Roller.Roll("1d6") |
||||
switch roll { |
||||
case [2]int{1, 6}: |
||||
return monTable.Base(baseRoll[0]) + " Arms" |
||||
case [2]int{2, 1}: |
||||
return monTable.Base(baseRoll[0]) + " Eyes" |
||||
case [2]int{2, 2}: |
||||
return monTable.Base(baseRoll[0]) + " Head" |
||||
case [2]int{2, 3}: |
||||
return monTable.Base(baseRoll[0]) + " Legs" |
||||
case [2]int{2, 4}: |
||||
return monTable.Base(baseRoll[0]) + " Mouth" |
||||
case [2]int{2, 5}: |
||||
return monTable.Base(baseRoll[0]) + " Skin" |
||||
case [2]int{2, 6}: |
||||
return monTable.Base(baseRoll[0]) + " Form" |
||||
case [2]int{4, 2}: |
||||
return TreasureTable{Roller: t.Roller}.TreasureItem(t.Roller.TableRoll()) + " Form" |
||||
case [2]int{4, 6}: |
||||
return monTable.Feature(t.Roller.TableRoll()) |
||||
case [2]int{5, 1}: |
||||
return monTable.Trait(t.Roller.TableRoll()) |
||||
case [2]int{5, 4}: |
||||
return t.PhysicalElement(t.Roller.TableRoll()) + " Skin" |
||||
default: |
||||
return data.Tables.Magic.Mutations[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t MagicTable) Insanity(roll [2]int) string { |
||||
monTable := MonsterTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{1, 3}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return monTable.Base(roll[0]) + " Form" |
||||
case [2]int{5, 6}: |
||||
return monTable.Ability(t.Roller.TableRoll()) |
||||
case [2]int{6, 1}: |
||||
return monTable.Feature(t.Roller.TableRoll()) |
||||
case [2]int{6, 2}: |
||||
return monTable.Trait(t.Roller.TableRoll()) |
||||
case [2]int{6, 4}: |
||||
return NPCTable{Roller: t.Roller}.Personality(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.Magic.Insanities[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t MagicTable) Catastrophe(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{1, 3}: |
||||
return "Animials " + t.Mutation(t.Roller.TableRoll()) |
||||
case [2]int{4, 1}: |
||||
return "Mass " + t.Insanity(t.Roller.TableRoll()) |
||||
case [2]int{4, 2}: |
||||
return "Mass " + t.Mutation(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.Magic.Catastrophes[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/dice" |
||||
. "mazeratsgen/test/helpers" |
||||
"testing" |
||||
) |
||||
|
||||
// TODO: Split out methods here
|
||||
func TestGenMethods(t *testing.T) { |
||||
roller := dice.NewRoller(1) |
||||
table := MagicTable{Roller: roller} |
||||
table.PhysicalEffect(roller.TableRoll()) |
||||
table.PhysicalElement(roller.TableRoll()) |
||||
table.PhysicalForm(roller.TableRoll()) |
||||
table.Element(roller.TableRoll()[0]) // Oh no an extra dice roll (/s)
|
||||
table.EtherealEffect(roller.TableRoll()) |
||||
table.EtherealElement(roller.TableRoll()) |
||||
table.EtherealForm(roller.TableRoll()) |
||||
table.Mutation(roller.TableRoll()) |
||||
table.Insanity(roller.TableRoll()) |
||||
table.Catastrophe(roller.TableRoll()) |
||||
table.Spell(roller.TableRoll()) |
||||
} |
||||
|
||||
func TestExactMethods(t *testing.T) { |
||||
roller := dice.NewRoller(1) |
||||
table := MagicTable{Roller: roller} |
||||
ExactItem(table.EtherealForm([2]int{1, 3}), "Beam", t) |
||||
RegexItem(table.Mutation([2]int{1, 6}), ".*Arms$", t) |
||||
RegexItem(table.Mutation([2]int{2, 1}), ".*Eyes$", t) |
||||
RegexItem(table.Mutation([2]int{2, 2}), ".*Head$", t) |
||||
RegexItem(table.Mutation([2]int{2, 3}), ".*Legs$", t) |
||||
RegexItem(table.Mutation([2]int{2, 4}), ".*Mouth$", t) |
||||
RegexItem(table.Mutation([2]int{2, 5}), ".*Skin$", t) |
||||
RegexItem(table.Mutation([2]int{2, 6}), ".* Form$", t) |
||||
// TODO: Finish specific items
|
||||
} |
||||
|
||||
func TestGenSpell(t *testing.T) { |
||||
roller := dice.NewRoller(1) |
||||
table := MagicTable{Roller: roller} |
||||
for x := 1; x <= 5; x++ { |
||||
for y := 1; y <= 5; y++ { |
||||
table.Spell([2]int{x, y}) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,174 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/data" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/helpers" |
||||
) |
||||
|
||||
type MazeTable struct { |
||||
Roller *dice.Roller |
||||
} |
||||
|
||||
type Room struct { |
||||
Type string |
||||
Detail string |
||||
} |
||||
|
||||
type Maze struct { |
||||
Form string |
||||
Entrance string |
||||
Layout string |
||||
Ruination string |
||||
Reward string |
||||
Activities []string |
||||
Rooms []Room |
||||
Tricks []string |
||||
Hazards []string |
||||
TrapEffects []string |
||||
TrapTriggers []string |
||||
} |
||||
|
||||
func GenMaze(seed int64) Maze { |
||||
roller := dice.NewRoller(seed) |
||||
mazeTable := MazeTable{Roller: roller} |
||||
|
||||
total_rooms := 5 |
||||
roomTypes := helpers.GenUniqueItems(total_rooms, mazeTable.DungeonRoom, seed) |
||||
roomDetails := helpers.GenUniqueItems(total_rooms, mazeTable.DungeonRoomDetail, seed) |
||||
rooms := []Room{} |
||||
for i := 0; i < total_rooms; i++ { |
||||
room := Room{ |
||||
Type: roomTypes[i], |
||||
Detail: roomDetails[i], |
||||
} |
||||
rooms = append(rooms, room) |
||||
} |
||||
return Maze{ |
||||
Form: mazeTable.DungeonForm(roller.TableRoll()), |
||||
Entrance: mazeTable.DungeonEntrance(roller.TableRoll()), |
||||
Layout: mazeTable.DungeonLayout(roller.TableRoll()), |
||||
Ruination: mazeTable.DungeonRuination(roller.TableRoll()), |
||||
Reward: mazeTable.DungeonReward(roller.TableRoll()), |
||||
Activities: helpers.GenUniqueItems(5, mazeTable.DungeonActivity, seed), |
||||
Rooms: rooms, |
||||
Hazards: helpers.GenUniqueItems(5, mazeTable.DungeonHazard, seed), |
||||
Tricks: helpers.GenUniqueItems(5, mazeTable.DungeonTrick, seed), |
||||
TrapEffects: helpers.GenUniqueItems(5, mazeTable.TrapEffect, seed), |
||||
TrapTriggers: helpers.GenUniqueItems(5, mazeTable.TrapTrigger, seed), |
||||
} |
||||
} |
||||
|
||||
func (t MazeTable) DungeonEntrance(roll [2]int) string { |
||||
roll[0], roll[1] = roll[0]-1, roll[0]-1 |
||||
return data.Tables.Maze.DungeonEntrances[roll[0]][roll[1]] |
||||
} |
||||
|
||||
func (t MazeTable) DungeonForm(roll [2]int) string { |
||||
cityTable := CityTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{2, 1}: |
||||
return cityTable.BuildingRoom(t.Roller.TableRoll()) |
||||
case [2]int{2, 6}: |
||||
return t.DungeonRoom(t.Roller.TableRoll()) |
||||
case [2]int{3, 5}: |
||||
return cityTable.LowerClassBuilding(t.Roller.TableRoll()).Type |
||||
case [2]int{6, 3}: |
||||
return cityTable.UpperClassBuilding(t.Roller.TableRoll()).Type |
||||
} |
||||
return data.Tables.Maze.DungeonForms[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MazeTable) DungeonLayout(roll [2]int) string { |
||||
return data.Tables.Maze.DungeonLayout[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MazeTable) DungeonRuination(roll [2]int) string { |
||||
magicTable := MagicTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{4, 2}: |
||||
return magicTable.Insanity(t.Roller.TableRoll()) |
||||
case [2]int{5, 1}: |
||||
return magicTable.Mutation(t.Roller.TableRoll()) |
||||
} |
||||
return data.Tables.Maze.DungeonRuinations[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MazeTable) DungeonReward(roll [2]int) string { |
||||
treasureTable := TreasureTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{3, 6}: |
||||
return "Magic " + treasureTable.TreasureItem(t.Roller.TableRoll()) |
||||
case [2]int{4, 5}: |
||||
return "Generate monster as an ally" |
||||
case [2]int{6, 2}: |
||||
return treasureTable.TreasureItem(t.Roller.TableRoll()) |
||||
case [2]int{5, 4}: |
||||
return treasureTable.ValuableMaterial(t.Roller.TableRoll()) |
||||
} |
||||
return data.Tables.Maze.DungeonRewards[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MazeTable) DungeonActivity(roll [2]int) string { |
||||
cityTable := CityTable{Roller: t.Roller} |
||||
monTable := MonsterTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{1, 3}: |
||||
return cityTable.CityActivity(t.Roller.TableRoll()) |
||||
case [2]int{1, 3}: |
||||
return monTable.Tactic(t.Roller.TableRoll()) |
||||
case [2]int{6, 5}: |
||||
return monTable.Tactic(t.Roller.TableRoll()) |
||||
} |
||||
return data.Tables.Maze.DungeonActivities[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MazeTable) DungeonRoom(roll [2]int) string { |
||||
cityTable := CityTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{1, 4}: |
||||
return cityTable.BuildingRoom(t.Roller.TableRoll()) |
||||
case [2]int{3, 5}: |
||||
return cityTable.LowerClassBuilding(t.Roller.TableRoll()).Type |
||||
case [2]int{6, 3}: |
||||
return cityTable.UpperClassBuilding(t.Roller.TableRoll()).Type |
||||
} |
||||
return data.Tables.Maze.DungeonRooms[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MazeTable) DungeonRoomDetail(roll [2]int) string { |
||||
return data.Tables.Maze.DungeonRoomDetails[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MazeTable) DungeonTrick(roll [2]int) string { |
||||
magicTable := MagicTable{Roller: t.Roller} |
||||
npcTable := NPCTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{2, 6}: |
||||
return magicTable.EtherealEffect(t.Roller.TableRoll()) |
||||
case [2]int{3, 6}: |
||||
return npcTable.Mission(t.Roller.TableRoll()) |
||||
case [2]int{4, 3}: |
||||
return magicTable.PhysicalEffect(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.Maze.DungeonTricks[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t MazeTable) DungeonHazard(roll [2]int) string { |
||||
return data.Tables.Maze.DungeonHazards[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t MazeTable) TrapEffect(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{4, 5}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return MonsterTable{Roller: t.Roller}.Base(roll[0]) + " freed" |
||||
default: |
||||
return data.Tables.Maze.TrapEffects[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t MazeTable) TrapTrigger(roll [2]int) string { |
||||
return data.Tables.Maze.TrapTriggers[roll[0]-1][roll[1]-1] |
||||
} |
@ -0,0 +1,310 @@ |
||||
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] |
||||
} |
||||
} |
@ -0,0 +1,18 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/dice" |
||||
"testing" |
||||
) |
||||
|
||||
func TestMonsterGenMethods(t *testing.T) { |
||||
roller := dice.NewRoller(1) |
||||
table := MonsterTable{Roller: roller} |
||||
table.Weakness(roller.TableRoll()) |
||||
table.Personality(roller.TableRoll()) |
||||
table.Tactic(roller.TableRoll()) |
||||
table.Ability(roller.TableRoll()) |
||||
table.Trait(roller.TableRoll()) |
||||
table.Feature(roller.TableRoll()) |
||||
table.Base(roller.TableRoll()[0]) // TODO: Test all 3 paths
|
||||
} |
@ -0,0 +1,252 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/data" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/helpers" |
||||
) |
||||
|
||||
type NPCTable struct { |
||||
Roller *dice.Roller |
||||
} |
||||
|
||||
type NPC struct { |
||||
Name string |
||||
Class string |
||||
Occupation string |
||||
Gender string |
||||
Appearance string |
||||
PhysicalDetail string |
||||
Clothing string |
||||
Personality string |
||||
Mannerism string |
||||
Secret string |
||||
Reputation string |
||||
Relationship string |
||||
Hobby string |
||||
DivineDomain string |
||||
AfterTheParty string |
||||
Assets []string |
||||
Liabilities []string |
||||
Goals []string |
||||
Misfortunes []string |
||||
Missions []string |
||||
Methods []string |
||||
} |
||||
|
||||
func GenNPC(seed int64) NPC { |
||||
roller := dice.NewRoller(seed) |
||||
npcTable := NPCTable{Roller: roller} |
||||
var occupation, class, gender string |
||||
|
||||
occupationRoll, _ := roller.Roll("1d3") |
||||
switch occupationRoll[0] { |
||||
case 1: |
||||
occupation = npcTable.CivilizedNPC(roller.TableRoll()) |
||||
case 2: |
||||
occupation = npcTable.UnderworldNPC(roller.TableRoll()) |
||||
case 3: |
||||
occupation = npcTable.WildernessNPC(roller.TableRoll()) |
||||
} |
||||
|
||||
classRoll, _ := roller.Roll("1d2") |
||||
if classRoll[0] == 1 { |
||||
class = "Upperclass" |
||||
} else { |
||||
class = "Lowerclass" |
||||
} |
||||
|
||||
genderRoll, _ := roller.Roll("1d2") |
||||
if genderRoll[0] == 1 { |
||||
gender = "Male" |
||||
} else { |
||||
gender = "Female" |
||||
} |
||||
|
||||
return NPC{ |
||||
Name: GenName(class, gender, seed).FullName, |
||||
Occupation: occupation, |
||||
Class: class, |
||||
Gender: gender, |
||||
Appearance: npcTable.Appearance(roller.TableRoll()), |
||||
PhysicalDetail: npcTable.PhysicalDetail(roller.TableRoll()), |
||||
Clothing: npcTable.Clothing(roller.TableRoll()), |
||||
Personality: npcTable.Personality(roller.TableRoll()), |
||||
Mannerism: npcTable.Mannerism(roller.TableRoll()), |
||||
Secret: npcTable.Secret(roller.TableRoll()), |
||||
Reputation: npcTable.Reputation(roller.TableRoll()), |
||||
Relationship: npcTable.Relationship(roller.TableRoll()), |
||||
Hobby: npcTable.Hobby(roller.TableRoll()), |
||||
DivineDomain: npcTable.DivineDomain(roller.TableRoll()), |
||||
AfterTheParty: npcTable.AfterTheParty(roller.TableRoll()), |
||||
Assets: helpers.GenUniqueItems(3, npcTable.Asset, seed), |
||||
Liabilities: helpers.GenUniqueItems(3, npcTable.Liability, seed), |
||||
Goals: helpers.GenUniqueItems(3, npcTable.NPCGoal, seed), |
||||
Misfortunes: helpers.GenUniqueItems(3, npcTable.Misfortune, seed), |
||||
Missions: helpers.GenUniqueItems(3, npcTable.Mission, seed), |
||||
Methods: helpers.GenUniqueItems(3, npcTable.Method, seed), |
||||
} |
||||
} |
||||
|
||||
func (t NPCTable) CivilizedNPC(tableRole [2]int) string { |
||||
return data.Tables.NPC.CivilizedNPCs[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) UnderworldNPC(tableRole [2]int) string { |
||||
return data.Tables.NPC.UnderworldNPCs[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) WildernessNPC(tableRole [2]int) string { |
||||
return data.Tables.NPC.WildernessNPCs[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) FemaleName(tableRole [2]int) string { |
||||
return data.Tables.NPC.FemaleNames[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) MaleName(tableRole [2]int) string { |
||||
return data.Tables.NPC.MaleNames[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) UpperClassSurname(tableRole [2]int) string { |
||||
return data.Tables.NPC.UpperClassSurnames[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) LowerClassSurname(tableRole [2]int) string { |
||||
return data.Tables.NPC.LowerClassSurnames[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Asset(tableRole [2]int) string { |
||||
switch tableRole { |
||||
case [2]int{2, 3}: |
||||
return "Leader of existing faction" |
||||
case [2]int{2, 4}: |
||||
return "Member of existing faction" |
||||
default: |
||||
return data.Tables.NPC.Assets[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t NPCTable) Liability(tableRole [2]int) string { |
||||
switch tableRole { |
||||
case [2]int{3, 1}: |
||||
return MagicTable{Roller: t.Roller}.Insanity(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.NPC.Liabilities[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t NPCTable) NPCGoal(tableRole [2]int) string { |
||||
treasureTable := TreasureTable{Roller: t.Roller} |
||||
switch tableRole { |
||||
case [2]int{1, 3}: |
||||
return "Acquire " + treasureTable.TreasureItem(t.Roller.TableRoll()) |
||||
case [2]int{1, 4}: |
||||
return "Craft " + treasureTable.TreasureItem(t.Roller.TableRoll()) |
||||
case [2]int{1, 5}: |
||||
return "Destroy an existing faction" |
||||
case [2]int{1, 6}: |
||||
return "Destroy " + treasureTable.TreasureItem(t.Roller.TableRoll()) |
||||
case [2]int{2, 3}: |
||||
return "Found a faction" |
||||
case [2]int{2, 6}: |
||||
return "Impress an existing NPC" |
||||
case [2]int{3, 2}: |
||||
return "Infiltrate an existing faction" |
||||
case [2]int{3, 4}: |
||||
return "Kidnap an existing NPC" |
||||
case [2]int{3, 5}: |
||||
return "Lead an existing faction" |
||||
case [2]int{4, 1}: |
||||
return "Locate an existing NPC" |
||||
case [2]int{4, 6}: |
||||
return "Rescue an existing NPC" |
||||
case [2]int{5, 2}: |
||||
return "Restore an existing faction" |
||||
case [2]int{5, 5}: |
||||
return "Sabotage an existing faction" |
||||
case [2]int{6, 2}: |
||||
return "Serve an existing faction" |
||||
default: |
||||
return data.Tables.NPC.NPCGoals[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t NPCTable) Misfortune(tableRole [2]int) string { |
||||
return data.Tables.NPC.Misfortunes[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Mission(tableRole [2]int) string { |
||||
return data.Tables.NPC.Missions[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Method(tableRole [2]int) string { |
||||
return data.Tables.NPC.Methods[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Appearance(tableRole [2]int) string { |
||||
return data.Tables.NPC.Appearances[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) PhysicalDetail(tableRole [2]int) string { |
||||
return data.Tables.NPC.PhysicalDetails[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Clothing(tableRole [2]int) string { |
||||
return data.Tables.NPC.Clothing[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Personality(tableRole [2]int) string { |
||||
return data.Tables.NPC.Personalities[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Mannerism(tableRole [2]int) string { |
||||
return data.Tables.NPC.Mannerisms[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Secret(tableRole [2]int) string { |
||||
switch tableRole { |
||||
case [2]int{4, 5}: |
||||
return t.Misfortune(t.Roller.TableRoll()) |
||||
case [2]int{5, 2}: |
||||
return "An existing NPC" |
||||
default: |
||||
return data.Tables.NPC.Secrets[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t NPCTable) Reputation(tableRole [2]int) string { |
||||
return data.Tables.NPC.Reputations[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Hobby(tableRole [2]int) string { |
||||
return data.Tables.NPC.Hobbies[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) Relationship(tableRole [2]int) string { |
||||
return data.Tables.NPC.Relationships[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
|
||||
func (t NPCTable) DivineDomain(tableRole [2]int) string { |
||||
switch tableRole { |
||||
case [2]int{1, 1}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return MonsterTable{Roller: t.Roller}.Base(roll[0]) |
||||
case [2]int{2, 5}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return MagicTable{Roller: t.Roller}.Element(roll[0]) |
||||
case [2]int{4, 1}: |
||||
return "An existing NPC" |
||||
default: |
||||
return data.Tables.NPC.DivineDomains[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t NPCTable) AfterTheParty(tableRole [2]int) string { |
||||
switch tableRole { |
||||
case [2]int{3, 3}: |
||||
return "Insulted an existing faction" |
||||
default: |
||||
return data.Tables.NPC.AfterTheParty[tableRole[0]-1][tableRole[1]-1] |
||||
} |
||||
} |
@ -0,0 +1,85 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/dice" |
||||
"testing" |
||||
) |
||||
|
||||
func TestNPCGenMethods(t *testing.T) { |
||||
roller := dice.NewRoller(1) |
||||
table := NPCTable{Roller: roller} |
||||
table.CivilizedNPC(roller.TableRoll()) |
||||
table.UnderworldNPC(roller.TableRoll()) |
||||
table.WildernessNPC(roller.TableRoll()) |
||||
table.FemaleName(roller.TableRoll()) |
||||
table.MaleName(roller.TableRoll()) |
||||
table.UpperClassSurname(roller.TableRoll()) |
||||
table.LowerClassSurname(roller.TableRoll()) |
||||
table.Asset(roller.TableRoll()) |
||||
table.Liability(roller.TableRoll()) |
||||
table.NPCGoal(roller.TableRoll()) |
||||
table.Misfortune(roller.TableRoll()) |
||||
table.Mission(roller.TableRoll()) |
||||
table.Method(roller.TableRoll()) |
||||
table.Appearance(roller.TableRoll()) |
||||
table.PhysicalDetail(roller.TableRoll()) |
||||
table.Clothing(roller.TableRoll()) |
||||
table.Personality(roller.TableRoll()) |
||||
table.Mannerism(roller.TableRoll()) |
||||
table.Secret(roller.TableRoll()) |
||||
table.Hobby(roller.TableRoll()) |
||||
table.Reputation(roller.TableRoll()) |
||||
table.DivineDomain(roller.TableRoll()) |
||||
table.AfterTheParty(roller.TableRoll()) |
||||
} |
||||
|
||||
func TestForEXTERNALs(t *testing.T) { |
||||
t.Parallel() |
||||
|
||||
roller := dice.NewRoller(1) |
||||
table := NPCTable{Roller: roller} |
||||
|
||||
tests := []struct { |
||||
Name string |
||||
Func func([2]int) string |
||||
}{ |
||||
{Name: "Secret", Func: table.Secret}, |
||||
{Name: "CivilizedNPC", Func: table.CivilizedNPC}, |
||||
{Name: "UnderworldNPC", Func: table.UnderworldNPC}, |
||||
{Name: "WildernessNPC", Func: table.WildernessNPC}, |
||||
{Name: "FemaleName", Func: table.FemaleName}, |
||||
{Name: "MaleName", Func: table.MaleName}, |
||||
{Name: "UpperClassName", Func: table.UpperClassSurname}, |
||||
{Name: "LowerClassName", Func: table.LowerClassSurname}, |
||||
{Name: "Asset", Func: table.Asset}, |
||||
{Name: "Liability", Func: table.Liability}, |
||||
{Name: "NPCGoal", Func: table.NPCGoal}, |
||||
{Name: "Misfortune", Func: table.Misfortune}, |
||||
{Name: "Mission", Func: table.Mission}, |
||||
{Name: "Method", Func: table.Method}, |
||||
{Name: "Appearance", Func: table.Appearance}, |
||||
{Name: "PhysicalDetail", Func: table.PhysicalDetail}, |
||||
{Name: "Clothing", Func: table.Clothing}, |
||||
{Name: "Personality", Func: table.Personality}, |
||||
{Name: "Mannerism", Func: table.Mannerism}, |
||||
{Name: "Hobby", Func: table.Hobby}, |
||||
{Name: "Reputation", Func: table.Reputation}, |
||||
{Name: "DivineDomain", Func: table.DivineDomain}, |
||||
{Name: "AfterTheParty", Func: table.AfterTheParty}, |
||||
} |
||||
|
||||
t.Run("No EXTERNALs", func(t *testing.T) { |
||||
t.Parallel() |
||||
for _, fTest := range tests { |
||||
for x := 1; x <= 6; x++ { |
||||
for y := 1; y <= 6; y++ { |
||||
result := fTest.Func([2]int{x, y}) |
||||
if result == "EXTERNAL" { |
||||
t.Errorf("Expected roll %v(%v,%v) to not equal 'EXTERNAL'", |
||||
fTest.Name, x, y) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}) |
||||
} |
@ -0,0 +1,83 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"bytes" |
||||
"encoding/json" |
||||
"mazeratsgen/internal/dice" |
||||
"text/template" |
||||
) |
||||
|
||||
// TODO: Add GenRandomName
|
||||
|
||||
type Name struct { |
||||
FirstName string |
||||
LastName string |
||||
FullName string |
||||
Gender string |
||||
Class string |
||||
Seed int64 |
||||
} |
||||
|
||||
func GenRandomName(seed int64) Name { |
||||
var class string |
||||
var gender string |
||||
|
||||
roller := dice.NewRoller(seed) |
||||
|
||||
classRoll, _ := roller.Roll("1d2") |
||||
if classRoll[0] == 1 { |
||||
class = "Upperclass" |
||||
} else { |
||||
class = "Lowerclass" |
||||
} |
||||
|
||||
genderRoll, _ := roller.Roll("1d2") |
||||
if genderRoll[0] == 1 { |
||||
gender = "Male" |
||||
} else { |
||||
gender = "Female" |
||||
} |
||||
|
||||
return GenName(class, gender, seed) |
||||
} |
||||
|
||||
func GenName(gender string, class string, seed int64) Name { |
||||
name := Name{Seed: seed} |
||||
roller := dice.NewRoller(seed) |
||||
npcTable := NPCTable{Roller: roller} |
||||
if gender == "Male" { |
||||
name.Gender = "Male" |
||||
name.FirstName = npcTable.MaleName(roller.TableRoll()) |
||||
} else { |
||||
name.Gender = "Female" |
||||
name.FirstName = npcTable.FemaleName(roller.TableRoll()) |
||||
} |
||||
if class == "Upper" { |
||||
name.Class = "Upper" |
||||
name.LastName = npcTable.UpperClassSurname(roller.TableRoll()) |
||||
} else { |
||||
name.Class = "Lower" |
||||
name.LastName = npcTable.LowerClassSurname(roller.TableRoll()) |
||||
} |
||||
name.FullName = name.FirstName + " " + name.LastName |
||||
return name |
||||
} |
||||
|
||||
// ConvertToJSON takes a interface and unmarshals it
|
||||
func ConvertToJSON(o interface{}) ([]byte, error) { |
||||
json, err := json.MarshalIndent(o, "", " ") |
||||
if err != nil { |
||||
return []byte{}, err |
||||
} |
||||
return json, nil |
||||
} |
||||
|
||||
func ConvertToText(o interface{}, t string) (string, error) { |
||||
tmpl, _ := template.New("textTemplate").Parse(t) |
||||
var d bytes.Buffer |
||||
err := tmpl.Execute(&d, &o) |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
return d.String(), nil |
||||
} |
@ -0,0 +1,149 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/data" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/helpers" |
||||
) |
||||
|
||||
type TreasureTable struct { |
||||
Roller *dice.Roller |
||||
} |
||||
|
||||
type Potion struct { |
||||
Effect string |
||||
Ingredients []string |
||||
OnFailure string |
||||
} |
||||
|
||||
func GenTreasure(seed int64) string { |
||||
roller := dice.NewRoller(seed) |
||||
treasureTable := TreasureTable{Roller: roller} |
||||
trait := treasureTable.TreasureTrait(roller.TableRoll()) |
||||
item := treasureTable.TreasureItem(roller.TableRoll()) |
||||
return trait + " " + item |
||||
} |
||||
|
||||
func GenPotion(seed int64) Potion { |
||||
roller := dice.NewRoller(seed) |
||||
magicTable := MagicTable{Roller: roller} |
||||
treasureTable := TreasureTable{Roller: roller} |
||||
var onFailure string |
||||
onFailRoll, _ := roller.Roll("1d2") |
||||
if onFailRoll[0] == 1 { |
||||
onFailure = magicTable.Mutation(roller.TableRoll()) |
||||
} else { |
||||
onFailure = magicTable.Insanity(roller.TableRoll()) |
||||
} |
||||
|
||||
ingredientRoll, _ := roller.Roll("1d3") |
||||
|
||||
return Potion{ |
||||
Effect: treasureTable.PotionBase(roller.TableRoll()), |
||||
OnFailure: onFailure, |
||||
Ingredients: helpers.GenUniqueItems(ingredientRoll[0], treasureTable.MagicalIngredient, seed), |
||||
} |
||||
} |
||||
|
||||
func (t TreasureTable) PotionBase(roll [2]int) string { |
||||
monTable := MonsterTable{Roller: t.Roller} |
||||
magicTable := MagicTable{Roller: t.Roller} |
||||
|
||||
switch roll { |
||||
case [2]int{1, 1}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return monTable.Base(roll[0]) + " Form" |
||||
case [2]int{1, 5}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return "Control " + magicTable.Element(roll[0]) |
||||
case [2]int{2, 5}: |
||||
roll, _ := t.Roller.Roll("1d6") |
||||
return magicTable.Element(roll[0]) + " Form" |
||||
case [2]int{3, 5}: |
||||
return magicTable.Insanity(t.Roller.TableRoll()) |
||||
case [2]int{4, 1}: |
||||
return t.TreasureItem(t.Roller.TableRoll()) + " Form" |
||||
case [2]int{4, 4}: |
||||
return monTable.Ability(t.Roller.TableRoll()) |
||||
case [2]int{4, 5}: |
||||
return monTable.Feature(t.Roller.TableRoll()) |
||||
case [2]int{4, 6}: |
||||
return monTable.Trait(t.Roller.TableRoll()) |
||||
case [2]int{5, 1}: |
||||
return magicTable.Mutation(t.Roller.TableRoll()) |
||||
case [2]int{5, 3}: |
||||
return magicTable.Spell(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.Treasure.Potions[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t TreasureTable) MiscItem(roll [2]int) string { |
||||
return data.Tables.Treasure.MiscItems[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t TreasureTable) WornItem(roll [2]int) string { |
||||
return data.Tables.Treasure.WornItems[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t TreasureTable) WeaponItem(roll [2]int) string { |
||||
return data.Tables.Treasure.WeaponItems[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t TreasureTable) BookSubject(roll [2]int) string { |
||||
return data.Tables.Treasure.BookSubjects[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t TreasureTable) ToolItem(roll [2]int) string { |
||||
return data.Tables.Treasure.ToolItems[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t TreasureTable) MagicalIngredient(roll [2]int) string { |
||||
monTable := MonsterTable{Roller: t.Roller} |
||||
wildTable := WildTable{Roller: t.Roller} |
||||
magicTable := MagicTable{Roller: t.Roller} |
||||
treasureTable := TreasureTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{1, 2}: |
||||
baseRoll, _ := t.Roller.Roll("1d6") |
||||
return monTable.Base(baseRoll[0]) |
||||
case [2]int{1, 5}: |
||||
return t.BookSubject(t.Roller.TableRoll()) + " page" |
||||
case [2]int{2, 5}: |
||||
return wildTable.EdiblePlant(t.Roller.TableRoll()) |
||||
case [2]int{4, 2}: |
||||
return monTable.Feature(t.Roller.TableRoll()) |
||||
case [2]int{4, 5}: |
||||
return magicTable.PhysicalElement(t.Roller.TableRoll()) |
||||
case [2]int{4, 6}: |
||||
return wildTable.PoisonousPlant(t.Roller.TableRoll()) |
||||
case [2]int{5, 1}: |
||||
return treasureTable.PotionBase(t.Roller.TableRoll()) |
||||
case [2]int{6, 3}: |
||||
return treasureTable.ValuableMaterial(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.Treasure.MagicalIngredients[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t TreasureTable) TreasureItem(roll [2]int) string { |
||||
return data.Tables.Treasure.TreasureItems[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t TreasureTable) TreasureTrait(roll [2]int) string { |
||||
magicTable := MagicTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{2, 6}: |
||||
effectRoll, _ := t.Roller.Roll("1d6") |
||||
return magicTable.Effect(effectRoll[0]) |
||||
case [2]int{3, 1}: |
||||
effectRoll, _ := t.Roller.Roll("1d6") |
||||
return magicTable.Effect(effectRoll[0]) |
||||
default: |
||||
return data.Tables.Treasure.TreasureItems[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t TreasureTable) ValuableMaterial(roll [2]int) string { |
||||
return data.Tables.Treasure.ValuableMaterials[roll[0]-1][roll[1]-1] |
||||
} |
@ -0,0 +1,183 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/data" |
||||
"mazeratsgen/internal/dice" |
||||
"mazeratsgen/internal/helpers" |
||||
) |
||||
|
||||
type WildTable struct { |
||||
Roller *dice.Roller |
||||
} |
||||
|
||||
type Inn struct { |
||||
Name string |
||||
Quirk string |
||||
} |
||||
|
||||
type Wild struct { |
||||
Region string |
||||
Landmark string |
||||
Trait string |
||||
Structures []string |
||||
Discoveries []string |
||||
Activities []string |
||||
Hazards []string |
||||
WildernessHazards []string |
||||
EdiblePlants []string |
||||
PoisonousPlants []string |
||||
Inns []Inn |
||||
} |
||||
|
||||
// TODO: Support two nouns
|
||||
func GenInn(seed int64) Inn { |
||||
roller := dice.NewRoller(seed) |
||||
wildTable := WildTable{Roller: roller} |
||||
adjective := wildTable.InnAdjective(roller.TableRoll()) |
||||
noun := wildTable.InnNoun(roller.TableRoll()) |
||||
quirk := wildTable.InnQuirk(roller.TableRoll()) |
||||
return Inn{ |
||||
Name: adjective + " " + noun, |
||||
Quirk: quirk, |
||||
} |
||||
} |
||||
|
||||
func GenInnName(seed int64) string { |
||||
inn := GenInn(seed) |
||||
return inn.Name + " (" + inn.Quirk + ")" |
||||
} |
||||
|
||||
func GenWild(seed int64) Wild { |
||||
roller := dice.NewRoller(seed) |
||||
wildTable := WildTable{Roller: roller} |
||||
|
||||
// TODO: Shouldn't this be genUnique
|
||||
var inns []Inn |
||||
for i := 0; i < 4; i++ { |
||||
inns = append(inns, GenInn(seed)) |
||||
} |
||||
|
||||
return Wild{ |
||||
Region: wildTable.WildernessRegion(roller.TableRoll()), |
||||
Landmark: wildTable.WildernessLandmark(roller.TableRoll()), |
||||
Trait: wildTable.WildernessRegionTrait(roller.TableRoll()), |
||||
Structures: helpers.GenUniqueItems(5, wildTable.WildernessStructure, seed), |
||||
Discoveries: helpers.GenUniqueItems(5, wildTable.WildernessDiscovery, seed), |
||||
Activities: helpers.GenUniqueItems(5, wildTable.WildernessActivity, seed), |
||||
Hazards: helpers.GenUniqueItems(5, wildTable.WildernessHazard, seed), |
||||
EdiblePlants: helpers.GenUniqueItems(5, wildTable.EdiblePlant, seed), |
||||
PoisonousPlants: helpers.GenUniqueItems(5, wildTable.PoisonousPlant, seed), |
||||
Inns: inns, |
||||
} |
||||
} |
||||
|
||||
func (t WildTable) WildernessRegion(roll [2]int) string { |
||||
return data.Tables.Wild.WildernessRegions[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t WildTable) WildernessLandmark(roll [2]int) string { |
||||
return data.Tables.Wild.WildernessLandmarks[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t WildTable) WildernessStructure(roll [2]int) string { |
||||
return data.Tables.Wild.WildernessStructures[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t WildTable) WildernessRegionTrait(roll [2]int) string { |
||||
mazeTable := MazeTable{Roller: t.Roller} |
||||
magicTable := MagicTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{2, 3}: |
||||
return mazeTable.DungeonForm(t.Roller.TableRoll()) |
||||
case [2]int{2, 4}: |
||||
return magicTable.EtherealEffect(t.Roller.TableRoll()) |
||||
case [2]int{6, 4}: |
||||
return magicTable.PhysicalEffect(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.Wild.WildernessRegionTraits[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t WildTable) WildernessDiscovery(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{1, 5}: |
||||
return CityTable{Roller: t.Roller}.CityActivity(t.Roller.TableRoll()) |
||||
case [2]int{1, 6}: |
||||
return NPCTable{Roller: t.Roller}.CivilizedNPC(t.Roller.TableRoll()) |
||||
case [2]int{2, 3}: |
||||
return MazeTable{Roller: t.Roller}.DungeonActivity(t.Roller.TableRoll()) |
||||
case [2]int{3, 1}: |
||||
return TreasureTable{Roller: t.Roller}.TreasureItem(t.Roller.TableRoll()) |
||||
case [2]int{1, 3}: |
||||
return "Lost an existing NPC" |
||||
case [2]int{4, 1}: |
||||
return MagicTable{Roller: t.Roller}.Mutation(t.Roller.TableRoll()) |
||||
case [2]int{5, 1}: |
||||
return "Lost an existing NPC" |
||||
case [2]int{6, 1}: |
||||
return NPCTable{Roller: t.Roller}.UnderworldNPC(t.Roller.TableRoll()) |
||||
case [2]int{6, 2}: |
||||
return WildTable{Roller: t.Roller}.WildernessActivity(t.Roller.TableRoll()) |
||||
case [2]int{6, 3}: |
||||
return WildTable{Roller: t.Roller}.WildernessLandmark(t.Roller.TableRoll()) |
||||
case [2]int{6, 4}: |
||||
return WildTable{Roller: t.Roller}.WildernessStructure(t.Roller.TableRoll()) |
||||
case [2]int{6, 5}: |
||||
return NPCTable{Roller: t.Roller}.WildernessNPC(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.Wild.WildernessDiscoveries[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t WildTable) WildernessActivity(roll [2]int) string { |
||||
switch roll { |
||||
case [2]int{2, 1}: |
||||
return CityTable{Roller: t.Roller}.CityActivity(t.Roller.TableRoll()) |
||||
case [2]int{2, 6}: |
||||
return MazeTable{Roller: t.Roller}.DungeonActivity(t.Roller.TableRoll()) |
||||
default: |
||||
return data.Tables.Wild.WildernessActivities[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
||||
|
||||
func (t WildTable) WildernessHazard(roll [2]int) string { |
||||
return data.Tables.Wild.WildernessHazards[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t WildTable) EdiblePlant(roll [2]int) string { |
||||
return data.Tables.Wild.EdiblePlants[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t WildTable) PoisonousPlant(roll [2]int) string { |
||||
return data.Tables.Wild.PoisonousPlants[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t WildTable) InnAdjective(roll [2]int) string { |
||||
return data.Tables.Wild.InnAdjectives[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t WildTable) InnNoun(roll [2]int) string { |
||||
return data.Tables.Wild.InnNouns[roll[0]-1][roll[1]-1] |
||||
} |
||||
|
||||
func (t WildTable) InnQuirk(roll [2]int) string { |
||||
cityTable := CityTable{Roller: t.Roller} |
||||
mazeTable := MazeTable{Roller: t.Roller} |
||||
switch roll { |
||||
case [2]int{2, 3}: |
||||
return cityTable.CityActivity(t.Roller.TableRoll()) |
||||
case [2]int{3, 1}: |
||||
return mazeTable.DungeonForm(t.Roller.TableRoll()) |
||||
case [2]int{3, 3}: |
||||
return "An existing faction hangout" |
||||
case [2]int{3, 4}: |
||||
return cityTable.FactionTrait(t.Roller.TableRoll()) |
||||
case [2]int{4, 6}: |
||||
buildingRoll, _ := t.Roller.Roll("1d6") |
||||
return "Inn/" + cityTable.GenBuilding(buildingRoll[0]).Type |
||||
case [2]int{5, 4}: |
||||
return "Existing NPC hangout" |
||||
default: |
||||
return data.Tables.Wild.InnQuirks[roll[0]-1][roll[1]-1] |
||||
} |
||||
} |
@ -0,0 +1,17 @@ |
||||
package tables |
||||
|
||||
import ( |
||||
"mazeratsgen/internal/dice" |
||||
. "mazeratsgen/test/helpers" |
||||
"testing" |
||||
) |
||||
|
||||
func TestWildMethods(t *testing.T) { |
||||
roller := dice.NewRoller(1) |
||||
WildTable{Roller: roller}.WildernessRegion(roller.TableRoll()) |
||||
} |
||||
|
||||
func TestMethods(t *testing.T) { |
||||
roller := dice.NewRoller(1) |
||||
ExactItem(WildTable{Roller: roller}.WildernessRegion([2]int{5, 2}), "Rainforest", t) |
||||
} |
@ -0,0 +1,12 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"mazeratsgen/cmd" |
||||
) |
||||
|
||||
// @title Maze Rats API
|
||||
// @BasePath /
|
||||
// @query.collection.format multi
|
||||
func main() { |
||||
cmd.Execute() |
||||
} |
@ -0,0 +1,19 @@ |
||||
package helpers |
||||
|
||||
import ( |
||||
"testing" |
||||
"regexp" |
||||
) |
||||
|
||||
func ExactItem(actualResult string, expectedResult string, t *testing.T) { |
||||
if actualResult != expectedResult { |
||||
t.Errorf("Expected '%v' to equal '%v'", actualResult, expectedResult) |
||||
} |
||||
} |
||||
|
||||
func RegexItem(actual string, regex string, t *testing.T) { |
||||
re := regexp.MustCompile(regex) |
||||
if re.MatchString(actual) != true { |
||||
t.Errorf("Expected '%v' to match '%v'", actual, re) |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
# Swagger UI |
||||
|
||||
Contains static assets and `swagger.json` |
||||
|
@ -0,0 +1,212 @@ |
||||
/* Forgive me for these awful hacks. */ |
||||
|
||||
body { |
||||
background: #000000; |
||||
} |
||||
|
||||
.swagger-ui { |
||||
color: #000000; |
||||
} |
||||
|
||||
.swagger-ui a { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .model, |
||||
.swagger-ui .model-title { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .prop-type { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui section.models, |
||||
.swagger-ui section.models.is-open h4, |
||||
.swagger-ui section.models h4 { |
||||
border-color: #00FF00; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui section.models .model-container:first-of-type { |
||||
margin: 0 0 0 20px; |
||||
} |
||||
|
||||
.swagger-ui section.models .model-container { |
||||
margin: 0 0 0 20px; |
||||
} |
||||
|
||||
.swagger-ui section.models .model-box { |
||||
padding: 2px; |
||||
} |
||||
|
||||
.swagger-ui .info { |
||||
margin: 0; |
||||
} |
||||
|
||||
.swagger-ui .info .title { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .info .base-url { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .info a { |
||||
display: none; |
||||
} |
||||
|
||||
.swagger-ui .info .title small { |
||||
background: #005007; |
||||
} |
||||
|
||||
.swagger-ui .info .title small pre { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .info .title small pre { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .info p { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
|
||||
.swagger-ui a.nostyle, |
||||
.swagger-ui a.nostyle:active, |
||||
.swagger-ui a.nostyle:hover, |
||||
.swagger-ui a.nostyle:visited |
||||
{ |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .opblock.opblock-get, |
||||
.swagger-ui .opblock.opblock-get .opblock-summary { |
||||
border-color: #00FF00; |
||||
background: #000000; |
||||
} |
||||
|
||||
.swagger-ui .opblock.opblock-get .opblock-summary-method { |
||||
background: #007000; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .opblock-description-wrapper p { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .opblock .opblock-section-header { |
||||
background: #000000; |
||||
} |
||||
|
||||
.swagger-ui .opblock .opblock-summary-description { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .opblock .opblock-section-header h4 { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .opblock .opblock-section-header>label { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .btn { |
||||
border-color: #00FF00; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .btn.cancel { |
||||
border-color: #00FF00; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .btn.execute { |
||||
border-color: #00FF00; |
||||
background: #000000; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui select, |
||||
.swagger-ui select[disabled] { |
||||
background: #000000; |
||||
border-color: #00FF00; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .response-col_status, |
||||
.swagger-ui .response-col_status .response-undocumented, |
||||
.swagger-ui .response-col_description { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .responses-inner h4, |
||||
.swagger-ui .responses-inner h5 { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui textarea.curl { |
||||
background: #000000; |
||||
border: 1px solid #00FF00; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .opblock-body pre.microlight { |
||||
background: #000000; |
||||
border: 1px solid #00FF00; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .opblock-body pre.microlight span { |
||||
color: #00FF00!important; |
||||
} |
||||
|
||||
.swagger-ui .download-contents { |
||||
background: #000000; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .copy-to-clipboard { |
||||
background: #000000; |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .copy-to-clipboard button { |
||||
background: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" aria-hidden="true"><path fill="%230f0" fill-rule="evenodd" d="M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3 3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H3c-.55 0-1 .45-1 1z"/></svg>') 50% no-repeat; |
||||
color: #00FF00; |
||||
margin-right: 10px; |
||||
} |
||||
|
||||
.swagger-ui table thead tr td, |
||||
.swagger-ui table thead tr th { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .parameter__name, |
||||
.swagger-ui .parameter__type, |
||||
.swagger-ui .parameter__in, |
||||
.swagger-ui .markdown p { |
||||
color: #00FF00; |
||||
} |
||||
|
||||
.swagger-ui .parameters-col_description input[type=text], |
||||
.swagger-ui .parameters-col_description input[type=text]:focus { |
||||
outline: 0; |
||||
color: #00FF00; |
||||
border-color: #00FF00; |
||||
background: #000000; |
||||
} |
||||
|
||||
.swagger-ui .parameters-col_description input[type=text]::placeholder, |
||||
.swagger-ui .parameter__name.required span, |
||||
.swagger-ui .parameter__name.required:after { |
||||
color: #00AA00; |
||||
} |
||||
|
||||
.swagger-ui .loading-container .loading::before, |
||||
.swagger-ui .loading-container .loading::after { |
||||
color: #00FF00; |
||||
border-color: #001100; |
||||
border-top-color: #00FF00; |
||||
} |
@ -0,0 +1,504 @@ |
||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// This file was generated by swaggo/swag
|
||||
|
||||
package swagger |
||||
|
||||
import ( |
||||
"bytes" |
||||
"encoding/json" |
||||
"strings" |
||||
|
||||
"github.com/alecthomas/template" |
||||
"github.com/swaggo/swag" |
||||
) |
||||
|
||||
var doc = `{ |
||||
"schemes": {{ marshal .Schemes }}, |
||||
"swagger": "2.0", |
||||
"info": { |
||||
"description": "{{.Description}}", |
||||
"title": "{{.Title}}", |
||||
"contact": {}, |
||||
"license": {}, |
||||
"version": "{{.Version}}" |
||||
}, |
||||
"host": "{{.Host}}", |
||||
"basePath": "{{.BasePath}}", |
||||
"paths": { |
||||
"/api/character/{seed}": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"character" |
||||
], |
||||
"summary": "Generate a specific player character using a seed", |
||||
"parameters": [ |
||||
{ |
||||
"type": "integer", |
||||
"description": "Int64", |
||||
"name": "seed", |
||||
"in": "path", |
||||
"required": true |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.Character" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/city/{seed}": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"city" |
||||
], |
||||
"summary": "Generate a specific city using a seed", |
||||
"parameters": [ |
||||
{ |
||||
"type": "integer", |
||||
"description": "Int64", |
||||
"name": "seed", |
||||
"in": "path", |
||||
"required": true |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.City" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/character": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"character" |
||||
], |
||||
"summary": "Generate a player character", |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.Character" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/city": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"city" |
||||
], |
||||
"summary": "Generate a city", |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.City" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/monster": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"monster" |
||||
], |
||||
"summary": "Generate a monster", |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.Monster" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/name": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"character" |
||||
], |
||||
"summary": "Generate a character name", |
||||
"responses": { |
||||
"200": {} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/spell": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"magic" |
||||
], |
||||
"summary": "Generate a spell", |
||||
"responses": { |
||||
"200": {} |
||||
} |
||||
} |
||||
}, |
||||
"/api/monster/{seed}": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"monster" |
||||
], |
||||
"summary": "Generate a specific monster using a seed", |
||||
"parameters": [ |
||||
{ |
||||
"type": "integer", |
||||
"description": "Int64", |
||||
"name": "seed", |
||||
"in": "path", |
||||
"required": true |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.Monster" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/roll/{xdy}": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"dice" |
||||
], |
||||
"summary": "Roll some dice", |
||||
"parameters": [ |
||||
{ |
||||
"type": "string", |
||||
"description": "Roll in xdy format (e.g. 1d6)", |
||||
"name": "xdy", |
||||
"in": "path", |
||||
"required": true |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": {} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"definitions": { |
||||
"tables.Building": { |
||||
"type": "object", |
||||
"properties": { |
||||
"rooms": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"tacticalFeature": { |
||||
"type": "string" |
||||
}, |
||||
"type": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
}, |
||||
"tables.Character": { |
||||
"type": "object", |
||||
"properties": { |
||||
"appearance": { |
||||
"type": "string" |
||||
}, |
||||
"background": { |
||||
"type": "string" |
||||
}, |
||||
"clothing": { |
||||
"type": "string" |
||||
}, |
||||
"feature": { |
||||
"type": "string" |
||||
}, |
||||
"items": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"mannerism": { |
||||
"type": "string" |
||||
}, |
||||
"name": { |
||||
"type": "string" |
||||
}, |
||||
"personality": { |
||||
"type": "string" |
||||
}, |
||||
"physical_detail": { |
||||
"type": "string" |
||||
}, |
||||
"seed": { |
||||
"type": "integer" |
||||
}, |
||||
"stats": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.CharacterStats" |
||||
}, |
||||
"weapons": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"tables.CharacterStats": { |
||||
"type": "object", |
||||
"properties": { |
||||
"armor": { |
||||
"type": "integer" |
||||
}, |
||||
"dex": { |
||||
"type": "integer" |
||||
}, |
||||
"max_health": { |
||||
"type": "integer" |
||||
}, |
||||
"str": { |
||||
"type": "integer" |
||||
}, |
||||
"wil": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
}, |
||||
"tables.City": { |
||||
"type": "object", |
||||
"properties": { |
||||
"activities": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"districtThemes": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"events": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"factions": { |
||||
"type": "array", |
||||
"items": { |
||||
"$ref": "#/definitions/tables.Faction" |
||||
} |
||||
}, |
||||
"lowerClassBuildings": { |
||||
"type": "array", |
||||
"items": { |
||||
"$ref": "#/definitions/tables.Building" |
||||
} |
||||
}, |
||||
"seed": { |
||||
"type": "integer" |
||||
}, |
||||
"tacticalStreetFeatures": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"theme": { |
||||
"type": "string" |
||||
}, |
||||
"upperClassBuildings": { |
||||
"type": "array", |
||||
"items": { |
||||
"$ref": "#/definitions/tables.Building" |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"tables.Faction": { |
||||
"type": "object", |
||||
"properties": { |
||||
"goal": { |
||||
"type": "string" |
||||
}, |
||||
"trait": { |
||||
"type": "string" |
||||
}, |
||||
"type": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
}, |
||||
"tables.Monster": { |
||||
"type": "object", |
||||
"properties": { |
||||
"ability": { |
||||
"type": "string" |
||||
}, |
||||
"base": { |
||||
"type": "string" |
||||
}, |
||||
"feature": { |
||||
"type": "string" |
||||
}, |
||||
"personality": { |
||||
"type": "string" |
||||
}, |
||||
"seed": { |
||||
"type": "integer" |
||||
}, |
||||
"stats": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStats" |
||||
}, |
||||
"tactics": { |
||||
"type": "string" |
||||
}, |
||||
"trait": { |
||||
"type": "string" |
||||
}, |
||||
"weakness": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
}, |
||||
"tables.MonsterStat": { |
||||
"type": "object", |
||||
"properties": { |
||||
"qualifier": { |
||||
"type": "string" |
||||
}, |
||||
"value": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
}, |
||||
"tables.MonsterStats": { |
||||
"type": "object", |
||||
"properties": { |
||||
"armor": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"attack": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"dex": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"health": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"str": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"wil": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}` |
||||
|
||||
type swaggerInfo struct { |
||||
Version string |
||||
Host string |
||||
BasePath string |
||||
Schemes []string |
||||
Title string |
||||
Description string |
||||
} |
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = swaggerInfo{ |
||||
Version: "", |
||||
Host: "", |
||||
BasePath: "/", |
||||
Schemes: []string{}, |
||||
Title: "Maze Rats API", |
||||
Description: "", |
||||
} |
||||
|
||||
type s struct{} |
||||
|
||||
func (s *s) ReadDoc() string { |
||||
sInfo := SwaggerInfo |
||||
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1) |
||||
|
||||
t, err := template.New("swagger_info").Funcs(template.FuncMap{ |
||||
"marshal": func(v interface{}) string { |
||||
a, _ := json.Marshal(v) |
||||
return string(a) |
||||
}, |
||||
}).Parse(doc) |
||||
if err != nil { |
||||
return doc |
||||
} |
||||
|
||||
var tpl bytes.Buffer |
||||
if err := t.Execute(&tpl, sInfo); err != nil { |
||||
return doc |
||||
} |
||||
|
||||
return tpl.String() |
||||
} |
||||
|
||||
func init() { |
||||
swag.Register(swag.Name, &s{}) |
||||
} |
After Width: | Height: | Size: 665 B |
After Width: | Height: | Size: 628 B |
@ -0,0 +1,61 @@ |
||||
<!-- HTML for static distribution bundle build --> |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>Maze Rats API</title> |
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" > |
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" /> |
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" /> |
||||
<style> |
||||
html |
||||
{ |
||||
box-sizing: border-box; |
||||
overflow: -moz-scrollbars-vertical; |
||||
overflow-y: scroll; |
||||
} |
||||
|
||||
*, |
||||
*:before, |
||||
*:after |
||||
{ |
||||
box-sizing: inherit; |
||||
} |
||||
|
||||
body |
||||
{ |
||||
margin:0; |
||||
background: #fafafa; |
||||
} |
||||
</style> |
||||
<link rel="stylesheet" type="text/css" href="./custom.css" > |
||||
</head> |
||||
|
||||
<body> |
||||
<div id="swagger-ui"></div> |
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script> |
||||
<script src="./swagger-ui-standalone-preset.js"> </script> |
||||
<script> |
||||
window.onload = function() { |
||||
// Begin Swagger UI call region |
||||
const ui = SwaggerUIBundle({ |
||||
url: "./swagger.json", |
||||
dom_id: '#swagger-ui', |
||||
deepLinking: true, |
||||
presets: [ |
||||
SwaggerUIBundle.presets.apis, |
||||
SwaggerUIStandalonePreset |
||||
], |
||||
plugins: [ |
||||
SwaggerUIBundle.plugins.DownloadUrl |
||||
], |
||||
layout: "BaseLayout" |
||||
}) |
||||
// End Swagger UI call region |
||||
|
||||
window.ui = ui |
||||
} |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,68 @@ |
||||
<!doctype html> |
||||
<html lang="en-US"> |
||||
<title>Swagger UI: OAuth2 Redirect</title> |
||||
<body onload="run()"> |
||||
</body> |
||||
</html> |
||||
<script> |
||||
'use strict'; |
||||
function run () { |
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2; |
||||
var sentState = oauth2.state; |
||||
var redirectUrl = oauth2.redirectUrl; |
||||
var isValid, qp, arr; |
||||
|
||||
if (/code|token|error/.test(window.location.hash)) { |
||||
qp = window.location.hash.substring(1); |
||||
} else { |
||||
qp = location.search.substring(1); |
||||
} |
||||
|
||||
arr = qp.split("&") |
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';}) |
||||
qp = qp ? JSON.parse('{' + arr.join() + '}', |
||||
function (key, value) { |
||||
return key === "" ? value : decodeURIComponent(value) |
||||
} |
||||
) : {} |
||||
|
||||
isValid = qp.state === sentState |
||||
|
||||
if (( |
||||
oauth2.auth.schema.get("flow") === "accessCode"|| |
||||
oauth2.auth.schema.get("flow") === "authorizationCode" |
||||
) && !oauth2.auth.code) { |
||||
if (!isValid) { |
||||
oauth2.errCb({ |
||||
authId: oauth2.auth.name, |
||||
source: "auth", |
||||
level: "warning", |
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server" |
||||
}); |
||||
} |
||||
|
||||
if (qp.code) { |
||||
delete oauth2.state; |
||||
oauth2.auth.code = qp.code; |
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl}); |
||||
} else { |
||||
let oauthErrorMsg |
||||
if (qp.error) { |
||||
oauthErrorMsg = "["+qp.error+"]: " + |
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") + |
||||
(qp.error_uri ? "More info: "+qp.error_uri : ""); |
||||
} |
||||
|
||||
oauth2.errCb({ |
||||
authId: oauth2.auth.name, |
||||
source: "auth", |
||||
level: "error", |
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server" |
||||
}); |
||||
} |
||||
} else { |
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl}); |
||||
} |
||||
window.close(); |
||||
} |
||||
</script> |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,439 @@ |
||||
{ |
||||
"swagger": "2.0", |
||||
"info": { |
||||
"title": "Maze Rats API", |
||||
"contact": {}, |
||||
"license": {} |
||||
}, |
||||
"basePath": "/", |
||||
"paths": { |
||||
"/api/character/{seed}": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"character" |
||||
], |
||||
"summary": "Generate a specific player character using a seed", |
||||
"parameters": [ |
||||
{ |
||||
"type": "integer", |
||||
"description": "Int64", |
||||
"name": "seed", |
||||
"in": "path", |
||||
"required": true |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.Character" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/city/{seed}": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"city" |
||||
], |
||||
"summary": "Generate a specific city using a seed", |
||||
"parameters": [ |
||||
{ |
||||
"type": "integer", |
||||
"description": "Int64", |
||||
"name": "seed", |
||||
"in": "path", |
||||
"required": true |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.City" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/character": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"character" |
||||
], |
||||
"summary": "Generate a player character", |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.Character" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/city": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"city" |
||||
], |
||||
"summary": "Generate a city", |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.City" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/monster": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"monster" |
||||
], |
||||
"summary": "Generate a monster", |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.Monster" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/name": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"character" |
||||
], |
||||
"summary": "Generate a character name", |
||||
"responses": { |
||||
"200": {} |
||||
} |
||||
} |
||||
}, |
||||
"/api/generate/spell": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"magic" |
||||
], |
||||
"summary": "Generate a spell", |
||||
"responses": { |
||||
"200": {} |
||||
} |
||||
} |
||||
}, |
||||
"/api/monster/{seed}": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"monster" |
||||
], |
||||
"summary": "Generate a specific monster using a seed", |
||||
"parameters": [ |
||||
{ |
||||
"type": "integer", |
||||
"description": "Int64", |
||||
"name": "seed", |
||||
"in": "path", |
||||
"required": true |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "OK", |
||||
"schema": { |
||||
"$ref": "#/definitions/tables.Monster" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/api/roll/{xdy}": { |
||||
"get": { |
||||
"produces": [ |
||||
"application/json", |
||||
" text/plain" |
||||
], |
||||
"tags": [ |
||||
"dice" |
||||
], |
||||
"summary": "Roll some dice", |
||||
"parameters": [ |
||||
{ |
||||
"type": "string", |
||||
"description": "Roll in xdy format (e.g. 1d6)", |
||||
"name": "xdy", |
||||
"in": "path", |
||||
"required": true |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": {} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"definitions": { |
||||
"tables.Building": { |
||||
"type": "object", |
||||
"properties": { |
||||
"rooms": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"tacticalFeature": { |
||||
"type": "string" |
||||
}, |
||||
"type": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
}, |
||||
"tables.Character": { |
||||
"type": "object", |
||||
"properties": { |
||||
"appearance": { |
||||
"type": "string" |
||||
}, |
||||
"background": { |
||||
"type": "string" |
||||
}, |
||||
"clothing": { |
||||
"type": "string" |
||||
}, |
||||
"feature": { |
||||
"type": "string" |
||||
}, |
||||
"items": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"mannerism": { |
||||
"type": "string" |
||||
}, |
||||
"name": { |
||||
"type": "string" |
||||
}, |
||||
"personality": { |
||||
"type": "string" |
||||
}, |
||||
"physical_detail": { |
||||
"type": "string" |
||||
}, |
||||
"seed": { |
||||
"type": "integer" |
||||
}, |
||||
"stats": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.CharacterStats" |
||||
}, |
||||
"weapons": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"tables.CharacterStats": { |
||||
"type": "object", |
||||
"properties": { |
||||
"armor": { |
||||
"type": "integer" |
||||
}, |
||||
"dex": { |
||||
"type": "integer" |
||||
}, |
||||
"max_health": { |
||||
"type": "integer" |
||||
}, |
||||
"str": { |
||||
"type": "integer" |
||||
}, |
||||
"wil": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
}, |
||||
"tables.City": { |
||||
"type": "object", |
||||
"properties": { |
||||
"activities": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"districtThemes": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"events": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"factions": { |
||||
"type": "array", |
||||
"items": { |
||||
"$ref": "#/definitions/tables.Faction" |
||||
} |
||||
}, |
||||
"lowerClassBuildings": { |
||||
"type": "array", |
||||
"items": { |
||||
"$ref": "#/definitions/tables.Building" |
||||
} |
||||
}, |
||||
"seed": { |
||||
"type": "integer" |
||||
}, |
||||
"tacticalStreetFeatures": { |
||||
"type": "array", |
||||
"items": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
"theme": { |
||||
"type": "string" |
||||
}, |
||||
"upperClassBuildings": { |
||||
"type": "array", |
||||
"items": { |
||||
"$ref": "#/definitions/tables.Building" |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"tables.Faction": { |
||||
"type": "object", |
||||
"properties": { |
||||
"goal": { |
||||
"type": "string" |
||||
}, |
||||
"trait": { |
||||
"type": "string" |
||||
}, |
||||
"type": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
}, |
||||
"tables.Monster": { |
||||
"type": "object", |
||||
"properties": { |
||||
"ability": { |
||||
"type": "string" |
||||
}, |
||||
"base": { |
||||
"type": "string" |
||||
}, |
||||
"feature": { |
||||
"type": "string" |
||||
}, |
||||
"personality": { |
||||
"type": "string" |
||||
}, |
||||
"seed": { |
||||
"type": "integer" |
||||
}, |
||||
"stats": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStats" |
||||
}, |
||||
"tactics": { |
||||
"type": "string" |
||||
}, |
||||
"trait": { |
||||
"type": "string" |
||||
}, |
||||
"weakness": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
}, |
||||
"tables.MonsterStat": { |
||||
"type": "object", |
||||
"properties": { |
||||
"qualifier": { |
||||
"type": "string" |
||||
}, |
||||
"value": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
}, |
||||
"tables.MonsterStats": { |
||||
"type": "object", |
||||
"properties": { |
||||
"armor": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"attack": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"dex": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"health": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"str": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
}, |
||||
"wil": { |
||||
"type": "object", |
||||
"$ref": "#/definitions/tables.MonsterStat" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,290 @@ |
||||
basePath: / |
||||
definitions: |
||||
tables.Building: |
||||
properties: |
||||
rooms: |
||||
items: |
||||
type: string |
||||
type: array |
||||
tacticalFeature: |
||||
type: string |
||||
type: |
||||
type: string |
||||
type: object |
||||
tables.Character: |
||||
properties: |
||||
appearance: |
||||
type: string |
||||
background: |
||||
type: string |
||||
clothing: |
||||
type: string |
||||
feature: |
||||
type: string |
||||
items: |
||||
items: |
||||
type: string |
||||
type: array |
||||
mannerism: |
||||
type: string |
||||
name: |
||||
type: string |
||||
personality: |
||||
type: string |
||||
physical_detail: |
||||
type: string |
||||
seed: |
||||
type: integer |
||||
stats: |
||||
$ref: '#/definitions/tables.CharacterStats' |
||||
type: object |
||||
weapons: |
||||
items: |
||||
type: string |
||||
type: array |
||||
type: object |
||||
tables.CharacterStats: |
||||
properties: |
||||
armor: |
||||
type: integer |
||||
dex: |
||||
type: integer |
||||
max_health: |
||||
type: integer |
||||
str: |
||||
type: integer |
||||
wil: |
||||
type: integer |
||||
type: object |
||||
tables.City: |
||||
properties: |
||||
activities: |
||||
items: |
||||
type: string |
||||
type: array |
||||
districtThemes: |
||||
items: |
||||
type: string |
||||
type: array |
||||
events: |
||||
items: |
||||
type: string |
||||
type: array |
||||
factions: |
||||
items: |
||||
$ref: '#/definitions/tables.Faction' |
||||
type: array |
||||
lowerClassBuildings: |
||||
items: |
||||
$ref: '#/definitions/tables.Building' |
||||
type: array |
||||
seed: |
||||
type: integer |
||||
tacticalStreetFeatures: |
||||
items: |
||||
type: string |
||||
type: array |
||||
theme: |
||||
type: string |
||||
upperClassBuildings: |
||||
items: |
||||
$ref: '#/definitions/tables.Building' |
||||
type: array |
||||
type: object |
||||
tables.Faction: |
||||
properties: |
||||
goal: |
||||
type: string |
||||
trait: |
||||
type: string |
||||
type: |
||||
type: string |
||||
type: object |
||||
tables.Monster: |
||||
properties: |
||||
ability: |
||||
type: string |
||||
base: |
||||
type: string |
||||
feature: |
||||
type: string |
||||
personality: |
||||
type: string |
||||
seed: |
||||
type: integer |
||||
stats: |
||||
$ref: '#/definitions/tables.MonsterStats' |
||||
type: object |
||||
tactics: |
||||
type: string |
||||
trait: |
||||
type: string |
||||
weakness: |
||||
type: string |
||||
type: object |
||||
tables.MonsterStat: |
||||
properties: |
||||
qualifier: |
||||
type: string |
||||
value: |
||||
type: integer |
||||
type: object |
||||
tables.MonsterStats: |
||||
properties: |
||||
armor: |
||||
$ref: '#/definitions/tables.MonsterStat' |
||||
type: object |
||||
attack: |
||||
$ref: '#/definitions/tables.MonsterStat' |
||||
type: object |
||||
dex: |
||||
$ref: '#/definitions/tables.MonsterStat' |
||||
type: object |
||||
health: |
||||
$ref: '#/definitions/tables.MonsterStat' |
||||
type: object |
||||
str: |
||||
$ref: '#/definitions/tables.MonsterStat' |
||||
type: object |
||||
wil: |
||||
$ref: '#/definitions/tables.MonsterStat' |
||||
type: object |
||||
type: object |
||||
info: |
||||
contact: {} |
||||
license: {} |
||||
title: Maze Rats API |
||||
paths: |
||||
/api/character/{seed}: |
||||
get: |
||||
parameters: |
||||
- description: Int64 |
||||
in: path |
||||
name: seed |
||||
required: true |
||||
type: integer |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": |
||||
description: OK |
||||
schema: |
||||
$ref: '#/definitions/tables.Character' |
||||
summary: Generate a specific player character using a seed |
||||
tags: |
||||
- character |
||||
/api/city/{seed}: |
||||
get: |
||||
parameters: |
||||
- description: Int64 |
||||
in: path |
||||
name: seed |
||||
required: true |
||||
type: integer |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": |
||||
description: OK |
||||
schema: |
||||
$ref: '#/definitions/tables.City' |
||||
summary: Generate a specific city using a seed |
||||
tags: |
||||
- city |
||||
/api/generate/character: |
||||
get: |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": |
||||
description: OK |
||||
schema: |
||||
$ref: '#/definitions/tables.Character' |
||||
summary: Generate a player character |
||||
tags: |
||||
- character |
||||
/api/generate/city: |
||||
get: |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": |
||||
description: OK |
||||
schema: |
||||
$ref: '#/definitions/tables.City' |
||||
summary: Generate a city |
||||
tags: |
||||
- city |
||||
/api/generate/monster: |
||||
get: |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": |
||||
description: OK |
||||
schema: |
||||
$ref: '#/definitions/tables.Monster' |
||||
summary: Generate a monster |
||||
tags: |
||||
- monster |
||||
/api/generate/name: |
||||
get: |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": {} |
||||
summary: Generate a character name |
||||
tags: |
||||
- character |
||||
/api/generate/spell: |
||||
get: |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": {} |
||||
summary: Generate a spell |
||||
tags: |
||||
- magic |
||||
/api/monster/{seed}: |
||||
get: |
||||
parameters: |
||||
- description: Int64 |
||||
in: path |
||||
name: seed |
||||
required: true |
||||
type: integer |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": |
||||
description: OK |
||||
schema: |
||||
$ref: '#/definitions/tables.Monster' |
||||
summary: Generate a specific monster using a seed |
||||
tags: |
||||
- monster |
||||
/api/roll/{xdy}: |
||||
get: |
||||
parameters: |
||||
- description: Roll in xdy format (e.g. 1d6) |
||||
in: path |
||||
name: xdy |
||||
required: true |
||||
type: string |
||||
produces: |
||||
- application/json |
||||
- ' text/plain' |
||||
responses: |
||||
"200": {} |
||||
summary: Roll some dice |
||||
tags: |
||||
- dice |
||||
swagger: "2.0" |
Loading…
Reference in new issue