Migrated to cue+ninja
1
.gitignore
vendored
|
@ -8,6 +8,7 @@ changelist.txt
|
|||
*.d
|
||||
*.toc
|
||||
outputs/**
|
||||
output/**
|
||||
Console.
|
||||
Python-Fu
|
||||
Makefile.deps
|
||||
|
|
BIN
.ninja_deps
Normal file
1003
.ninja_log
Normal file
44
assets.cue
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Iditacards asset definitions
|
||||
|
||||
package iditacards
|
||||
|
||||
#AssetKind: "image" | "tex" | "template" | "cat"
|
||||
|
||||
#Asset: {
|
||||
// passed to convert to create the "print" version (usually to add bleed)
|
||||
// e.g. -set option:distort:viewport 825x1125-37-37 -virtual-pixel Edge -distort SRT 0 +repage
|
||||
print?: string
|
||||
|
||||
depends: {
|
||||
assets: [...string]
|
||||
files: [...string]
|
||||
}
|
||||
|
||||
kind: #AssetKind
|
||||
|
||||
if kind == "image" {
|
||||
source: string
|
||||
}
|
||||
|
||||
if kind == "template" {
|
||||
template: string
|
||||
size: #Dimensions
|
||||
data: _
|
||||
}
|
||||
|
||||
if kind == "cat" {
|
||||
contents: [...string]
|
||||
}
|
||||
|
||||
if kind == "tex" {
|
||||
source: string
|
||||
size: #Dimensions
|
||||
}
|
||||
}
|
||||
|
||||
// Assets are what actually need to be printed/created/etc
|
||||
assets: [string]: #Asset
|
||||
|
||||
// Pseudo assets are useful to build for actually interacting with the game
|
||||
// (e.g. a PDF of all cards)
|
||||
pseudoassets: [string]: #Asset
|
643
assets.yaml
|
@ -1,641 +1,8 @@
|
|||
# This file describes the assets of iditacards
|
||||
# vim: fdm=marker
|
||||
# The "other" assets
|
||||
# TODO: with e.g. the iditaboard, check the differences with master branch, make
|
||||
# sure "simplified" and "master" versions can both use assets without much issue
|
||||
|
||||
# It is processed to produce various source files that are then compiled into
|
||||
# assets
|
||||
# images:
|
||||
|
||||
# TODO: Change the system to be more like the toml. Just have a: b: generate
|
||||
# b using a.mako, but a: -b does not. (except unlike l4den, yaml can't mix
|
||||
# arrays and objects, so maybe use _: -b -c -...?)
|
||||
|
||||
# Any object with an "output" key will be processed to produce said output by
|
||||
# using its "template" key as a mako template and passing "data" is data.
|
||||
|
||||
cards: # {{{
|
||||
- &a_hat
|
||||
name: 'A Hat'
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
effects:
|
||||
- '\daydraw{+1}'
|
||||
image: hat
|
||||
type: attachment
|
||||
flavour: 'I bet its a valve hat.'
|
||||
|
||||
- &dog_chow
|
||||
name: 'Dog Chow'
|
||||
costs:
|
||||
energy: 3
|
||||
health: 3
|
||||
effects:
|
||||
- '\speed{+1}'
|
||||
image: dog_chow
|
||||
type: attachment
|
||||
flavour: 'A hungry dog is a slow dog.'
|
||||
|
||||
- &good_dog
|
||||
name: 'Good Dog'
|
||||
costs:
|
||||
energy: 3
|
||||
health: 3
|
||||
effects:
|
||||
- '\daydraw{+1}'
|
||||
image: good_dog
|
||||
type: dog
|
||||
flavour: 'Good boy.'
|
||||
|
||||
- &husky
|
||||
name: 'Husky'
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
risk: 2
|
||||
effects:
|
||||
- '\daydraw{+1}'
|
||||
- '\speed{+1}'
|
||||
image: husky
|
||||
type: dog
|
||||
flavour: 'Standard mushing fare.'
|
||||
|
||||
- &wheel_dog
|
||||
name: 'Wheel Dog'
|
||||
costs:
|
||||
energy: 3
|
||||
health: 3
|
||||
effects:
|
||||
- '\speed{+1}'
|
||||
- '\discardonkill'
|
||||
- '\inplayatstart'
|
||||
image: wheel_dog
|
||||
type: dog
|
||||
flavour: 'The dog right in front of the sled. Strong and steady.'
|
||||
|
||||
- &breakfast
|
||||
name: 'Breakfast'
|
||||
costs:
|
||||
health: 3
|
||||
effects:
|
||||
- '\draw{3}'
|
||||
image: breakfast
|
||||
type: food
|
||||
flavour: 'The most important meal of the day.'
|
||||
|
||||
- &lunch
|
||||
name: 'Lunch'
|
||||
costs:
|
||||
energy: 3
|
||||
effects:
|
||||
- '\draw{3}'
|
||||
image: lunch
|
||||
type: food
|
||||
flavour: 'What about second breakfast?'
|
||||
|
||||
- &dinner
|
||||
name: 'Dinner'
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
effects:
|
||||
- '\draw{7}'
|
||||
image: dinner
|
||||
type: food
|
||||
flavour: 'I hope you like salted fish.'
|
||||
|
||||
- &move
|
||||
name: 'Move'
|
||||
effects:
|
||||
- '\move{1}'
|
||||
image: move
|
||||
type: movement
|
||||
flavour: 'Just another day.'
|
||||
|
||||
- &mush
|
||||
name: 'Mush'
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
risk: 1
|
||||
effects:
|
||||
- '\move{10}'
|
||||
image: mush
|
||||
type: movement
|
||||
flavour: "Comes from the french word ``Marche''."
|
||||
|
||||
- &first_aid
|
||||
name: First Aid
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
effects:
|
||||
- '\see{3}'
|
||||
- '\destroy{1}'
|
||||
image: first_aid
|
||||
type: personal
|
||||
flavour: 'Reduces swelling.'
|
||||
|
||||
- &grandma_soup
|
||||
name: Grandma Soup
|
||||
costs:
|
||||
energy: 1
|
||||
health: 2
|
||||
risk: 1
|
||||
effects:
|
||||
- '\see{10}'
|
||||
- '\destroy{2}'
|
||||
image: grandma_soup
|
||||
type: personal
|
||||
flavour: 'Cures what ails you.'
|
||||
|
||||
- &repair_sled
|
||||
name: Repair Sled
|
||||
costs:
|
||||
energy: 1
|
||||
health: 3
|
||||
effects:
|
||||
- '\supply{1}'
|
||||
- '\take{2}'
|
||||
image: repair_sled
|
||||
type: sled
|
||||
flavour: "It doesn't need to be pretty. It just has to work."
|
||||
|
||||
- &upgrade_sled
|
||||
name: Upgrade Sled
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
effects:
|
||||
- '\supply{3}'
|
||||
- '\take{1}'
|
||||
image: upgrade_sled
|
||||
type: sled
|
||||
flavour: 'You have to keep your ride in top shape.'
|
||||
|
||||
- &buffer_panel
|
||||
name: Buffer Panel
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
effects:
|
||||
- '\immortal'
|
||||
- '\safepass'
|
||||
image: buffer_panel
|
||||
type: attachment
|
||||
flavour: 'Did the primary buffer panel just fall of my gorram ship for no apparent reason?'
|
||||
|
||||
- &nuclear_reactor
|
||||
name: Nuclear Reactor
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
effects:
|
||||
- '\speed{+5}'
|
||||
- '\passdie'
|
||||
image: nuclear_reactor
|
||||
type: attachment
|
||||
flavour: 'What could go wrong?'
|
||||
|
||||
- &engineer_dog
|
||||
name: Engineer Dog
|
||||
costs:
|
||||
energy: 3
|
||||
health: 5
|
||||
risk: 1
|
||||
effects:
|
||||
- '\speed{$\times 2$}'
|
||||
- '\nohold'
|
||||
image: engineer_dog
|
||||
type: dog
|
||||
flavour: 'Nails and Gears.'
|
||||
|
||||
- &moose
|
||||
name: Moose
|
||||
costs:
|
||||
energy: 5
|
||||
risk: 3
|
||||
effects:
|
||||
- '\speed{+5}'
|
||||
- '\immortal'
|
||||
image: moose
|
||||
type: dog
|
||||
flavour: 'Majestic creatures. Hard to tame.'
|
||||
|
||||
- &waffle
|
||||
name: Waffle
|
||||
effects:
|
||||
- '\draw{2}'
|
||||
image: waffles
|
||||
type: food
|
||||
flavour: 'Waffles are \textbf{delicious}.'
|
||||
|
||||
- &whale_meat
|
||||
name: Whale Meat
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
effects:
|
||||
- '\draw{5}'
|
||||
- '\nohypothermia'
|
||||
image: whale_meat
|
||||
type: food
|
||||
flavour: "It's like rubber."
|
||||
|
||||
- &hitch_a_ride
|
||||
name: Hitch a Ride
|
||||
costs:
|
||||
energy: 1
|
||||
effects:
|
||||
- '\move{6}'
|
||||
- '\damage{1}'
|
||||
image: hitch_a_ride
|
||||
type: movement
|
||||
flavour: 'Probably not in the spirit of the race.'
|
||||
|
||||
- &tactical_play
|
||||
name: Tactical Play
|
||||
costs:
|
||||
energy: 1
|
||||
risk: 1
|
||||
effects:
|
||||
- '\move{0}'
|
||||
- '\doubledistance'
|
||||
image: tactical_play
|
||||
type: movement
|
||||
flavour: 'Make the most of it.'
|
||||
|
||||
- &meditate
|
||||
name: Meditate
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
effects:
|
||||
- '\see{all}'
|
||||
- '\destroy{0}'
|
||||
image: meditate
|
||||
type: personal
|
||||
flavour: 'It \textit{is} just sitting.'
|
||||
|
||||
- &diamorphine
|
||||
name: Diamorphine
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
risk: 1
|
||||
effects:
|
||||
- '\see{all}'
|
||||
- '\destroy{all}'
|
||||
image: diamorphine
|
||||
type: personal
|
||||
flavour: 'Highly addicting.'
|
||||
|
||||
- &desperate_times
|
||||
name: Desperate Times
|
||||
costs:
|
||||
energy: all
|
||||
effects:
|
||||
- '\supply{10}'
|
||||
- '\take{5}'
|
||||
image: desparate_times
|
||||
type: sled
|
||||
flavour: 'Desperate measures hotline, how may I help you?'
|
||||
|
||||
- &lead_sled
|
||||
name: Lead Sled
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
risk: 1
|
||||
effects:
|
||||
- '\supply{10}'
|
||||
- '\take{10}'
|
||||
image: lead_sled
|
||||
type: sled
|
||||
flavour: "At least it's not a zeppelin."
|
||||
|
||||
- &damaged
|
||||
name: Damaged
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
effects:
|
||||
- '\damagetext'
|
||||
image: damaged
|
||||
type: damage
|
||||
flavour: 'You have been hurt.'
|
||||
|
||||
- &dog_shoes
|
||||
name: Dog Shoes
|
||||
costs:
|
||||
energy: 2
|
||||
health: 3
|
||||
effects:
|
||||
- '\speed{+2}'
|
||||
image: dog_shoes
|
||||
type: attachment
|
||||
flavour: 'Dogs look cute in shoes.'
|
||||
|
||||
- &squirrel
|
||||
name: Squirrel
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
risk: 1
|
||||
effects:
|
||||
- '\speed{+3}'
|
||||
image: squirrel
|
||||
type: attachment
|
||||
flavour: 'Dogs \emph{hate} squirrels.'
|
||||
|
||||
- &tiara
|
||||
name: Tiara
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
risk: 1
|
||||
effects:
|
||||
- '\daydraw{+1}'
|
||||
- '\speed{+1}'
|
||||
image: tiara
|
||||
type: attachment
|
||||
flavour: 'Makes the dog feel special.'
|
||||
|
||||
- &bear
|
||||
name: Bear
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
risk: 2
|
||||
effects:
|
||||
- '\speed{+5}'
|
||||
image: bear
|
||||
type: dog
|
||||
flavour: 'In hindsight, not the best idea.'
|
||||
|
||||
- &big_dog
|
||||
name: Big Dog
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
effects:
|
||||
- '\speed{+3}'
|
||||
image: big_dog
|
||||
type: dog
|
||||
flavour: "He's not red though."
|
||||
|
||||
- &greyhound
|
||||
name: Greyhound
|
||||
costs:
|
||||
risk: 2
|
||||
effects:
|
||||
- '\speed{+3}'
|
||||
- '\nohold'
|
||||
image: greyhound
|
||||
type: dog
|
||||
flavour: 'What happens when you mix the colours on a husky? You get a grey hound.'
|
||||
|
||||
- &malamute
|
||||
name: Malamute
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
risk: 1
|
||||
effects:
|
||||
- '\daydraw{+2}'
|
||||
image: malamute
|
||||
type: dog
|
||||
flavour: 'A common sled hauling breed.'
|
||||
|
||||
- &problem_dog
|
||||
name: Problem Dog
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
risk: 1
|
||||
effects:
|
||||
- '\daydraw{-1}'
|
||||
- '\speed{+3}'
|
||||
image: problem_dog
|
||||
type: dog
|
||||
flavour: "I swear, if you weren't so fast."
|
||||
|
||||
- &bison
|
||||
name: Bison
|
||||
costs:
|
||||
energy: 2
|
||||
risk: 1
|
||||
effects:
|
||||
- '\draw{5}'
|
||||
image: bison
|
||||
type: food
|
||||
flavour: "It's very lean."
|
||||
|
||||
- &poutine
|
||||
name: Poutine
|
||||
costs:
|
||||
health: 2
|
||||
effects:
|
||||
- '\draw{1}'
|
||||
- '\nohypothermia'
|
||||
image: poutine
|
||||
type: food
|
||||
flavour: 'The great Canadian carb!'
|
||||
|
||||
- &venison
|
||||
name: Venison
|
||||
costs:
|
||||
health: 2
|
||||
effects:
|
||||
- '\draw{3}'
|
||||
image: venison
|
||||
type: food
|
||||
flavour: 'Better than breakfast.'
|
||||
|
||||
- &steak
|
||||
name: Steak
|
||||
effects:
|
||||
- '\draw{1}'
|
||||
image: steak
|
||||
type: food
|
||||
flavour: "Well aren't you fancy."
|
||||
|
||||
- &jerky
|
||||
name: Jerky
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
effects:
|
||||
- '\draw{3}'
|
||||
image: jerky
|
||||
type: food
|
||||
flavour: 'Watch your sodium!'
|
||||
|
||||
- &midnight_sun
|
||||
name: Midnight Sun
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
risk: 1
|
||||
effects:
|
||||
- '\move{10}'
|
||||
image: midnight_sun
|
||||
type: movement
|
||||
flavour: 'Strange things are done in the midnight sun.'
|
||||
|
||||
- &push
|
||||
name: Push
|
||||
costs:
|
||||
energy: 1
|
||||
effects:
|
||||
- '\move{5}'
|
||||
image: push
|
||||
type: movement
|
||||
flavour: 'Not a full mush, but still putting in some effort.'
|
||||
|
||||
- &slow_and_steady
|
||||
name: Slow and Steady
|
||||
effects:
|
||||
- '\draw{1}'
|
||||
- '\move{0}'
|
||||
image: slow_and_steady
|
||||
type: movement
|
||||
flavour: 'Maybe a bit too slow.'
|
||||
|
||||
- &band_aid
|
||||
name: Band Aid
|
||||
effects:
|
||||
- '\see{1}'
|
||||
- '\destroy{1}'
|
||||
image: band_aid
|
||||
type: personal
|
||||
flavour: 'Not much.'
|
||||
|
||||
- &bandage
|
||||
name: Bandage
|
||||
costs:
|
||||
energy: 1
|
||||
effects:
|
||||
- '\see{5}'
|
||||
- '\destroy{1}'
|
||||
image: bandage
|
||||
type: personal
|
||||
flavour: 'Make sure you wrap it tight.'
|
||||
|
||||
- &brandy
|
||||
name: Brandy
|
||||
costs:
|
||||
risk: 1
|
||||
effects:
|
||||
- '\see{5}'
|
||||
- '\destroy{1}'
|
||||
image: brandy
|
||||
type: personal
|
||||
flavour: 'Brought by a St.\ Bernard'
|
||||
|
||||
- &caffeine
|
||||
name: Caffeine
|
||||
costs:
|
||||
health: 2
|
||||
effects:
|
||||
- '\draw{1}'
|
||||
- '\see{2}'
|
||||
- '\destroy{1}'
|
||||
image: caffeine
|
||||
type: personal
|
||||
flavour: 'The greatest addiction ever.'
|
||||
|
||||
- &improvise
|
||||
name: Improvise
|
||||
effects:
|
||||
- '\take{1}'
|
||||
image: improvise
|
||||
type: sled
|
||||
flavour: 'MacGyver of the north.'
|
||||
|
||||
- &makeshift_sled
|
||||
name: Makeshift Sled
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
effects:
|
||||
- '\supply{2}'
|
||||
- '\take{6}'
|
||||
image: makeshift_sled
|
||||
type: sled
|
||||
flavour: "Rickety, but it'll hold."
|
||||
|
||||
- &salvage
|
||||
name: Salvage
|
||||
costs:
|
||||
energy: 1
|
||||
health: 1
|
||||
effects:
|
||||
- '\supply{3}'
|
||||
- '\take{2}'
|
||||
image: salvage
|
||||
type: sled
|
||||
flavour: 'Take the good with the bad.'
|
||||
|
||||
- &antique_sled
|
||||
name: Antique Sled
|
||||
costs:
|
||||
health: 5
|
||||
effects:
|
||||
- '\supply{2}'
|
||||
- '\take{8}'
|
||||
image: antique_sled
|
||||
type: sled
|
||||
flavour: 'Withstood the test of the time.'
|
||||
|
||||
- &rush
|
||||
name: Rush
|
||||
costs:
|
||||
health: 3
|
||||
risk: 1
|
||||
effects:
|
||||
- '\move{8}'
|
||||
image: rush
|
||||
type: movement
|
||||
flavour: 'Hurry up!'
|
||||
|
||||
- &supply_run
|
||||
name: Supply Run
|
||||
effects:
|
||||
- '\move{3}'
|
||||
image: supply_run
|
||||
type: movement
|
||||
flavour: 'Not as easy as dropping by the grocery store.'
|
||||
|
||||
# }}}
|
||||
|
||||
decks:
|
||||
- name: Starter1
|
||||
cards:
|
||||
- &a_hat1
|
||||
data:
|
||||
<<: *a_hat
|
||||
rarity: common
|
||||
deck: Starter1
|
||||
output: "cards/a_hat1.tex"
|
||||
template: "templates/card.mako"
|
||||
- *breakfast
|
||||
- *breakfast
|
||||
- *dinner
|
||||
- *dog_chow
|
||||
- *first_aid
|
||||
- *first_aid
|
||||
- *good_dog
|
||||
- *grandma_soup
|
||||
- *husky
|
||||
- *lunch
|
||||
- *lunch
|
||||
- *move
|
||||
- *move
|
||||
- *move
|
||||
- *move
|
||||
- *mush
|
||||
- *repair_sled
|
||||
- *repair_sled
|
||||
- *upgrade_sled
|
||||
- *upgrade_sled
|
||||
- *wheel_dog
|
||||
|
||||
# documents:
|
||||
|
|
1000
build.ninja
Normal file
42
build.sh
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
# Incremental build script.
|
||||
# Main inputs are from the *.cue and *.yaml files in the top-level directory
|
||||
# Assets are taken from raw/ tex/ mako/ etc and put into the output/ directory
|
||||
# The output/ directory is populated with a ninja build script to do the
|
||||
# actual build, along with source files that are updated for a build.
|
||||
# Thus to build a full output in dir you would run: build.sh dir/ && cd dir/ && ninja build
|
||||
# Once built once, a simple `ninja` in the output directory should suffice
|
||||
|
||||
# echo "new" | update file
|
||||
# updates file with new content only if the content differs
|
||||
update() {
|
||||
fname="$1"
|
||||
data="$(cat)"
|
||||
new="$(echo "$data" | sha256sum | cut -d " " -f 1)"
|
||||
old="$(sha256sum "$fname" | cut -d " " -f 1)"
|
||||
if [ "$new" != "$old" ]; then
|
||||
echo "Updating $fname"
|
||||
echo "$data" > "$fname"
|
||||
fi
|
||||
}
|
||||
|
||||
outdir="${1:-output}/"
|
||||
|
||||
mkdir -p "$outdir"
|
||||
|
||||
json="$(cue export *.cue *.yaml)"
|
||||
|
||||
{
|
||||
echo "# Generated by build.sh on $(date)"
|
||||
|
||||
echo "include ../rules.ninja"
|
||||
|
||||
EOF
|
||||
} | update "$outdir/build.ninja"
|
||||
|
||||
# TODO: get json via `cue export *.cue *.yaml`
|
||||
|
||||
|
||||
|
99
cards.cue
Normal file
|
@ -0,0 +1,99 @@
|
|||
// Iditacards card and deck asset specification
|
||||
|
||||
package iditacards
|
||||
|
||||
import "list"
|
||||
|
||||
#CardType: "attachment" | "dog" | "food" | "movement" | "personal" | "sled" | "damage"
|
||||
#UnaryEffect: "see" | "destroy" | "supply" | "take" | "speed" | "draw" |
|
||||
"daydraw" | "move" | "damage"
|
||||
#NilaryEffect: "immortal" | "safepass" | "inplayatstart" | "discardonkill" |
|
||||
"nohypothermia" | "doubledistance" | "passdie" | "nohold" | "damagetext"
|
||||
|
||||
// the template for a card gets this
|
||||
#Card: {
|
||||
name: string
|
||||
type: #CardType
|
||||
costs: {
|
||||
energy: uint | *0 | "ALL"
|
||||
health: uint | *0 | "ALL"
|
||||
risk: uint | *0 | "ALL"
|
||||
}
|
||||
// effects: [#NAryEffect]: {} | null | int | "ALL" | =~"x[0-9]+"
|
||||
effects: [#UnaryEffect]: int | "ALL" | =~"x[0-9]+"
|
||||
effects: [#NilaryEffect]: {} | null
|
||||
flavour: string
|
||||
image: string
|
||||
rarity?: #Rarity
|
||||
deck?: string
|
||||
}
|
||||
cards: [string]: #Card
|
||||
|
||||
#Rarity: "info" | "starting" | "common" | "rare" | "epic" | "legendary"
|
||||
|
||||
decks: [string]: [Name=_]: {
|
||||
rarity: #Rarity
|
||||
count: int
|
||||
}
|
||||
|
||||
assets: {
|
||||
for deckname, deck in decks
|
||||
for cardname, freq in deck
|
||||
let card = cards[cardname] {
|
||||
"\(deckname)-\(cardname)[\(freq.count)]": {
|
||||
size: "750x1050"
|
||||
print: "-set option:distort:viewport 825x1125-37-37 -virtual-pixel Edge -distort SRT 0 +repage"
|
||||
depends: {
|
||||
assets: [
|
||||
"deck/\(deckname)",
|
||||
"card/\(card.image)",
|
||||
]
|
||||
files: [
|
||||
"iditacard.cls",
|
||||
]
|
||||
}
|
||||
|
||||
kind: "template"
|
||||
template: "card.tex"
|
||||
data: cards[cardname] & {
|
||||
rarity: freq.rarity
|
||||
deck: deckname
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for deckname, deck in decks
|
||||
for cardname, freq in deck
|
||||
let card = cards[cardname] {
|
||||
"card/\(cardname)": {
|
||||
kind: "image"
|
||||
source: "images/card/\(cardname).png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pseudoassets: {
|
||||
for deckname, deck in decks {
|
||||
"\(deckname)-deck": {
|
||||
kind: "cat"
|
||||
contents: [
|
||||
for cardname, freq in deck
|
||||
for idx in list.Range(0, freq.count, 1) {
|
||||
"\(deckname)-\(cardname)[\(freq.count)]"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
cardrun: {
|
||||
kind: "cat"
|
||||
contents: [
|
||||
for deckname, deck in decks
|
||||
for cardname, card in deck {
|
||||
for idx in list.Range(0, card.count, 1) {
|
||||
"\(deckname)-\(cardname)[\(card.count)]"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
640
cards.yaml
|
@ -1,12 +1,12 @@
|
|||
# The cards
|
||||
# vi: sw=2:ts=2:sts=2:et
|
||||
cards:
|
||||
- &a_hat
|
||||
a_hat: &a_hat
|
||||
name: 'A Hat'
|
||||
costs:
|
||||
energy: 2
|
||||
health: 2
|
||||
effects:
|
||||
- '\daydraw{+1}'
|
||||
daydraw: 1
|
||||
image: hat
|
||||
type: attachment
|
||||
flavour: 'I bet its a valve hat.'
|
||||
|
@ -17,7 +17,7 @@ cards:
|
|||
energy: 3
|
||||
health: 3
|
||||
effects:
|
||||
- '\speed{+1}'
|
||||
speed: 1
|
||||
image: dog_chow
|
||||
type: attachment
|
||||
flavour: 'A hungry dog is a slow dog.'
|
||||
|
|
43
configure.jq
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Takes iditacards output json and produces the dynamic ninja build
|
||||
|
||||
def everything:
|
||||
(.assets,.pseudoassets) | to_entries[] | .value + { name: .key };
|
||||
|
||||
def cuesources:
|
||||
$ARGS.positional | join(" ");
|
||||
|
||||
"# Generated from configure.jq, do not edit this file!",
|
||||
"",
|
||||
"root = .",
|
||||
"",
|
||||
"rule configure",
|
||||
" description = recreate build.ninja using configure.jq via configure.sh",
|
||||
" command = bash configure.sh > build.ninja",
|
||||
" generator = 1",
|
||||
" restat = 1",
|
||||
"",
|
||||
"build build.ninja: configure | configure.jq configure.sh \(cuesources)",
|
||||
"include rules.ninja",
|
||||
"",
|
||||
"build output/everything.json: cuegen \(cuesources)",
|
||||
" filter = .",
|
||||
"", (
|
||||
everything | (
|
||||
select(.kind == "template") | .w = (.size | split("x")[0]) | .h = (.size | split("x")[1]) |
|
||||
"build output/\(.name).json: extract output/everything.json",
|
||||
" filter = --arg asset '\(.name)' '.assets[$$asset].data'",
|
||||
"build output/\(.name).tex: template2tex output/\(.name).json | templates/\(.template)",
|
||||
" template = templates/\(.template)",
|
||||
"build output/\(.name).pdf: tex2pdf output/\(.name).tex || output/\(.name).pdf.dd",
|
||||
" dyndep = output/\(.name).pdf.dd",
|
||||
"build output/\(.name).pdf.dd: scantex output/\(.name).tex",
|
||||
"build output/\(.name).raw.png: pdf2png output/\(.name).pdf",
|
||||
" w = \(.w)",
|
||||
" h = \(.h)",
|
||||
"build output/\(.name).png: convert output/\(.name).raw.png",
|
||||
" args = \(.print)" # TODO: check that this doesn't break if print is missing
|
||||
)
|
||||
#,(
|
||||
# select(.kind == "tex") |
|
||||
#)
|
||||
)
|
4
configure.sh
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
# The real configure script uses jq to parse cue output
|
||||
cue export -- *.cue *.yaml | jq -r -f configure.jq --args -- *.cue *.yaml
|
0
dynamic.ninja
Normal file
|
@ -279,10 +279,10 @@
|
|||
\scoped[shift={(13.5,-3.75)},yscale=-1]{\cardtrackindicator{thirdleg}{\rotatebox[origin=c]{180}{Fifth Leg}}}
|
||||
\scoped[shift={(16.5,3.75)}]{\cardtrackindicator{thirdleg}{Sixth Leg}}
|
||||
|
||||
\node at (-12, 0) {\includegraphics[width=1cm]{images/icons/legend.png}};
|
||||
\node at (-9, 0) {\includegraphics[width=1cm]{images/icons/legend.png}};
|
||||
\node at (-6, 0) {\includegraphics[width=1cm]{images/icons/legend.png}};
|
||||
\node at (-3, 0) {\includegraphics[width=1cm]{images/icons/legend.png}};
|
||||
\node at (-12, 0) {\includegraphics[width=1cm]{icons/legend.png}};
|
||||
\node at (-9, 0) {\includegraphics[width=1cm]{icons/legend.png}};
|
||||
\node at (-6, 0) {\includegraphics[width=1cm]{icons/legend.png}};
|
||||
\node at (-3, 0) {\includegraphics[width=1cm]{icons/legend.png}};
|
||||
|
||||
\node at (-12.0,7.5) {\fontsize{24}{24}\bebas Start};
|
||||
\node at (18.0,-7.5) {\fontsize{24}{24}\bebas End};
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
|
||||
% Aspect ratio of about 3:2
|
||||
\newcommand{\art}[1]{%
|
||||
\node [rectangle, minimum width=649.8/300.0, minimum height=425.0/300.0, inner sep=0, anchor=north west] at (49.2/300.0, 888.0/300.0) {\noindent\includegraphics*[width=2.1664in, height=1.416667in]{#1}};
|
||||
\node [rectangle, minimum width=649.8/300.0, minimum height=425.0/300.0, inner sep=0, anchor=north west] at (49.2/300.0, 888.0/300.0) {\noindent\includegraphics*[width=2.1664in, height=1.416667in]{card/#1}};
|
||||
}
|
||||
|
||||
\newcommand{\useicon}[1]{\raisebox{-0.1em}{\includegraphics[height=1em]{icons/#1.png}}}
|
||||
|
|
Before Width: | Height: | Size: 335 KiB After Width: | Height: | Size: 335 KiB |
Before Width: | Height: | Size: 333 KiB After Width: | Height: | Size: 333 KiB |
Before Width: | Height: | Size: 334 KiB After Width: | Height: | Size: 334 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 330 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 334 KiB After Width: | Height: | Size: 334 KiB |
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 330 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 337 KiB After Width: | Height: | Size: 337 KiB |
Before Width: | Height: | Size: 333 KiB After Width: | Height: | Size: 333 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 338 KiB After Width: | Height: | Size: 338 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 334 KiB After Width: | Height: | Size: 334 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 329 KiB After Width: | Height: | Size: 329 KiB |
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 336 KiB |
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
Before Width: | Height: | Size: 334 KiB After Width: | Height: | Size: 334 KiB |
Before Width: | Height: | Size: 329 KiB After Width: | Height: | Size: 329 KiB |
Before Width: | Height: | Size: 335 KiB After Width: | Height: | Size: 335 KiB |
Before Width: | Height: | Size: 14 MiB After Width: | Height: | Size: 14 MiB |
Before Width: | Height: | Size: 337 KiB After Width: | Height: | Size: 337 KiB |
Before Width: | Height: | Size: 335 KiB After Width: | Height: | Size: 335 KiB |
Before Width: | Height: | Size: 333 KiB After Width: | Height: | Size: 333 KiB |
Before Width: | Height: | Size: 333 KiB After Width: | Height: | Size: 333 KiB |
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 330 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 330 KiB |
Before Width: | Height: | Size: 337 KiB After Width: | Height: | Size: 337 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 334 KiB After Width: | Height: | Size: 334 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 336 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 338 KiB After Width: | Height: | Size: 338 KiB |
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 336 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 335 KiB After Width: | Height: | Size: 335 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 335 KiB After Width: | Height: | Size: 335 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
Before Width: | Height: | Size: 335 KiB After Width: | Height: | Size: 335 KiB |
Before Width: | Height: | Size: 333 KiB After Width: | Height: | Size: 333 KiB |
14
others.cue
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Iditacards other asset specification
|
||||
|
||||
images: [...string]
|
||||
|
||||
documents: [string]: #Dimensions
|
||||
|
||||
pseudoassets: {
|
||||
for image, path in images {
|
||||
"\(image)": {
|
||||
kind: "image"
|
||||
source: path
|
||||
}
|
||||
}
|
||||
}
|
28
rules.ninja
Normal file
|
@ -0,0 +1,28 @@
|
|||
rule template2tex
|
||||
description = convert $in to $out using $template as a template
|
||||
command = gomplate --left-delim '«' --right-delim '»' -c .=$in < $template > $out
|
||||
|
||||
rule cuegen
|
||||
description = run cue on $in to produce $out
|
||||
command = cue export $in > $out
|
||||
|
||||
rule extract
|
||||
description = extract $out from $in via jq filter $filter
|
||||
command = jq $filter < $in | bash update.sh $out
|
||||
restat = 1
|
||||
|
||||
rule tex2pdf
|
||||
description = render tex from $in to $out
|
||||
command = xelatex -interaction=batchmode -halt-on-error --shell-escape --output-directory=$$(dirname $in) $in
|
||||
|
||||
rule scantex
|
||||
description = scan tex $in for dependencies
|
||||
command = bash scantex.sh $in > $out
|
||||
|
||||
rule pdf2png
|
||||
description = convert pdf $in to png $out with size $w by $h
|
||||
command = pdftoppm -scale-to-x $w -scale-to-y $h -png $in > $out
|
||||
|
||||
rule convert
|
||||
description = run ImageMagick convert on $in with args $args to $out
|
||||
command = convert $in $args $out
|
38
scantex.sh
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo 'ninja_dyndep_version = 1'
|
||||
|
||||
src="$1"
|
||||
tgt="${src%%.*}.pdf"
|
||||
aux="${src%%.*}.aux"
|
||||
log="${src%%.*}.log"
|
||||
|
||||
# get_tex command
|
||||
# returns the argument of \command{...} in the src document
|
||||
get_tex() {
|
||||
grep "[\]$1" "$src" | sed 's/.*{\(.*\)}.*/\1/'
|
||||
}
|
||||
|
||||
deps=( )
|
||||
|
||||
if grep -q '\\documentclass{iditacard}' "$src"; then
|
||||
deps+=(
|
||||
# The class file
|
||||
'iditacard.cls'
|
||||
|
||||
# The artwork
|
||||
"images/cards/$(get_tex art).png"
|
||||
|
||||
# The deckmark
|
||||
"images/deck/$(get_tex deck).png"
|
||||
)
|
||||
fi
|
||||
|
||||
read -r -a rawimages <<<"$(grep -o '\\includegraphics[^}]*}' "$src" | sed 's/.*{\(.*\)}.*/images\/\1/')"
|
||||
deps+=( "${rawimages[@]}" )
|
||||
|
||||
if [ "${#deps[@]}" -gt 0 ]; then
|
||||
echo "build $tgt | $aux $log : dyndep | ${deps[*]}"
|
||||
else
|
||||
echo "build $tgt | $aux $log : dyndep"
|
||||
fi
|
|
@ -1,6 +1,19 @@
|
|||
## % TODO: how to get the deck info?
|
||||
\documentclass{iditacard}
|
||||
|
||||
\cardtype{${type}}
|
||||
## \rarity{${rarity}}
|
||||
## \deck{${deck}}
|
||||
\rarity{${rarity}}
|
||||
\deck{${deck}}
|
||||
|
||||
\begin{document}
|
||||
\begin{card}
|
||||
\art{${image}}
|
||||
% if costs["energy"] > 0:
|
||||
\energy{${costs["energy"]}}
|
||||
% endif
|
||||
% if costs["health"] > 0:
|
||||
\health{${costs["health"]}}
|
||||
% endif
|
||||
% if costs["risk"] > 0:
|
||||
\risk{${costs["risk"]}}
|
||||
% endif
|
||||
\name{${name}}
|
||||
|
|
28
templates/card.tex
Normal file
|
@ -0,0 +1,28 @@
|
|||
\documentclass{iditacard}
|
||||
|
||||
\cardtype{«.type»}
|
||||
\rarity{«.rarity»}
|
||||
\deck{«.deck»}
|
||||
|
||||
\begin{document}
|
||||
\begin{card}
|
||||
\art{«.image»}
|
||||
«- if gt .costs.energy 0»
|
||||
\energy{«.costs.energy»}
|
||||
«- end»
|
||||
«- if gt .costs.health 0»
|
||||
\health{«.costs.health»}
|
||||
«- end»
|
||||
«- if gt .costs.risk 0»
|
||||
\risk{«.costs.risk»}
|
||||
«- end»
|
||||
\name{«.name»}
|
||||
\text{
|
||||
«- range $effect, $amount := .effects -»
|
||||
\«- $effect -»{«- $amount -»}
|
||||
«- end -»
|
||||
}
|
||||
\flava{«.flavour»}
|
||||
\type{«.type»}
|
||||
\end{card}
|
||||
\end{document}
|
2
test/.ninja_log
Normal file
|
@ -0,0 +1,2 @@
|
|||
# ninja log v6
|
||||
0 1 1727044871155308194 a a7305d4d77a970a4
|
3
test/build.ninja
Normal file
|
@ -0,0 +1,3 @@
|
|||
include ../rules.ninja
|
||||
|
||||
build a: foo test.txt
|
0
test/test.txt
Normal file
5
types.cue
Normal file
|
@ -0,0 +1,5 @@
|
|||
// Iditacards internal type definitions
|
||||
|
||||
package iditacards
|
||||
|
||||
#Dimensions: string & =~"[0-9]+x[0-9]+"
|
14
update.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Takes input from standard input and overwrites output argument file only if
|
||||
# they differ
|
||||
|
||||
input="$(cat)"
|
||||
output="$1"
|
||||
|
||||
new="$(sha256sum <<<"$input" | cut -d " " -f 1)"
|
||||
old="$(sha256sum "$output" 2>/dev/null | cut -d " " -f 1)"
|
||||
|
||||
if [ "$new" != "$old" ]; then
|
||||
echo -n "$input" > "$output"
|
||||
fi
|