diff --git a/cmd/generate.go b/cmd/generate.go index e99f448..a7f220c 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -77,9 +77,21 @@ var generateSpellCmd = &cobra.Command{ 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) + i := t.Spell(t.Roller.TableRoll()) + output, err := buildOutput(i, "{{.}}", flagFormat) + if err != nil { + panic(err) + } + fmt.Printf(output) + }, +} + +var generateNPCCmd = &cobra.Command{ + Use: "npc", + Short: "Generate an NPC", + Run: func(cmd *cobra.Command, args []string) { + t := tables.NPCTable{Roller: dice.NewRoller(flagSeed)} + output, err := buildOutput(t.Generate(), t.Template(), flagFormat) if err != nil { panic(err) } @@ -115,4 +127,5 @@ func init() { generateCmd.AddCommand(generateMonsterCmd) generateCmd.AddCommand(generateNameCmd) generateCmd.AddCommand(generateSpellCmd) + generateCmd.AddCommand(generateNPCCmd) } diff --git a/go.mod b/go.mod index 7e9e7af..7eb43f6 100644 --- a/go.mod +++ b/go.mod @@ -5,17 +5,17 @@ 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/spec v0.19.9 // 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/mailru/easyjson v0.7.2 // 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-20200717024301-6ddee64345a6 // indirect + golang.org/x/tools v0.0.0-20200727233628-55644ead90ce // indirect gopkg.in/yaml.v2 v2.3.0 // indirect ) diff --git a/go.sum b/go.sum index c3f478d..7df1a93 100644 --- a/go.sum +++ b/go.sum @@ -53,11 +53,15 @@ github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3Hfo 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/jsonreference v0.19.4 h1:3Vw+rh13uq2JFNxgnMTGE1rnoieU9FmyE1gvnyylsYg= +github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= 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/spec v0.19.9 h1:9z9cbFuZJ7AcvOHKIY+f6Aevb4vObNDkTEyoMfO7rAc= +github.com/go-openapi/spec v0.19.9/go.mod h1:vqK/dIdLGCosfvYsQV3WfC7N3TiZSnGY2RZKoFK7X28= 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= @@ -86,6 +90,8 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T 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/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 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= @@ -104,6 +110,8 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq 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/mailru/easyjson v0.7.2 h1:V9ecaZWDYm7v9uJ15RZD6DajMu5sE0hdep0aoDwT9g4= +github.com/mailru/easyjson v0.7.2/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 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= @@ -248,6 +256,10 @@ golang.org/x/tools v0.0.0-20200715235423-130c9f19d3fe h1:q+DqTBqwpg3C8p5kTZ0WSLO golang.org/x/tools v0.0.0-20200715235423-130c9f19d3fe/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6 h1:nULzSsKgihxFGLnQFv2T7lE5vIhOtg8ZPpJHapEt7o0= golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305 h1:yaM5S0KcY0lIoZo7Fl+oi91b/DdlU2zuWpfHrpWbCS0= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200727233628-55644ead90ce h1:HEwYEPqqa3/M0N2Q6IgtBaf2CaxvmRiVdAhX6LR7uE4= +golang.org/x/tools v0.0.0-20200727233628-55644ead90ce/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= diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 0674187..1817191 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -11,6 +11,7 @@ func LoadHandlers(r *mux.Router) { r.HandleFunc("/api/generate/name", GenName) r.HandleFunc("/api/generate/spell", GenSpell) + r.HandleFunc("/api/generate/potion", GenPotion) r.HandleFunc("/api/generate/mutation", GenMutation) r.HandleFunc("/api/generate/insanity", GenInsanity) r.HandleFunc("/api/generate/catastrophe", GenCatastrophe) @@ -21,6 +22,11 @@ func LoadHandlers(r *mux.Router) { r.HandleFunc("/api/generate/character", GenCharacter) r.HandleFunc("/api/character/{seed}", Character) + r.HandleFunc("/api/generate/npc", GenNPC) + r.HandleFunc("/api/npc/{seed}", NPC) + + r.HandleFunc("/api/generate/character", GenCharacter) + r.HandleFunc("/api/generate/city", GenCity) r.HandleFunc("/api/city/{seed}", City) diff --git a/internal/handlers/magic.go b/internal/handlers/magic.go index 70af835..2614b23 100644 --- a/internal/handlers/magic.go +++ b/internal/handlers/magic.go @@ -15,7 +15,8 @@ import ( // @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()) + s := t.Spell(t.Roller.TableRoll()) + WriteResponse(w, r, s, "{{.}}") } // @Summary Generate a mutation @@ -26,8 +27,8 @@ func GenSpell(w http.ResponseWriter, r *http.Request) { // @Success 200 func GenMutation(w http.ResponseWriter, r *http.Request) { t := tables.MagicTable{Roller: dice.NewRoller(time.Now().UnixNano())} - mutation := t.Mutation(t.Roller.TableRoll()) - WriteResponse(w, r, mutation, "{{.}}") + m := t.Mutation(t.Roller.TableRoll()) + WriteResponse(w, r, m, "{{.}}") } // @Summary Generate a insanity diff --git a/internal/handlers/npc.go b/internal/handlers/npc.go new file mode 100644 index 0000000..31e6456 --- /dev/null +++ b/internal/handlers/npc.go @@ -0,0 +1,41 @@ +package handlers + +import ( + "fmt" + "github.com/gorilla/mux" + "mazeratsgen/internal/dice" + "mazeratsgen/internal/tables" + "net/http" + "strconv" + "time" +) + +// @Summary Generate an NPC +// @Tags NPC +// @Produce application/json, text/plain +// @Method GET +// @Router /api/generate/npc [get] +// @Success 200 {object} tables.NPC +func GenNPC(w http.ResponseWriter, r *http.Request) { + t := tables.NPCTable{Roller: dice.NewRoller(time.Now().UnixNano())} + WriteResponse(w, r, t.Generate(), t.Template()) +} + +// @Summary Generate a specific NPC using a seed +// @Tags NPC +// @Produce application/json, text/plain +// @Method GET +// @Router /api/npc/{seed} [get] +// @Param seed path int64 true "Int64" +// @Success 200 {object} tables.NPC +func NPC(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.NPCTable{Roller: dice.NewRoller(seed)} + WriteResponse(w, r, t.Generate(), t.Template()) +} diff --git a/internal/handlers/treasure.go b/internal/handlers/treasure.go new file mode 100644 index 0000000..b184872 --- /dev/null +++ b/internal/handlers/treasure.go @@ -0,0 +1,19 @@ +package handlers + +import ( + "mazeratsgen/internal/dice" + "mazeratsgen/internal/tables" + "net/http" + "time" +) + +// @Summary Generate a potion +// @Tags treasure +// @Produce application/json, text/plain +// @Method GET +// @Router /api/generate/potion [get] +// @Success 200 +func GenPotion(w http.ResponseWriter, r *http.Request) { + t := tables.TreasureTable{Roller: dice.NewRoller(time.Now().UnixNano())} + WriteResponse(w, r, t.GenPotion(), t.PotionTemplate()) +} diff --git a/internal/tables/character.go b/internal/tables/character.go index c801994..d4d773d 100644 --- a/internal/tables/character.go +++ b/internal/tables/character.go @@ -86,7 +86,7 @@ func (t *CharacterTable) Generate() Character { } } -func (t CharacterTable) Template() string { +func (t *CharacterTable) Template() string { return strings.TrimSpace(` Name: {{.Name}} Feature: {{.Feature}} diff --git a/internal/tables/city.go b/internal/tables/city.go index 6aeedb7..82b6738 100644 --- a/internal/tables/city.go +++ b/internal/tables/city.go @@ -129,7 +129,8 @@ func (t *CityTable) CityTheme(roll [2]int) string { 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()) + npcTable := NPCTable{Roller: t.Roller} + return npcTable.DivineDomain(t.Roller.TableRoll()) case [2]int{3, 1}: return t.GenFaction(t.Roller.TableRoll()).Type case [2]int{3, 5}: @@ -172,14 +173,14 @@ func (t *CityTable) DistrictTheme(roll [2]int) string { } } -func (t CityTable) GenBuilding(roll int) Building { +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 { +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()), @@ -187,7 +188,7 @@ func (t CityTable) UpperClassBuilding(roll [2]int) Building { } } -func (t CityTable) LowerClassBuilding(roll [2]int) Building { +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()), @@ -195,7 +196,7 @@ func (t CityTable) LowerClassBuilding(roll [2]int) Building { } } -func (t CityTable) BuildingRoom(roll [2]int) string { +func (t *CityTable) BuildingRoom(roll [2]int) string { switch roll { case [2]int{3, 1}: return MazeTable{Roller: t.Roller}.DungeonRoom(t.Roller.TableRoll()) @@ -204,7 +205,7 @@ func (t CityTable) BuildingRoom(roll [2]int) string { } } -func (t CityTable) TacticalStreetFeature(roll [2]int) string { +func (t *CityTable) TacticalStreetFeature(roll [2]int) string { mazeTable := MazeTable{Roller: t.Roller} switch roll { case [2]int{2, 3}: @@ -218,26 +219,27 @@ func (t CityTable) TacticalStreetFeature(roll [2]int) string { } } -func (t CityTable) TacticalBuildingFeature(roll [2]int) string { +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" + 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 { +func (t *CityTable) FactionTrait(roll [2]int) string { switch roll { case [2]int{4, 4}: - return NPCTable{Roller: t.Roller}.Personality(t.Roller.TableRoll()) + npcTable := NPCTable{Roller: t.Roller} + return npcTable.Personality(t.Roller.TableRoll()) default: return data.Tables.City.FactionTraits[roll[0]-1][roll[1]-1] } } -func (t CityTable) GenFaction(roll [2]int) Faction { +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()), @@ -245,7 +247,7 @@ func (t CityTable) GenFaction(roll [2]int) Faction { } } -func (t CityTable) FactionGoal(roll [2]int) string { +func (t *CityTable) FactionGoal(roll [2]int) string { switch roll { case [2]int{1, 6}: return "Control " + t.GenFaction(t.Roller.TableRoll()).Type @@ -260,12 +262,13 @@ func (t CityTable) FactionGoal(roll [2]int) string { } } -func (t CityTable) CityActivity(roll [2]int) string { +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()) + npcTable := NPCTable{Roller: t.Roller} + return npcTable.Mission(t.Roller.TableRoll()) case [2]int{6, 6}: return WildTable{Roller: t.Roller}.WildernessActivity(t.Roller.TableRoll()) default: diff --git a/internal/tables/magic.go b/internal/tables/magic.go index 741d653..4c4e69a 100644 --- a/internal/tables/magic.go +++ b/internal/tables/magic.go @@ -9,14 +9,6 @@ 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: @@ -134,7 +126,8 @@ func (t MagicTable) Insanity(roll [2]int) string { 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()) + npcTable := NPCTable{Roller: t.Roller} + return npcTable.Personality(t.Roller.TableRoll()) default: return data.Tables.Magic.Insanities[roll[0]-1][roll[1]-1] } diff --git a/internal/tables/npc.go b/internal/tables/npc.go index c06c1b9..d989d97 100644 --- a/internal/tables/npc.go +++ b/internal/tables/npc.go @@ -4,6 +4,7 @@ import ( "mazeratsgen/internal/data" "mazeratsgen/internal/dice" "mazeratsgen/internal/helpers" + "strings" ) type NPCTable struct { @@ -32,31 +33,30 @@ type NPC struct { Misfortunes []string Missions []string Methods []string + Seed int64 } -func GenNPC(seed int64) NPC { - roller := dice.NewRoller(seed) - npcTable := NPCTable{Roller: roller} +func (t *NPCTable) Generate() NPC { var occupation, class, gender string - occupationRoll, _ := roller.Roll("1d3") + occupationRoll, _ := t.Roller.Roll("1d3") switch occupationRoll[0] { case 1: - occupation = npcTable.CivilizedNPC(roller.TableRoll()) + occupation = t.CivilizedNPC(t.Roller.TableRoll()) case 2: - occupation = npcTable.UnderworldNPC(roller.TableRoll()) + occupation = t.UnderworldNPC(t.Roller.TableRoll()) case 3: - occupation = npcTable.WildernessNPC(roller.TableRoll()) + occupation = t.WildernessNPC(t.Roller.TableRoll()) } - classRoll, _ := roller.Roll("1d2") + classRoll, _ := t.Roller.Roll("1d2") if classRoll[0] == 1 { class = "Upperclass" } else { class = "Lowerclass" } - genderRoll, _ := roller.Roll("1d2") + genderRoll, _ := t.Roller.Roll("1d2") if genderRoll[0] == 1 { gender = "Male" } else { @@ -64,59 +64,105 @@ func GenNPC(seed int64) NPC { } return NPC{ - Name: GenName(class, gender, seed).FullName, + Name: GenName(class, gender, t.Roller.Seed).FullName, + Gender: gender, 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), + Appearance: t.Appearance(t.Roller.TableRoll()), + PhysicalDetail: t.PhysicalDetail(t.Roller.TableRoll()), + Clothing: t.Clothing(t.Roller.TableRoll()), + Personality: t.Personality(t.Roller.TableRoll()), + Mannerism: t.Mannerism(t.Roller.TableRoll()), + Secret: t.Secret(t.Roller.TableRoll()), + Reputation: t.Reputation(t.Roller.TableRoll()), + Relationship: t.Relationship(t.Roller.TableRoll()), + Hobby: t.Hobby(t.Roller.TableRoll()), + DivineDomain: t.DivineDomain(t.Roller.TableRoll()), + AfterTheParty: t.AfterTheParty(t.Roller.TableRoll()), + Assets: helpers.GenUniqueItems(3, t.Asset, t.Roller.Seed), + Liabilities: helpers.GenUniqueItems(3, t.Liability, t.Roller.Seed), + Goals: helpers.GenUniqueItems(3, t.NPCGoal, t.Roller.Seed), + Misfortunes: helpers.GenUniqueItems(3, t.Misfortune, t.Roller.Seed), + Missions: helpers.GenUniqueItems(3, t.Mission, t.Roller.Seed), + Methods: helpers.GenUniqueItems(3, t.Method, t.Roller.Seed), + Seed: t.Roller.Seed, } } -func (t NPCTable) CivilizedNPC(tableRole [2]int) string { +func (t *NPCTable) Template() string { + return strings.TrimSpace(` +Name: {{.Name}} +Gender: {{.Gender}} +Class: {{.Class}} +Occupation: {{.Occupation}} +Appearance: {{.Appearance}} +Physical Detail: {{.PhysicalDetail}} +Clothing: {{.Clothing}} +Personality: {{.Personality}} +Mannerism: {{.Mannerism}} +Secret: {{.Secret}} +Reputation: {{.Reputation}} +Relationship: {{.Relationship}} +Hobby: {{.Hobby}} +Divine Domain: {{.DivineDomain}} +After The Party: {{.AfterTheParty}} +Assets: +{{- range $asset := .Assets }} + {{$asset}} +{{- end}} +Liabilities: +{{- range $liability := .Liabilities }} + {{$liability}} +{{- end}} +Goal: +{{- range $goal := .Goals }} + {{$goal}} +{{- end}} +Misfortunes: +{{- range $misfortune := .Misfortunes }} + {{$misfortune}} +{{- end}} +Missions: +{{- range $mission := .Missions }} + {{$mission}} +{{- end}} +Methods: +{{- range $method := .Methods }} + {{$method}} +{{- end}} +Seed: {{.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 { +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 { +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 { +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 { +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 { +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 { +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 { +func (t *NPCTable) Asset(tableRole [2]int) string { switch tableRole { case [2]int{2, 3}: return "Leader of existing faction" @@ -127,7 +173,7 @@ func (t NPCTable) Asset(tableRole [2]int) string { } } -func (t NPCTable) Liability(tableRole [2]int) string { +func (t *NPCTable) Liability(tableRole [2]int) string { switch tableRole { case [2]int{3, 1}: return MagicTable{Roller: t.Roller}.Insanity(t.Roller.TableRoll()) @@ -136,7 +182,7 @@ func (t NPCTable) Liability(tableRole [2]int) string { } } -func (t NPCTable) NPCGoal(tableRole [2]int) string { +func (t *NPCTable) NPCGoal(tableRole [2]int) string { treasureTable := TreasureTable{Roller: t.Roller} switch tableRole { case [2]int{1, 3}: @@ -172,39 +218,39 @@ func (t NPCTable) NPCGoal(tableRole [2]int) string { } } -func (t NPCTable) Misfortune(tableRole [2]int) string { +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 { +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 { +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 { +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 { +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 { +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 { +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 { +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 { +func (t *NPCTable) Secret(tableRole [2]int) string { switch tableRole { case [2]int{4, 5}: return t.Misfortune(t.Roller.TableRoll()) @@ -215,19 +261,19 @@ func (t NPCTable) Secret(tableRole [2]int) string { } } -func (t NPCTable) Reputation(tableRole [2]int) string { +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 { +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 { +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 { +func (t *NPCTable) DivineDomain(tableRole [2]int) string { switch tableRole { case [2]int{1, 1}: roll, _ := t.Roller.Roll("1d6") @@ -242,7 +288,7 @@ func (t NPCTable) DivineDomain(tableRole [2]int) string { } } -func (t NPCTable) AfterTheParty(tableRole [2]int) string { +func (t *NPCTable) AfterTheParty(tableRole [2]int) string { switch tableRole { case [2]int{3, 3}: return "Insulted an existing faction" diff --git a/internal/tables/tables.go b/internal/tables/tables.go index add3d17..3cffd06 100644 --- a/internal/tables/tables.go +++ b/internal/tables/tables.go @@ -7,8 +7,6 @@ import ( "text/template" ) -// TODO: Add GenRandomName - type Name struct { FirstName string LastName string diff --git a/internal/tables/treasure.go b/internal/tables/treasure.go index de865e9..4a124e6 100644 --- a/internal/tables/treasure.go +++ b/internal/tables/treasure.go @@ -4,6 +4,7 @@ import ( "mazeratsgen/internal/data" "mazeratsgen/internal/dice" "mazeratsgen/internal/helpers" + "strings" ) type TreasureTable struct { @@ -16,32 +17,41 @@ type Potion struct { 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()) +func (t *TreasureTable) GenTreasure() string { + treasureTable := TreasureTable{Roller: t.Roller} + trait := treasureTable.TreasureTrait(t.Roller.TableRoll()) + item := treasureTable.TreasureItem(t.Roller.TableRoll()) return trait + " " + item } -func GenPotion(seed int64) Potion { - roller := dice.NewRoller(seed) - magicTable := MagicTable{Roller: roller} - treasureTable := TreasureTable{Roller: roller} +func (t *TreasureTable) PotionTemplate() string { + return strings.TrimSpace(` +Effect: {{.Effect}} +Ingredients: +{{- range $ingredient := .Ingredients}} + {{$ingredient}} +{{- end}} +Failure: {{.OnFailure}} + `) +} + +func (t *TreasureTable) GenPotion() Potion { + magicTable := MagicTable{Roller: t.Roller} + treasureTable := TreasureTable{Roller: t.Roller} var onFailure string - onFailRoll, _ := roller.Roll("1d2") + onFailRoll, _ := t.Roller.Roll("1d2") if onFailRoll[0] == 1 { - onFailure = magicTable.Mutation(roller.TableRoll()) + onFailure = magicTable.Mutation(t.Roller.TableRoll()) } else { - onFailure = magicTable.Insanity(roller.TableRoll()) + onFailure = magicTable.Insanity(t.Roller.TableRoll()) } - ingredientRoll, _ := roller.Roll("1d3") + ingredientRoll, _ := t.Roller.Roll("1d3") return Potion{ - Effect: treasureTable.PotionBase(roller.TableRoll()), + Effect: treasureTable.PotionBase(t.Roller.TableRoll()), OnFailure: onFailure, - Ingredients: helpers.GenUniqueItems(ingredientRoll[0], treasureTable.MagicalIngredient, seed), + Ingredients: helpers.GenUniqueItems(ingredientRoll[0], treasureTable.MagicalIngredient, t.Roller.Seed), } } diff --git a/internal/tables/wild.go b/internal/tables/wild.go index 0526ec0..65aaad0 100644 --- a/internal/tables/wild.go +++ b/internal/tables/wild.go @@ -101,9 +101,11 @@ func (t WildTable) WildernessRegionTrait(roll [2]int) string { func (t WildTable) WildernessDiscovery(roll [2]int) string { switch roll { case [2]int{1, 5}: - return CityTable{Roller: t.Roller}.CityActivity(t.Roller.TableRoll()) + t := CityTable{Roller: t.Roller} + return t.CityActivity(t.Roller.TableRoll()) case [2]int{1, 6}: - return NPCTable{Roller: t.Roller}.CivilizedNPC(t.Roller.TableRoll()) + npcTable := NPCTable{Roller: t.Roller} + return npcTable.CivilizedNPC(t.Roller.TableRoll()) case [2]int{2, 3}: return MazeTable{Roller: t.Roller}.DungeonActivity(t.Roller.TableRoll()) case [2]int{3, 1}: @@ -115,7 +117,8 @@ func (t WildTable) WildernessDiscovery(roll [2]int) string { case [2]int{5, 1}: return "Lost an existing NPC" case [2]int{6, 1}: - return NPCTable{Roller: t.Roller}.UnderworldNPC(t.Roller.TableRoll()) + npcTable := NPCTable{Roller: t.Roller} + return npcTable.UnderworldNPC(t.Roller.TableRoll()) case [2]int{6, 2}: return WildTable{Roller: t.Roller}.WildernessActivity(t.Roller.TableRoll()) case [2]int{6, 3}: @@ -123,7 +126,8 @@ func (t WildTable) WildernessDiscovery(roll [2]int) string { 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()) + npcTable := NPCTable{Roller: t.Roller} + return npcTable.WildernessNPC(t.Roller.TableRoll()) default: return data.Tables.Wild.WildernessDiscoveries[roll[0]-1][roll[1]-1] } @@ -132,7 +136,8 @@ func (t WildTable) WildernessDiscovery(roll [2]int) string { func (t WildTable) WildernessActivity(roll [2]int) string { switch roll { case [2]int{2, 1}: - return CityTable{Roller: t.Roller}.CityActivity(t.Roller.TableRoll()) + t := CityTable{Roller: t.Roller} + return t.CityActivity(t.Roller.TableRoll()) case [2]int{2, 6}: return MazeTable{Roller: t.Roller}.DungeonActivity(t.Roller.TableRoll()) default: diff --git a/web/swagger/docs.go b/web/swagger/docs.go index 0e80aa3..2fbee1a 100644 --- a/web/swagger/docs.go +++ b/web/swagger/docs.go @@ -252,6 +252,41 @@ var doc = `{ } } }, + "/api/generate/npc": { + "get": { + "produces": [ + "application/json", + " text/plain" + ], + "tags": [ + "NPC" + ], + "summary": "Generate an NPC", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/tables.NPC" + } + } + } + } + }, + "/api/generate/potion": { + "get": { + "produces": [ + "application/json", + " text/plain" + ], + "tags": [ + "treasure" + ], + "summary": "Generate a potion", + "responses": { + "200": {} + } + } + }, "/api/generate/spell": { "get": { "produces": [ @@ -296,6 +331,35 @@ var doc = `{ } } }, + "/api/npc/{seed}": { + "get": { + "produces": [ + "application/json", + " text/plain" + ], + "tags": [ + "NPC" + ], + "summary": "Generate a specific NPC using a seed", + "parameters": [ + { + "type": "integer", + "description": "Int64", + "name": "seed", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/tables.NPC" + } + } + } + } + }, "/api/roll/{xdy}": { "get": { "produces": [ @@ -510,6 +574,9 @@ var doc = `{ "ruination": { "type": "string" }, + "seed": { + "type": "integer" + }, "trapEffects": { "type": "array", "items": { @@ -602,6 +669,92 @@ var doc = `{ "$ref": "#/definitions/tables.MonsterStat" } } + }, + "tables.NPC": { + "type": "object", + "properties": { + "afterTheParty": { + "type": "string" + }, + "appearance": { + "type": "string" + }, + "assets": { + "type": "array", + "items": { + "type": "string" + } + }, + "class": { + "type": "string" + }, + "clothing": { + "type": "string" + }, + "divineDomain": { + "type": "string" + }, + "gender": { + "type": "string" + }, + "goals": { + "type": "array", + "items": { + "type": "string" + } + }, + "hobby": { + "type": "string" + }, + "liabilities": { + "type": "array", + "items": { + "type": "string" + } + }, + "mannerism": { + "type": "string" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + } + }, + "misfortunes": { + "type": "array", + "items": { + "type": "string" + } + }, + "missions": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "occupation": { + "type": "string" + }, + "personality": { + "type": "string" + }, + "physicalDetail": { + "type": "string" + }, + "relationship": { + "type": "string" + }, + "reputation": { + "type": "string" + }, + "secret": { + "type": "string" + } + } } } }` diff --git a/web/swagger/swagger.json b/web/swagger/swagger.json index 631cfd5..3335e6d 100644 --- a/web/swagger/swagger.json +++ b/web/swagger/swagger.json @@ -234,6 +234,41 @@ } } }, + "/api/generate/npc": { + "get": { + "produces": [ + "application/json", + " text/plain" + ], + "tags": [ + "NPC" + ], + "summary": "Generate an NPC", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/tables.NPC" + } + } + } + } + }, + "/api/generate/potion": { + "get": { + "produces": [ + "application/json", + " text/plain" + ], + "tags": [ + "treasure" + ], + "summary": "Generate a potion", + "responses": { + "200": {} + } + } + }, "/api/generate/spell": { "get": { "produces": [ @@ -278,6 +313,35 @@ } } }, + "/api/npc/{seed}": { + "get": { + "produces": [ + "application/json", + " text/plain" + ], + "tags": [ + "NPC" + ], + "summary": "Generate a specific NPC using a seed", + "parameters": [ + { + "type": "integer", + "description": "Int64", + "name": "seed", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/tables.NPC" + } + } + } + } + }, "/api/roll/{xdy}": { "get": { "produces": [ @@ -492,6 +556,9 @@ "ruination": { "type": "string" }, + "seed": { + "type": "integer" + }, "trapEffects": { "type": "array", "items": { @@ -584,6 +651,92 @@ "$ref": "#/definitions/tables.MonsterStat" } } + }, + "tables.NPC": { + "type": "object", + "properties": { + "afterTheParty": { + "type": "string" + }, + "appearance": { + "type": "string" + }, + "assets": { + "type": "array", + "items": { + "type": "string" + } + }, + "class": { + "type": "string" + }, + "clothing": { + "type": "string" + }, + "divineDomain": { + "type": "string" + }, + "gender": { + "type": "string" + }, + "goals": { + "type": "array", + "items": { + "type": "string" + } + }, + "hobby": { + "type": "string" + }, + "liabilities": { + "type": "array", + "items": { + "type": "string" + } + }, + "mannerism": { + "type": "string" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + } + }, + "misfortunes": { + "type": "array", + "items": { + "type": "string" + } + }, + "missions": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "occupation": { + "type": "string" + }, + "personality": { + "type": "string" + }, + "physicalDetail": { + "type": "string" + }, + "relationship": { + "type": "string" + }, + "reputation": { + "type": "string" + }, + "secret": { + "type": "string" + } + } } } } \ No newline at end of file diff --git a/web/swagger/swagger.yaml b/web/swagger/swagger.yaml index dccf784..c229425 100644 --- a/web/swagger/swagger.yaml +++ b/web/swagger/swagger.yaml @@ -124,6 +124,8 @@ definitions: type: array ruination: type: string + seed: + type: integer trapEffects: items: type: string @@ -187,6 +189,63 @@ definitions: $ref: '#/definitions/tables.MonsterStat' type: object type: object + tables.NPC: + properties: + afterTheParty: + type: string + appearance: + type: string + assets: + items: + type: string + type: array + class: + type: string + clothing: + type: string + divineDomain: + type: string + gender: + type: string + goals: + items: + type: string + type: array + hobby: + type: string + liabilities: + items: + type: string + type: array + mannerism: + type: string + methods: + items: + type: string + type: array + misfortunes: + items: + type: string + type: array + missions: + items: + type: string + type: array + name: + type: string + occupation: + type: string + personality: + type: string + physicalDetail: + type: string + relationship: + type: string + reputation: + type: string + secret: + type: string + type: object info: contact: {} license: {} @@ -341,6 +400,29 @@ paths: summary: Generate a character name tags: - character + /api/generate/npc: + get: + produces: + - application/json + - ' text/plain' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/tables.NPC' + summary: Generate an NPC + tags: + - NPC + /api/generate/potion: + get: + produces: + - application/json + - ' text/plain' + responses: + "200": {} + summary: Generate a potion + tags: + - treasure /api/generate/spell: get: produces: @@ -370,6 +452,25 @@ paths: summary: Generate a specific monster using a seed tags: - monster + /api/npc/{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.NPC' + summary: Generate a specific NPC using a seed + tags: + - NPC /api/roll/{xdy}: get: parameters: