diff --git a/cmd/internal/docs/api.go b/cmd/internal/docs/api.go
new file mode 100644
index 0000000..2cdedb5
--- /dev/null
+++ b/cmd/internal/docs/api.go
@@ -0,0 +1,116 @@
+package main
+
+import (
+ "fmt"
+ "github.com/BigJk/end_of_eden/game"
+ "github.com/BigJk/end_of_eden/internal/lua/ludoc"
+ "github.com/samber/lo"
+ "regexp"
+ "sort"
+ "strings"
+)
+
+const globTemplate = ` %s
+
+%s
+
+
+
+`
+
+const fnTemplate = ` %s
+
+%s
+
+**Signature:**
+
+%s
+
+
+
+`
+
+var linkPattern = regexp.MustCompile("[^a-zA-Z\\d\\s:-]")
+
+func functionToMd(fn ludoc.Function) string {
+ signature := fmt.Sprintf("%s(%s) -> %s", fn.Name, strings.Join(fn.Args, ", "), lo.Ternary(len(fn.Return) == 0, "None", fn.Return))
+ return fmt.Sprintf(fnTemplate, fn.Name, fn.Description, "```\n"+signature+"\n```")
+}
+
+func globToMd(glob ludoc.Global) string {
+ return fmt.Sprintf(globTemplate, glob.Name, glob.Description)
+}
+
+func buildAPIDocs() {
+ docs := game.NewSession().LuaDocs()
+
+ // Fetch the globals and functions keys
+ globals := lo.Keys(docs.Globals)
+ functions := lo.Keys(docs.Functions)
+
+ // Sort them
+ sort.Strings(globals)
+ sort.Strings(functions)
+
+ // Get the sorted categories
+ cats := lo.Keys(docs.Categories)
+ sort.SliceStable(cats, func(i, j int) bool {
+ return docs.Categories[cats[i]].Order < docs.Categories[cats[j]].Order
+ })
+
+ // Build index
+ builder := strings.Builder{}
+ builder.WriteString("# End Of Eden Lua Docs\n")
+
+ builder.WriteString("## Index\n\n")
+ for _, key := range cats {
+ cat := docs.Categories[key]
+ builder.WriteString(fmt.Sprintf("- [%s](#%s)\n", cat.Name, linkPattern.ReplaceAllString(strings.ToLower(strings.ReplaceAll(cat.Name, " ", "-")), "")))
+ }
+
+ builder.WriteString("\n")
+
+ // Build docs
+ for _, key := range cats {
+ cat := docs.Categories[key]
+
+ builder.WriteString("## " + cat.Name + "\n\n")
+ builder.WriteString(cat.Description + "\n\n")
+
+ builder.WriteString("### Globals\n")
+
+ hasGlobals := false
+ for _, key := range globals {
+ glob := docs.Globals[key]
+ if glob.Category != cat.Name {
+ continue
+ }
+ builder.WriteString(globToMd(glob))
+ hasGlobals = true
+ }
+
+ if !hasGlobals {
+ builder.WriteString("\nNone\n\n")
+ }
+
+ builder.WriteString("### Functions\n")
+
+ hasFunctions := false
+ for _, key := range functions {
+ fn := docs.Functions[key]
+ if fn.Category != cat.Name {
+ continue
+ }
+ builder.WriteString(functionToMd(fn))
+ hasFunctions = true
+ }
+
+ if !hasFunctions {
+ builder.WriteString("\nNone\n\n")
+ }
+
+ }
+
+ // Output docs
+ fmt.Print(builder.String())
+}
diff --git a/cmd/internal/docs/game_content.go b/cmd/internal/docs/game_content.go
new file mode 100644
index 0000000..f3e7de5
--- /dev/null
+++ b/cmd/internal/docs/game_content.go
@@ -0,0 +1,325 @@
+package main
+
+import (
+ "fmt"
+ "github.com/BigJk/end_of_eden/game"
+ "github.com/acarl005/stripansi"
+ "github.com/alexeyco/simpletable"
+ "github.com/samber/lo"
+ "regexp"
+ "sort"
+ "strings"
+)
+
+func stripSpecial(s string) string {
+ // 1. collapse consecutive newlines
+ newlineRegex := regexp.MustCompile(`\n+`)
+ s = newlineRegex.ReplaceAllString(s, " - ")
+
+ // 2. replace [ with **
+ return strings.ReplaceAll(strings.ReplaceAll(s, "[", "**"), "]", "**")
+}
+
+func makeCode(s string) string {
+ return "``" + s + "``"
+}
+
+func makeCodes(s []string) string {
+ return strings.Join(lo.Map(s, func(s string, i int) string {
+ return makeCode(s)
+ }), ", ")
+}
+
+func makeCodeBlock(s string) string {
+ return "" + strings.ReplaceAll(strings.ReplaceAll(s, "\n", ""), "\\", "\\\\") + " "
+}
+
+func buildGameContentDocs() {
+ res := game.NewSession().GetResources()
+
+ fmt.Println("# Game Content")
+
+ fmt.Println(`This document contains all game content that is available in the game. It is automatically generated and may be out of date.
+Content that is dynamically generated at runtime is not included in this document, only content that is registered at the beginning of a session.
+
+`)
+
+ // Stats
+
+ fmt.Println("\n\n## Stats\n")
+
+ statsTable := simpletable.New()
+ statsTable.Header = &simpletable.Header{
+ Cells: []*simpletable.Cell{
+ {Align: simpletable.AlignCenter, Text: "Type"},
+ {Align: simpletable.AlignCenter, Text: "Count"},
+ },
+ }
+ statsTable.SetStyle(simpletable.StyleMarkdown)
+
+ countArtifacts := len(res.Artifacts)
+ countCards := len(res.Cards)
+ countStatusEffects := len(res.StatusEffects)
+ countEnemies := len(res.Enemies)
+ countEvents := len(res.Events)
+
+ statsTable.Body.Cells = append(statsTable.Body.Cells, []*simpletable.Cell{
+ {Text: "Artifacts"},
+ {Text: fmt.Sprint(countArtifacts)},
+ })
+
+ statsTable.Body.Cells = append(statsTable.Body.Cells, []*simpletable.Cell{
+ {Text: "Cards"},
+ {Text: fmt.Sprint(countCards)},
+ })
+
+ statsTable.Body.Cells = append(statsTable.Body.Cells, []*simpletable.Cell{
+ {Text: "Status Effects"},
+ {Text: fmt.Sprint(countStatusEffects)},
+ })
+
+ statsTable.Body.Cells = append(statsTable.Body.Cells, []*simpletable.Cell{
+ {Text: "Enemies"},
+ {Text: fmt.Sprint(countEnemies)},
+ })
+
+ statsTable.Body.Cells = append(statsTable.Body.Cells, []*simpletable.Cell{
+ {Text: "Events"},
+ {Text: fmt.Sprint(countEvents)},
+ })
+
+ statsTable.Println()
+
+ // Artifacts
+
+ artifactTable := simpletable.New()
+ artifactTable.Header = &simpletable.Header{
+ Cells: []*simpletable.Cell{
+ {Align: simpletable.AlignCenter, Text: "ID"},
+ {Align: simpletable.AlignCenter, Text: "Name"},
+ {Align: simpletable.AlignCenter, Text: "Description"},
+ {Align: simpletable.AlignCenter, Text: "Price"},
+ {Align: simpletable.AlignCenter, Text: "Tags"},
+ {Align: simpletable.AlignCenter, Text: "Test Present"},
+ },
+ }
+ artifactTable.SetStyle(simpletable.StyleMarkdown)
+
+ artifacts := lo.Values(res.Artifacts)
+ sort.SliceStable(artifacts, func(i, j int) bool {
+ return artifacts[i].Price < artifacts[j].Price
+ })
+
+ for _, v := range artifacts {
+ r := []*simpletable.Cell{
+ {Text: "``" + v.ID + "``"},
+ {Text: v.Name},
+ {Text: stripSpecial(stripansi.Strip(v.Description))},
+ {Text: fmt.Sprint(v.Price)},
+ {Text: strings.Join(v.Tags, ", ")},
+ {Text: lo.Ternary(v.Test != nil, ":heavy_check_mark:", ":no_entry_sign:")},
+ }
+
+ artifactTable.Body.Cells = append(artifactTable.Body.Cells, r)
+ }
+
+ fmt.Println("\n\n## Artifacts\n")
+ artifactTable.Println()
+
+ // Cards
+
+ cardTable := simpletable.New()
+ cardTable.Header = &simpletable.Header{
+ Cells: []*simpletable.Cell{
+ {Align: simpletable.AlignCenter, Text: "ID"},
+ {Align: simpletable.AlignCenter, Text: "Name"},
+ {Align: simpletable.AlignCenter, Text: "Description"},
+ {Align: simpletable.AlignCenter, Text: "Action Points"},
+ {Align: simpletable.AlignCenter, Text: "Exhaust"},
+ {Align: simpletable.AlignCenter, Text: "Consumable"},
+ {Align: simpletable.AlignCenter, Text: "Max Level"},
+ {Align: simpletable.AlignCenter, Text: "Price"},
+ {Align: simpletable.AlignCenter, Text: "Tags"},
+ {Align: simpletable.AlignCenter, Text: "Color"},
+ {Align: simpletable.AlignCenter, Text: "Used Callbacks"},
+ {Align: simpletable.AlignCenter, Text: "Test Present"},
+ },
+ }
+ cardTable.SetStyle(simpletable.StyleMarkdown)
+
+ actionPoints := make(map[int]int)
+ cardType := make(map[string]int)
+
+ cards := lo.Values(res.Cards)
+ sort.SliceStable(cards, func(i, j int) bool {
+ return cards[i].Price < cards[j].Price
+ })
+
+ for _, v := range cards {
+ actionPoints[v.PointCost]++
+
+ if v.DoesExhaust {
+ cardType["Exhaust"]++
+ } else if v.DoesConsume {
+ cardType["Consume"]++
+ } else {
+ cardType["Normal"]++
+ }
+
+ r := []*simpletable.Cell{
+ {Text: "``" + v.ID + "``"},
+ {Text: v.Name},
+ {Text: stripSpecial(stripansi.Strip(v.Description))},
+ {Text: fmt.Sprint(v.PointCost)},
+ {Text: lo.Ternary(v.DoesExhaust, ":heavy_check_mark:", ":no_entry_sign:")},
+ {Text: lo.Ternary(v.DoesConsume, ":heavy_check_mark:", ":no_entry_sign:")},
+ {Text: fmt.Sprint(v.MaxLevel)},
+ {Text: fmt.Sprint(v.Price)},
+ {Text: strings.Join(v.Tags, ", ")},
+ {Text: v.Color},
+ {Text: makeCodes(lo.Keys(v.Callbacks))},
+ {Text: lo.Ternary(v.Test != nil, ":heavy_check_mark:", ":no_entry_sign:")},
+ }
+
+ cardTable.Body.Cells = append(cardTable.Body.Cells, r)
+ }
+
+ fmt.Println("\n\n## Cards\n")
+ cardTable.Println()
+
+ fmt.Println("\n\n### Action Points\n")
+
+ fmt.Println(fmt.Sprintf("´´´mermaid\npie title Action Points\n%s\n´´´\n\n", strings.Join(lo.Map(lo.Entries(actionPoints), func(e lo.Entry[int, int], i int) string {
+ return fmt.Sprintf("%d AP: %d", e.Key, e.Value)
+ }), "\n")))
+
+ fmt.Println("\n\n### Card Types\n")
+
+ fmt.Println(fmt.Sprintf("´´´mermaid\npie title Card Types\n%s\n´´´\n\n", strings.Join(lo.Map(lo.Entries(cardType), func(e lo.Entry[string, int], i int) string {
+ return fmt.Sprintf("%s: %d", e.Key, e.Value)
+ }), "\n")))
+
+ // Status Effects
+
+ statusEffectTable := simpletable.New()
+ statusEffectTable.Header = &simpletable.Header{
+ Cells: []*simpletable.Cell{
+ {Align: simpletable.AlignCenter, Text: "ID"},
+ {Align: simpletable.AlignCenter, Text: "Name"},
+ {Align: simpletable.AlignCenter, Text: "Description"},
+ {Align: simpletable.AlignCenter, Text: "Look"},
+ {Align: simpletable.AlignCenter, Text: "Foreground"},
+ {Align: simpletable.AlignCenter, Text: "Can Stack"},
+ {Align: simpletable.AlignCenter, Text: "Decay"},
+ {Align: simpletable.AlignCenter, Text: "Rounds"},
+ {Align: simpletable.AlignCenter, Text: "Used Callbacks"},
+ {Align: simpletable.AlignCenter, Text: "Test Present"},
+ },
+ }
+ statusEffectTable.SetStyle(simpletable.StyleMarkdown)
+
+ statusEffects := lo.Values(res.StatusEffects)
+ sort.SliceStable(statusEffects, func(i, j int) bool {
+ return statusEffects[i].Order < statusEffects[j].Order
+ })
+
+ for _, v := range statusEffects {
+ r := []*simpletable.Cell{
+ {Text: "``" + v.ID + "``"},
+ {Text: v.Name},
+ {Text: stripSpecial(stripansi.Strip(v.Description))},
+ {Text: v.Look},
+ {Text: v.Foreground},
+ {Text: lo.Ternary(v.CanStack, ":heavy_check_mark:", ":no_entry_sign:")},
+ {Text: string(v.Decay)},
+ {Text: fmt.Sprint(v.Rounds)},
+ {Text: makeCodes(lo.Keys(v.Callbacks))},
+ {Text: lo.Ternary(v.Test != nil, ":heavy_check_mark:", ":no_entry_sign:")},
+ }
+
+ statusEffectTable.Body.Cells = append(statusEffectTable.Body.Cells, r)
+ }
+
+ fmt.Println("\n\n## Status Effects\n")
+ statusEffectTable.Println()
+
+ // Enemies
+
+ enemyTable := simpletable.New()
+ enemyTable.Header = &simpletable.Header{
+ Cells: []*simpletable.Cell{
+ {Align: simpletable.AlignCenter, Text: "ID"},
+ {Align: simpletable.AlignCenter, Text: "Name"},
+ {Align: simpletable.AlignCenter, Text: "Description"},
+ {Align: simpletable.AlignCenter, Text: "Initial HP"},
+ {Align: simpletable.AlignCenter, Text: "Max HP"},
+ {Align: simpletable.AlignCenter, Text: "Look"},
+ {Align: simpletable.AlignCenter, Text: "Color"},
+ {Align: simpletable.AlignCenter, Text: "Used Callbacks"},
+ {Align: simpletable.AlignCenter, Text: "Test Present"},
+ },
+ }
+ enemyTable.SetStyle(simpletable.StyleMarkdown)
+
+ enemies := lo.Values(res.Enemies)
+ sort.SliceStable(enemies, func(i, j int) bool {
+ return enemies[i].Name < enemies[j].Name
+ })
+
+ for _, v := range enemies {
+ r := []*simpletable.Cell{
+ {Text: "``" + v.ID + "``"},
+ {Text: v.Name},
+ {Text: stripSpecial(stripansi.Strip(v.Description))},
+ {Text: fmt.Sprint(v.InitialHP)},
+ {Text: fmt.Sprint(v.MaxHP)},
+ {Text: makeCodeBlock(v.Look)},
+ {Text: v.Color},
+ {Text: makeCodes(lo.Keys(v.Callbacks))},
+ {Text: lo.Ternary(v.Test != nil, ":heavy_check_mark:", ":no_entry_sign:")},
+ }
+
+ enemyTable.Body.Cells = append(enemyTable.Body.Cells, r)
+ }
+
+ fmt.Println("\n\n## Enemies\n")
+ enemyTable.Println()
+
+ // Events
+
+ eventTable := simpletable.New()
+ eventTable.Header = &simpletable.Header{
+ Cells: []*simpletable.Cell{
+ {Align: simpletable.AlignCenter, Text: "ID"},
+ {Align: simpletable.AlignCenter, Text: "Name"},
+ {Align: simpletable.AlignCenter, Text: "Description"},
+ {Align: simpletable.AlignCenter, Text: "Tags"},
+ {Align: simpletable.AlignCenter, Text: "Choices"},
+ {Align: simpletable.AlignCenter, Text: "Test Present"},
+ },
+ }
+ eventTable.SetStyle(simpletable.StyleMarkdown)
+
+ events := lo.Values(res.Events)
+ sort.SliceStable(events, func(i, j int) bool {
+ return events[i].Name < events[j].Name
+ })
+
+ for _, v := range events {
+ r := []*simpletable.Cell{
+ {Text: "``" + v.ID + "``"},
+ {Text: v.Name},
+ {Text: stripSpecial(stripansi.Strip(v.Description))},
+ {Text: strings.Join(v.Tags, ", ")},
+ {Text: makeCodes(lo.Map(v.Choices, func(c game.EventChoice, i int) string {
+ return stripansi.Strip(c.Description)
+ }))},
+ {Text: lo.Ternary(v.Test != nil, ":heavy_check_mark:", ":no_entry_sign:")},
+ }
+
+ eventTable.Body.Cells = append(eventTable.Body.Cells, r)
+ }
+
+ fmt.Println("\n\n## Events\n")
+ eventTable.Println()
+}
diff --git a/cmd/internal/docs/main.go b/cmd/internal/docs/main.go
index e4eb300..e921760 100644
--- a/cmd/internal/docs/main.go
+++ b/cmd/internal/docs/main.go
@@ -1,116 +1,22 @@
package main
-import (
- "fmt"
- "github.com/BigJk/end_of_eden/game"
- "github.com/BigJk/end_of_eden/internal/lua/ludoc"
- "github.com/samber/lo"
- "regexp"
- "sort"
- "strings"
+import "flag"
+
+const (
+ TypeAPI = "api"
+ TypeGameContent = "game_content"
)
-const globTemplate = ` %s
-
-%s
-
-
-
-`
-
-const fnTemplate = ` %s
-
-%s
-
-**Signature:**
-
-%s
-
-
-
-`
-
-var linkPattern = regexp.MustCompile("[^a-zA-Z\\d\\s:-]")
-
-func functionToMd(fn ludoc.Function) string {
- signature := fmt.Sprintf("%s(%s) -> %s", fn.Name, strings.Join(fn.Args, ", "), lo.Ternary(len(fn.Return) == 0, "None", fn.Return))
- return fmt.Sprintf(fnTemplate, fn.Name, fn.Description, "```\n"+signature+"\n```")
-}
-
-func globToMd(glob ludoc.Global) string {
- return fmt.Sprintf(globTemplate, glob.Name, glob.Description)
-}
-
func main() {
- docs := game.NewSession().LuaDocs()
+ t := flag.String("type", "api", "api,game_content")
+ flag.Parse()
- // Fetch the globals and functions keys
- globals := lo.Keys(docs.Globals)
- functions := lo.Keys(docs.Functions)
-
- // Sort them
- sort.Strings(globals)
- sort.Strings(functions)
-
- // Get the sorted categories
- cats := lo.Keys(docs.Categories)
- sort.SliceStable(cats, func(i, j int) bool {
- return docs.Categories[cats[i]].Order < docs.Categories[cats[j]].Order
- })
-
- // Build index
- builder := strings.Builder{}
- builder.WriteString("# End Of Eden Lua Docs\n")
-
- builder.WriteString("## Index\n\n")
- for _, key := range cats {
- cat := docs.Categories[key]
- builder.WriteString(fmt.Sprintf("- [%s](#%s)\n", cat.Name, linkPattern.ReplaceAllString(strings.ToLower(strings.ReplaceAll(cat.Name, " ", "-")), "")))
+ switch *t {
+ case TypeAPI:
+ buildAPIDocs()
+ case TypeGameContent:
+ buildGameContentDocs()
+ default:
+ panic("unknown type")
}
-
- builder.WriteString("\n")
-
- // Build docs
- for _, key := range cats {
- cat := docs.Categories[key]
-
- builder.WriteString("## " + cat.Name + "\n\n")
- builder.WriteString(cat.Description + "\n\n")
-
- builder.WriteString("### Globals\n")
-
- hasGlobals := false
- for _, key := range globals {
- glob := docs.Globals[key]
- if glob.Category != cat.Name {
- continue
- }
- builder.WriteString(globToMd(glob))
- hasGlobals = true
- }
-
- if !hasGlobals {
- builder.WriteString("\nNone\n\n")
- }
-
- builder.WriteString("### Functions\n")
-
- hasFunctions := false
- for _, key := range functions {
- fn := docs.Functions[key]
- if fn.Category != cat.Name {
- continue
- }
- builder.WriteString(functionToMd(fn))
- hasFunctions = true
- }
-
- if !hasFunctions {
- builder.WriteString("\nNone\n\n")
- }
-
- }
-
- // Output docs
- fmt.Print(builder.String())
}
diff --git a/docs/GAME_CONTENT_DOCS.md b/docs/GAME_CONTENT_DOCS.md
new file mode 100644
index 0000000..aa7b44d
--- /dev/null
+++ b/docs/GAME_CONTENT_DOCS.md
@@ -0,0 +1,127 @@
+# Game Content
+This document contains all game content that is available in the game. It is automatically generated and may be out of date.
+Content that is dynamically generated at runtime is not included in this document, only content that is registered at the beginning of a session.
+
+
+
+
+## Stats
+
+| Type | Count |
+|----------------|-------|
+| Artifacts | 10 |
+| Cards | 18 |
+| Status Effects | 8 |
+| Enemies | 4 |
+| Events | 16 |
+
+
+## Artifacts
+
+| ID | Name | Description | Price | Tags | Test Present |
+|---------------------|-----------------|-----------------------------------------------------------------------------------------------------|-------|----------------|--------------------|
+| ``CROWBAR`` | Crowbar | A crowbar. It's a bit rusty, but it should still be useful! Can be used in your hand. | 80 | ATK, M, T, HND | :no_entry_sign: |
+| ``COMBAT_GLASSES`` | Combat Glasses | Whenever you play a **Ranged (R)** card, deal **1 additional damage** | 100 | _ACT_0 | :heavy_check_mark: |
+| ``PORTABLE_BUFFER`` | PRTBL Buffer | Start each turn with 1 **Block** | 100 | _ACT_0 | :no_entry_sign: |
+| ``SPEED_ENHANCER`` | Speed Enhancer | Start with a additional card at the beginning of combat. | 100 | _ACT_0 | :no_entry_sign: |
+| ``COMBAT_GLOVES`` | Combat Gloves | Whenever you play a **Meele (M)** card, deal **1 additional damage** | 100 | _ACT_0 | :heavy_check_mark: |
+| ``VIBRO_KNIFE`` | VIBRO Knife | A VIBRO knife. Uses ultrasonic vibrations to cut through almost anything. Can be used in your hand. | 180 | ATK, M, T, HND | :no_entry_sign: |
+| ``INTERVA_JUICER`` | Interval Juicer | **Heal 2** at the beginning of combat | 200 | _ACT_0 | :no_entry_sign: |
+| ``ARM_MOUNTED_GUN`` | Arm Mounted Gun | Weapon that is mounted on your arm. It is very powerful. | 250 | ARM | :no_entry_sign: |
+| ``LZR_PISTOL`` | LZR Pistol | A LZR pistol. Fires a concentrated beam of light. Can be used in your hand. | 280 | ATK, R, T, HND | :no_entry_sign: |
+| ``HAR_II`` | HAR-II | A HAR-II. A heavy assault rifle with a high rate of fire. Can be used in your hand. | 380 | ATK, R, T, HND | :no_entry_sign: |
+
+
+## Cards
+
+| ID | Name | Description | Action Points | Exhaust | Consumable | Max Level | Price | Tags | Color | Used Callbacks | Test Present |
+|------------------------|--------------------|--------------------------------------------------------------------------------------------------------|---------------|--------------------|--------------------|-----------|-------|----------------|---------|----------------|--------------------|
+| ``ARM_MOUNTED_GUN`` | Arm Mounted Gun | Exhaust. Use your arm mounted gun to deal 15 (+3 for each upgrade) damage. | 3 | :heavy_check_mark: | :no_entry_sign: | 1 | -1 | ATK, R, T, ARM | #2f3e46 | ``OnCast`` | :heavy_check_mark: |
+| ``KNOCK_OUT`` | Knock Out | Inflicts **Knock Out** on the target, causing them to miss their next turn. | 2 | :no_entry_sign: | :no_entry_sign: | 0 | -1 | CC | #725e9c | ``OnCast`` | :no_entry_sign: |
+| ``MELEE_HIT`` | Melee Hit | Use your bare hands to deal 1 (+1 for each upgrade) damage. | 1 | :no_entry_sign: | :no_entry_sign: | 1 | -1 | ATK, M, HND | #2f3e46 | ``OnCast`` | :heavy_check_mark: |
+| ``KILL`` | Kill | Debug Card | 0 | :no_entry_sign: | :no_entry_sign: | 0 | -1 | | #2f3e46 | ``OnCast`` | :no_entry_sign: |
+| ``CROWBAR`` | Crowbar | Use to deal 2 (+3 for each upgrade) damage. | 1 | :no_entry_sign: | :no_entry_sign: | 3 | 0 | ATK, M, T, HND | #2f3e46 | ``OnCast`` | :heavy_check_mark: |
+| ``VIBRO_KNIFE`` | VIBRO Knife | Use to deal 3 (+3 for each upgrade) damage. | 1 | :no_entry_sign: | :no_entry_sign: | 3 | 0 | ATK, M, T, HND | #2f3e46 | ``OnCast`` | :heavy_check_mark: |
+| ``LZR_PISTOL`` | LZR Pistol | Use to deal 4 (+3 for each upgrade) damage. | 1 | :no_entry_sign: | :no_entry_sign: | 3 | 0 | ATK, R, T, HND | #2f3e46 | ``OnCast`` | :heavy_check_mark: |
+| ``HAR_II`` | HAR-II | Use to deal 5 (+3 for each upgrade) damage. | 1 | :no_entry_sign: | :no_entry_sign: | 3 | 0 | ATK, R, T, HND | #2f3e46 | ``OnCast`` | :heavy_check_mark: |
+| ``BLOCK`` | Block | Shield yourself and gain 5 **block**. | 1 | :no_entry_sign: | :no_entry_sign: | 1 | 50 | DEF | #219ebc | ``OnCast`` | :no_entry_sign: |
+| ``ENERGY_DRINK`` | ENRGY Drink X91 | **One-Time** - Gain 1 action point. | 0 | :no_entry_sign: | :heavy_check_mark: | 0 | 150 | UTIL, _ACT_0 | #fb5607 | ``OnCast`` | :heavy_check_mark: |
+| ``FLASH_SHIELD`` | Flash Shield | **One-Time** - Deploy a temporary shield. **Negates** the next attack. | 0 | :no_entry_sign: | :heavy_check_mark: | 0 | 150 | DEF, _ACT_0 | #219ebc | ``OnCast`` | :no_entry_sign: |
+| ``NANO_CHARGER`` | Nano Charger | **One-Time** - Supercharge your next attack. Deals **Double** damage. | 0 | :no_entry_sign: | :heavy_check_mark: | 0 | 150 | BUFF, _ACT_0 | #c1121f | ``OnCast`` | :heavy_check_mark: |
+| ``STIM_PACK`` | Stim Pack | **One-Time** - Restores **5** HP. | 0 | :no_entry_sign: | :heavy_check_mark: | 0 | 150 | HEAL, _ACT_0 | #219ebc | ``OnCast`` | :heavy_check_mark: |
+| ``BOUNCE_SHIELD`` | Bounce Shield | **One-Time** - Deploy a temporary shield. **Negates** bounces the damage back, but still takes damage. | 0 | :no_entry_sign: | :heavy_check_mark: | 0 | 150 | DEF, _ACT_0 | #219ebc | ``OnCast`` | :no_entry_sign: |
+| ``FLASH_BANG`` | Flash Bang | **One-Time** - Inflicts **Blinded** on the target, causing them to deal less damage. | 0 | :no_entry_sign: | :heavy_check_mark: | 0 | 150 | CC, _ACT_0 | #725e9c | ``OnCast`` | :no_entry_sign: |
+| ``ENERGY_DRINK_2`` | ENRGY Drink X92 | **One-Time** - Gain 2 action points. | 0 | :no_entry_sign: | :heavy_check_mark: | 0 | 250 | UTIL, _ACT_0 | #fb5607 | ``OnCast`` | :heavy_check_mark: |
+| ``ULTRA_FLASH_SHIELD`` | Ultra Flash Shield | **One-Time** - Deploy a temporary shield. **Negates** all attack this turn. | 3 | :no_entry_sign: | :heavy_check_mark: | 0 | 250 | DEF, _ACT_0 | #219ebc | ``OnCast`` | :no_entry_sign: |
+| ``ENERGY_DRINK_3`` | ENRGY Drink X93 | **One-Time** - Gain 3 action points. | 0 | :no_entry_sign: | :heavy_check_mark: | 0 | 350 | UTIL, _ACT_0 | #fb5607 | ``OnCast`` | :heavy_check_mark: |
+
+
+### Action Points
+
+´´´mermaid
+pie title Action Points
+0 AP: 9
+3 AP: 2
+2 AP: 1
+1 AP: 6
+´´´
+
+
+
+
+### Card Types
+
+´´´mermaid
+pie title Card Types
+Exhaust: 1
+Normal: 8
+Consume: 9
+´´´
+
+
+
+
+## Status Effects
+
+| ID | Name | Description | Look | Foreground | Can Stack | Decay | Rounds | Used Callbacks | Test Present |
+|------------------------|--------------------|---------------------------------------------------|------|------------|--------------------|-----------|--------|------------------|--------------------|
+| ``KNOCK_OUT`` | Knock Out | Can't act | KO | #725e9c | :heavy_check_mark: | DecayOne | 1 | ``OnTurn`` | :no_entry_sign: |
+| ``CHARGED`` | Charged | Attacks will deal more damage per stack. | CHRG | #207BE7 | :heavy_check_mark: | DecayNone | 0 | ``OnDamageCalc`` | :no_entry_sign: |
+| ``FLASH_BANG`` | Blinded | Causing **25%** less damage. | FL | #725e9c | :heavy_check_mark: | DecayOne | 1 | ``OnDamageCalc`` | :heavy_check_mark: |
+| ``BLOCK`` | Block | Decreases incoming damage for each stack | B | #219ebc | :heavy_check_mark: | DecayAll | 1 | ``OnDamageCalc`` | :heavy_check_mark: |
+| ``BOUNCE_SHIELD`` | Bounce Shield | Bounces back the next damage. Still takes damage. | BS | #219ebc | :no_entry_sign: | DecayAll | 1 | ``OnDamageCalc`` | :heavy_check_mark: |
+| ``FLASH_SHIELD`` | Flash Shield | Negates the next attack. | FS | #219ebc | :no_entry_sign: | DecayAll | 1 | ``OnDamageCalc`` | :heavy_check_mark: |
+| ``NANO_CHARGER`` | Nano Charge | Next attack deals **Double** damage. | NC | #c1121f | :no_entry_sign: | DecayAll | 1 | ``OnDamageCalc`` | :heavy_check_mark: |
+| ``ULTRA_FLASH_SHIELD`` | Ultra Flash Shield | Negates all attacks. | UFS | #219ebc | :no_entry_sign: | DecayAll | 1 | ``OnDamageCalc`` | :heavy_check_mark: |
+
+
+## Enemies
+
+| ID | Name | Description | Initial HP | Max HP | Look | Color | Used Callbacks | Test Present |
+|------------------|--------------|--------------------------------------|------------|--------|------------------------------------------------------------------|---------|------------------------------|-----------------|
+| ``CYBER_SPIDER`` | CYBER Spider | It waits for its prey to come closer | 8 | 8 | /\\o^o/\\ | #ff4d6d | ``OnTurn`` | :no_entry_sign: |
+| ``CLEAN_BOT`` | Cleaning Bot | It never stopped cleaning... | 13 | 13 | \\_/(* *) )#( | #32a891 | ``OnTurn``, ``OnPlayerTurn`` | :no_entry_sign: |
+| ``DUMMY`` | Dummy | End me... | 100 | 100 | DUM | #deeb6a | ``OnTurn`` | :no_entry_sign: |
+| ``RUST_MITE`` | Rust Mite | A small robot that eats metal. | 12 | 12 | /v\\ | #e6e65a | ``OnTurn`` | :no_entry_sign: |
+
+
+## Events
+
+| ID | Name | Description | Tags | Choices | Test Present |
+|------------------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|--------------------------------------------------------------------------------------------------------|-----------------|
+| ``GAIN_GOLD_ACT_0`` | | ... - | _ACT_0 | ``Take it! [Gain 20 Gold]``, ``Leave!`` | :no_entry_sign: |
+| ``MERCHANT`` | A strange figure | !!merchant.jpg - - The merchant is a tall, lanky figure draped in a long, tattered coat made of plant fibers and animal hides. Their face is hidden behind a mask made of twisted roots and vines, giving them an unsettling, almost alien appearance. - Despite their strange appearance, the merchant is a shrewd negotiator and a skilled trader. They carry with them a collection of bizarre and exotic items, including plant-based weapons, animal pelts, and strange, glowing artifacts that seem to pulse with an otherworldly energy. - The merchant is always looking for a good deal, and they're not above haggling with potential customers... | _ACT_0, _ACT_1, _ACT_2, _ACT_3 | ``Trade``, ``Pass`` | :no_entry_sign: |
+| ``CLEAN_BOT`` | Corpse. Clean. Engage. | !!clean_bot.jpg - While exploring the facility you hear a strange noise. Suddenly a strange robot appears from one of the corridors. - It seems to be cleaning up the area, but it's not working properly anymore and you can see small sparks coming out of it. - It looks at you and says "Corpse. Clean. Engage.". - **You're not sure what it means, but it doesn't seem to be friendly!** - | _ACT_0_FIGHT | ``Fight!`` | :no_entry_sign: |
+| ``GAMBLE_1_ACT_0`` | Electro Barrier | You find a room with a strange device in the middle. It seems to be some kind of electro barrier protecting a storage container. You can either try to disable the barrier or leave. - | _ACT_0 | ``50% [Gain Artifact & Consumeable] 50% [Take 5 damage]``, ``Leave!`` | :no_entry_sign: |
+| ``CROWBAR`` | Found: Crowbar | !!red_room.jpg - **You found something!** A crowbar. It's a bit rusty, but it should still be useful! - **Important:** If you already carry a artifact in your hand, you will have to drop it and related cards to pick up the new one. | _ACT_0 | ````, ``Leave...`` | :no_entry_sign: |
+| ``HAR_II`` | Found: HAR-II | !!artifact_chest.jpg - **You found something!** A HAR-II. A heavy assault rifle with a high rate of fire. - **Important:** If you already carry a artifact in your hand, you will have to drop it and related cards to pick up the new one. | _ACT_1 | ````, ``Leave...`` | :no_entry_sign: |
+| ``LZR_PISTOL`` | Found: LZR Pistol | !!artifact_chest.jpg - **You found something!** A LZR pistol. Fires a concentrated beam of light. - **Important:** If you already carry a artifact in your hand, you will have to drop it and related cards to pick up the new one. | _ACT_1 | ````, ``Leave...`` | :no_entry_sign: |
+| ``VIBRO_KNIFE`` | Found: VIBRO Knife | !!artifact_chest.jpg - **You found something!** A VIBRO knife. Uses ultrasonic vibrations to cut through almost anything. - **Important:** If you already carry a artifact in your hand, you will have to drop it and related cards to pick up the new one. | _ACT_0 | ````, ``Leave...`` | :no_entry_sign: |
+| ``GOLD_TO_HP_ACT_0`` | Old Vending Machine | You find an old vending machine, it seems to be still working. You can either pay 20 Gold to get 5 HP or leave. - | _ACT_0 | ``Pay [20 Gold] [Gain 5 HP]``, ``Leave!`` | :no_entry_sign: |
+| ``RANDOM_ARTIFACT_ACT_0`` | Random Artifact | !!artifact_chest.jpg - You found a chest with a strange symbol on it. The chest is protected by a strange barrier. You can either open it and take some damage or leave. - | _ACT_0 | ``Random Artifact [Gain 1 Artifact] [Take 5 damage]``, ``Leave!`` | :no_entry_sign: |
+| ``RANDOM_CONSUMEABLE_ACT_0`` | Random Consumeable | !!artifact_chest.jpg - You found a chest with a strange symbol on it. The chest is protected by a strange barrier. You can either open it and take some damage or leave. - | _ACT_0 | ``Random Artifact [Gain 1 Consumeable] [Take 2 damage]``, ``Leave!`` | :no_entry_sign: |
+| ``MAX_LIFE_ACT_0`` | Symbiotic Parasite | You find a strange creature, it seems to be a symbiotic parasite. It offers to increase your max HP by 5. You can either accept or leave. - | _ACT_0 | ``Accept it! [Gain 5 Max HP]``, ``Leave!`` | :no_entry_sign: |
+| ``RUST_MITE`` | Tasty metals... | !!rust_mite.jpg - You are walking through the facility hoping to find a way out. After a few turns you hear a strange noise. You look around and come across a strange being. - It seems to be eating the metal from the walls. It looks at you and after a few seconds it rushes towards you. - **It seems to be hostile!** - | _ACT_0_FIGHT | ``Fight!`` | :no_entry_sign: |
+| ``UPRAGDE_CARD_ACT_0`` | Upgrade Station | You find a old automatic workstation. You are able to get it working again. You can either upgrade a random card or leave. - | _ACT_0 | ``Upgrade a card [Upgrade a card] [Take 5 damage]``, ``Leave!`` | :no_entry_sign: |
+| ``START`` | Waking up... | !!cryo_start.jpg - You wake up in a dimly lit room, the faint glow of a red emergency light casting an eerie hue over the surroundings. The air is musty and stale, the metallic scent of the cryo-chamber still lingering in your nostrils. You feel groggy and disoriented, your mind struggling to process what's happening. - As you try to sit up, you notice that your body is stiff and unresponsive. It takes a few moments for your muscles to warm up and regain their strength. Looking around, you see that the walls are made of a dull gray metal, covered in scratches and scuff marks. There's a faint humming sound coming from somewhere, indicating that the facility is still operational. - You try to remember how you ended up here, but your memories are hazy and fragmented. The last thing you recall is a blinding flash of light and a deafening boom. You must have been caught in one of the nuclear explosions that devastated the world. - As you struggle to gather your bearings, you notice a blinking panel on the wall, with the words *"Cryo Sleep Malfunction"* displayed in bold letters. It seems that the system has finally detected the error that caused your prolonged slumber and triggered your awakening. - **Shortly after you realize that you are not alone...** | | ``Try to find a weapon. [Find meele weapon] [Take 4 damage]``, ``Gather your strength and attack it!`` | :no_entry_sign: |
+| ``CYBER_SPIDER`` | What is this thing at the ceiling? | !!cyber_spider.jpg - You come around a corner and see a strange creature hanging from the ceiling. It looks like a spider, but it's made out of metal. - It seems to be waiting for its prey to come closer and there is no way around it. - | _ACT_0_FIGHT | ``Fight!`` | :no_entry_sign: |
diff --git a/go.mod b/go.mod
index 60aaece..bc355de 100644
--- a/go.mod
+++ b/go.mod
@@ -31,7 +31,7 @@ require (
github.com/lrstanley/bubblezone v0.0.0-20230303230241-08f906ff62a9
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/maruel/panicparse/v2 v2.3.1
- github.com/mattn/go-runewidth v0.0.14
+ github.com/mattn/go-runewidth v0.0.15
github.com/mitchellh/mapstructure v1.5.0
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6
github.com/muesli/reflow v0.3.0
@@ -52,8 +52,10 @@ require (
cdr.dev/slog v1.4.2-0.20221206192828-e4803b10ae17 // indirect
cloud.google.com/go/logging v1.7.0 // indirect
github.com/PuerkitoBio/goquery v1.8.1 // indirect
+ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
github.com/alecthomas/chroma v0.10.0 // indirect
github.com/alecthomas/chroma/v2 v2.5.0 // indirect
+ github.com/alexeyco/simpletable v1.0.0 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/anthonynsimon/bild v0.13.0 // indirect
diff --git a/go.sum b/go.sum
index 890b324..ac54a05 100644
--- a/go.sum
+++ b/go.sum
@@ -64,6 +64,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
+github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
+github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw=
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
@@ -74,6 +76,8 @@ github.com/alecthomas/chroma/v2 v2.5.0 h1:CQCdj1BiBV17sD4Bd32b/Bzuiq/EqoNTrnIhyQ
github.com/alecthomas/chroma/v2 v2.5.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw=
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
+github.com/alexeyco/simpletable v1.0.0 h1:ZQ+LvJ4bmoeHb+dclF64d0LX+7QAi7awsfCrptZrpHk=
+github.com/alexeyco/simpletable v1.0.0/go.mod h1:VJWVTtGUnW7EKbMRH8cE13SigKGx/1fO2SeeOiGeBkk=
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
@@ -324,6 +328,8 @@ github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRC
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mazznoer/csscolorparser v0.1.3 h1:vug4zh6loQxAUxfU1DZEu70gTPufDPspamZlHAkKcxE=
github.com/mazznoer/csscolorparser v0.1.3/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic=
github.com/mewkiz/flac v1.0.7/go.mod h1:yU74UH277dBUpqxPouHSQIar3G1X/QIclVbFahSd1pU=
diff --git a/update-docs.sh b/update-docs.sh
index 1789869..3473cb1 100755
--- a/update-docs.sh
+++ b/update-docs.sh
@@ -4,6 +4,10 @@ echo "Updating docs..."
go run ./cmd/internal/docs > ./docs/LUA_API_DOCS.md
echo "Done!"
+echo "Updating game docs..."
+go run ./cmd/internal/docs -type game_content > ./docs/GAME_CONTENT_DOCS.md
+echo "Done!"
+
echo "Updating definitions..."
go run ./cmd/internal/definitions > ./assets/scripts/definitions/api.lua
echo "Done!"