auto-generate card images
|
|
@ -6,7 +6,7 @@
|
||||||
"name": "Rapid Response",
|
"name": "Rapid Response",
|
||||||
"type": "Passive",
|
"type": "Passive",
|
||||||
"cost": 0,
|
"cost": 0,
|
||||||
"image": "https://docs.brut.systems/judah/entropy/passive-base.png",
|
"image": "https://docs.brut.systems/judah/entropy/000.png",
|
||||||
"isHorizontal": true
|
"isHorizontal": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
"name": "Breaker",
|
"name": "Breaker",
|
||||||
"type": "Passive",
|
"type": "Passive",
|
||||||
"cost": 0,
|
"cost": 0,
|
||||||
"image": "https://docs.brut.systems/judah/entropy/passive-base.png",
|
"image": "https://docs.brut.systems/judah/entropy/001.png",
|
||||||
"isHorizontal": true
|
"isHorizontal": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
"name": "Inverse Entropy",
|
"name": "Inverse Entropy",
|
||||||
"type": "Passive",
|
"type": "Passive",
|
||||||
"cost": 0,
|
"cost": 0,
|
||||||
"image": "https://docs.brut.systems/judah/entropy/passive-base.png",
|
"image": "https://docs.brut.systems/judah/entropy/002.png",
|
||||||
"isHorizontal": true
|
"isHorizontal": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -69,14 +69,14 @@
|
||||||
"id": "003",
|
"id": "003",
|
||||||
"face": {
|
"face": {
|
||||||
"front": {
|
"front": {
|
||||||
"name": "SoftReflex",
|
"name": "SpentReflex",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 1,
|
"cost": 1,
|
||||||
"image": "https://docs.brut.systems/judah/entropy/red-base.png",
|
"image": "https://docs.brut.systems/judah/entropy/003.png",
|
||||||
"isHorizontal": true
|
"isHorizontal": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "SoftReflex",
|
"name": "SpentReflex",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 1,
|
"cost": 1,
|
||||||
"isToken": false,
|
"isToken": false,
|
||||||
|
|
@ -91,14 +91,14 @@
|
||||||
"id": "004",
|
"id": "004",
|
||||||
"face": {
|
"face": {
|
||||||
"front": {
|
"front": {
|
||||||
"name": "CivicContour",
|
"name": "InlandAperture",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 2,
|
"cost": 2,
|
||||||
"image": "https://docs.brut.systems/judah/entropy/red-base.png",
|
"image": "https://docs.brut.systems/judah/entropy/004.png",
|
||||||
"isHorizontal": true
|
"isHorizontal": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "CivicContour",
|
"name": "InlandAperture",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 2,
|
"cost": 2,
|
||||||
"isToken": false,
|
"isToken": false,
|
||||||
|
|
@ -113,14 +113,14 @@
|
||||||
"id": "005",
|
"id": "005",
|
||||||
"face": {
|
"face": {
|
||||||
"front": {
|
"front": {
|
||||||
"name": "FlatDividend",
|
"name": "ObliqueCortex",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 3,
|
"cost": 3,
|
||||||
"image": "https://docs.brut.systems/judah/entropy/red-base.png",
|
"image": "https://docs.brut.systems/judah/entropy/005.png",
|
||||||
"isHorizontal": true
|
"isHorizontal": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "FlatDividend",
|
"name": "ObliqueCortex",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 3,
|
"cost": 3,
|
||||||
"isToken": false,
|
"isToken": false,
|
||||||
|
|
@ -135,14 +135,14 @@
|
||||||
"id": "006",
|
"id": "006",
|
||||||
"face": {
|
"face": {
|
||||||
"front": {
|
"front": {
|
||||||
"name": "AbsentFilament",
|
"name": "FormerDividend",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 4,
|
"cost": 4,
|
||||||
"image": "https://docs.brut.systems/judah/entropy/red-base.png",
|
"image": "https://docs.brut.systems/judah/entropy/006.png",
|
||||||
"isHorizontal": true
|
"isHorizontal": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "AbsentFilament",
|
"name": "FormerDividend",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 4,
|
"cost": 4,
|
||||||
"isToken": false,
|
"isToken": false,
|
||||||
|
|
@ -157,20 +157,20 @@
|
||||||
"id": "007",
|
"id": "007",
|
||||||
"face": {
|
"face": {
|
||||||
"front": {
|
"front": {
|
||||||
"name": "SoftSubstrate",
|
"name": "SoftReflex",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 5,
|
"cost": 10,
|
||||||
"image": "https://docs.brut.systems/judah/entropy/red-base.png",
|
"image": "https://docs.brut.systems/judah/entropy/007.png",
|
||||||
"isHorizontal": true
|
"isHorizontal": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "SoftSubstrate",
|
"name": "SoftReflex",
|
||||||
"type": "Unit",
|
"type": "Unit",
|
||||||
"cost": 5,
|
"cost": 10,
|
||||||
"isToken": false,
|
"isToken": false,
|
||||||
"Lane": "🟥 Red",
|
"Lane": "🟥 Red",
|
||||||
"Entropy": 5,
|
"Entropy": 10,
|
||||||
"Force": 5,
|
"Force": 10,
|
||||||
"_legal": {
|
"_legal": {
|
||||||
"playtest": true
|
"playtest": true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
cards.go
|
|
@ -24,6 +24,6 @@ var CARDS = []struct {
|
||||||
desc: ``},
|
desc: ``},
|
||||||
{typ: Unit, lane: Red, entropy: 4, force: 4,
|
{typ: Unit, lane: Red, entropy: 4, force: 4,
|
||||||
desc: ``},
|
desc: ``},
|
||||||
{typ: Unit, lane: Red, entropy: 5, force: 5,
|
{typ: Unit, lane: Red, entropy: 10, force: 10,
|
||||||
desc: ``},
|
desc: ``},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
docs/000.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
docs/001.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
docs/002.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/003.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/004.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
docs/005.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
docs/006.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/007.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
docs/Krungthep.ttf
Normal file
BIN
docs/SFCamera.ttf
Normal file
BIN
docs/base-blue.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
docs/base-green.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
docs/base-passive.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/base-red.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 714 KiB |
|
Before Width: | Height: | Size: 983 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 493 KiB |
6
go.mod
|
|
@ -1,3 +1,9 @@
|
||||||
module tcg
|
module tcg
|
||||||
|
|
||||||
go 1.26.1
|
go 1.26.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/fogleman/gg v1.3.0 // indirect
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
|
golang.org/x/image v0.38.0 // indirect
|
||||||
|
)
|
||||||
|
|
|
||||||
6
go.sum
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||||
|
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
|
golang.org/x/image v0.38.0 h1:5l+q+Y9JDC7mBOMjo4/aPhMDcxEptsX+Tt3GgRQRPuE=
|
||||||
|
golang.org/x/image v0.38.0/go.mod h1:/3f6vaXC+6CEanU4KJxbcUZyEePbyKbaLoDOe4ehFYY=
|
||||||
78
main.go
|
|
@ -3,8 +3,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fogleman/gg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Lane int
|
type Lane int
|
||||||
|
|
@ -88,21 +92,77 @@ func main() {
|
||||||
card.name = generateTemporaryName()
|
card.name = generateTemporaryName()
|
||||||
}
|
}
|
||||||
|
|
||||||
baseurl := "https://docs.brut.systems/judah/entropy/"
|
var (
|
||||||
|
baseimg string
|
||||||
var imgurl string
|
color [3]float64
|
||||||
|
)
|
||||||
switch card.lane {
|
switch card.lane {
|
||||||
case Red:
|
case Red:
|
||||||
imgurl = baseurl + "red-base.png"
|
baseimg = "base-red.png"
|
||||||
case Blue:
|
color = [3]float64{248.0 / 255.0, 120.0 / 255.0, 143.0 / 255.0}
|
||||||
imgurl = baseurl + "blue-base.png"
|
|
||||||
case Green:
|
case Green:
|
||||||
imgurl = baseurl + "green-base.png"
|
baseimg = "base-green.png"
|
||||||
|
color = [3]float64{120.0 / 255.0, 190.0 / 255.0, 248.0 / 255.0}
|
||||||
|
case Blue:
|
||||||
|
baseimg = "base-blue.png"
|
||||||
|
color = [3]float64{120.0 / 255.0, 248.0 / 255.0, 178.0 / 255.0}
|
||||||
default:
|
default:
|
||||||
imgurl = baseurl + "passive-base.png"
|
color = [3]float64{184.0 / 255.0, 184.0 / 255.0, 184.0 / 255.0}
|
||||||
|
baseimg = "base-passive.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img, err := gg.LoadImage("docs/" + baseimg)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := gg.NewContextForImage(img)
|
||||||
|
if err := ctx.LoadFontFace("docs/Krungthep.ttf", 48); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw force
|
||||||
|
if card.typ != Passive {
|
||||||
|
ctx.SetRGB(1, 1, 1)
|
||||||
|
ctx.Push()
|
||||||
|
{
|
||||||
|
ctx.Translate(120, 115)
|
||||||
|
ctx.Rotate(270 * math.Pi / 180)
|
||||||
|
ctx.DrawStringAnchored(fmt.Sprintf("%d", card.force), 0, 0, 0.5, 0.5)
|
||||||
|
}
|
||||||
|
ctx.Pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw entropy
|
||||||
|
ctx.SetRGB(color[0], color[1], color[2])
|
||||||
|
ctx.Push()
|
||||||
|
{
|
||||||
|
ctx.Translate(273, 115)
|
||||||
|
ctx.Rotate(270 * math.Pi / 180)
|
||||||
|
ctx.DrawStringAnchored(fmt.Sprintf("%d", card.entropy), 0, 0, 0.5, 0.5)
|
||||||
|
}
|
||||||
|
ctx.Pop()
|
||||||
|
|
||||||
|
if err := ctx.LoadFontFace("docs/SFCamera.ttf", 30); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw description
|
||||||
|
cleandesc := strings.NewReplacer("{{", "", "}}", "").Replace(card.desc)
|
||||||
|
ctx.SetRGBA(0, 0, 0, 0.9)
|
||||||
|
ctx.Push()
|
||||||
|
{
|
||||||
|
ctx.Translate(435, 985)
|
||||||
|
ctx.Rotate(270 * math.Pi / 180)
|
||||||
|
ctx.DrawStringWrapped(fmt.Sprintf("%s -\n%s", card.name, cleandesc), 0, 0, 0.0, 0.0, 900, 1.70, gg.AlignLeft)
|
||||||
|
}
|
||||||
|
ctx.Pop()
|
||||||
|
|
||||||
id := fmt.Sprintf("%03d", i)
|
id := fmt.Sprintf("%03d", i)
|
||||||
|
if err := ctx.SavePNG("docs/" + id + ".png"); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
thejson[id] = jsoncard{
|
thejson[id] = jsoncard{
|
||||||
Id: id,
|
Id: id,
|
||||||
Face: struct {
|
Face: struct {
|
||||||
|
|
@ -111,7 +171,7 @@ func main() {
|
||||||
jsonfront{
|
jsonfront{
|
||||||
Name: card.name,
|
Name: card.name,
|
||||||
Type: card.typ.String(),
|
Type: card.typ.String(),
|
||||||
Image: imgurl,
|
Image: fmt.Sprintf("https://docs.brut.systems/judah/entropy/%s.png", id),
|
||||||
Cost: card.entropy,
|
Cost: card.entropy,
|
||||||
Horizontal: true,
|
Horizontal: true,
|
||||||
},
|
},
|
||||||
|
|
|
||||||