Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tiled v1.10 export #1

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions export/tiled/exporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package tiled

import (
"errors"
"fmt"
"os"
"strings"
"text/template"
)

type Template struct {
TiledVersion string
TileWidth int
TileHeight int
TileCount int
Columns int
ImageSource string // e.g. ../14x2_output.local.png
ImageWidth int
ImageHeight int
Terrain1Name string
Terrain2Name string
TilesetName string
}

type Exporter struct {
tmpl *Template
}

var (
errNilTemplate = errors.New("template is nil")
errInvalidTemplate = errors.New("invalid template")
errInvalidWidth = errors.New("invalid width")
errInvalidHeight = errors.New("invalid height")
errInvalidTileCount = errors.New("invalid tile count")
errInvalidColumns = errors.New("invalid columns")
errInvalidTerrain1Name = errors.New("invalid terrain1 name")
errInvalidTerrain2Name = errors.New("invalid terrain2 name")
errInvalidImageSource = errors.New("invalid image source")
errInvalidImageWidth = errors.New("invalid image width")
errInvalidImageHeight = errors.New("invalid image height")
errInvalidTileWidth = errors.New("invalid tile width")
errInvalidTileHeight = errors.New("invalid tile height")
errInvalidTiledVersion = errors.New("invalid tiled version. expected 1.10.x")
errInvalidTilesetName = errors.New("invalid tileset name")
)

func NewExporter(template *Template) *Exporter {
return &Exporter{
tmpl: template,
}
}

func NewTemplate(
tilesetName string,
tileWidth int,
tileHeight int,
tileCount int,
columns int,
imageSource string,
imageWidth int,
imageHeight int,
terrain1Name string,
terrain2Name string,
) *Template {
return &Template{
TiledVersion: "1.10.2",
TilesetName: tilesetName,
TileWidth: tileWidth,
TileHeight: tileHeight,
TileCount: tileCount,
Columns: columns,
ImageSource: imageSource,
ImageWidth: imageWidth,
ImageHeight: imageHeight,
Terrain1Name: terrain1Name,
Terrain2Name: terrain2Name,
}
}

func (e *Exporter) Export() error {
err := e.tmpl.Validate()
if err != nil {
return err
}
var tmplFile = "templates/tiled/v1_10/14x2_tiled_1.10.x.tsx.tmpl"
tmpl, err := template.New(tmplFile).ParseFiles(tmplFile)
if err != nil {
return err
}

outFile, err := os.Create(fmt.Sprintf("out/%s.tsx", e.tmpl.TilesetName))
if err != nil {
panic(err)
}
defer outFile.Close()

err = tmpl.Execute(outFile, e.tmpl)
if err != nil {
return err
}
return nil
}

func (t *Template) Validate() error {
errs := make([]error, 0)

if t == nil {
return errNilTemplate
}
if t.TilesetName == "" {
errs = append(errs, errInvalidTilesetName)
}
if t.TileWidth == 0 {
errs = append(errs, errInvalidTileWidth)
}
if t.TileHeight == 0 {
errs = append(errs, errInvalidTileHeight)
}
if t.TileCount == 0 {
errs = append(errs, errInvalidTileCount)
}
if t.Columns == 0 {
errs = append(errs, errInvalidColumns)
}
if t.Terrain1Name == "" {
errs = append(errs, errInvalidTerrain1Name)
}
if t.Terrain2Name == "" {
errs = append(errs, errInvalidTerrain2Name)
}
if t.ImageSource == "" {
errs = append(errs, errInvalidImageSource)
}
if t.ImageWidth == 0 {
errs = append(errs, errInvalidWidth)
}
if t.ImageHeight == 0 {
errs = append(errs, errInvalidHeight)
}
if t.TiledVersion == "" || !strings.HasPrefix(t.TiledVersion, "1.10") {
errs = append(errs, errInvalidTiledVersion)
}
if t.ImageHeight == 0 {
errs = append(errs, errInvalidImageHeight)
}
if t.ImageWidth == 0 {
errs = append(errs, errInvalidImageWidth)
}

if len(errs) > 0 {
errs = append(errs, errInvalidTemplate)
return errors.Join(errs...)
}

return nil
}
9 changes: 5 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"fmt"
"github.com/krylphi/autotiler/unpack"
"image"
"image/png"
"log"
Expand All @@ -25,15 +26,15 @@ func main() {
panic(err)
}

g := NewUnpacker(img, 4)
g := unpack.NewUnpacker(img, 4)
if err := g.Init(); err != nil {
log.Fatal(err)
}

// todo parallel

canvas := g.From6to16Terrain1()
file15t1, err := os.Create(fmt.Sprintf("16x1_terrain1_%s", outputFile))
file15t1, err := os.Create(fmt.Sprintf("out/16x1_terrain1_%s", outputFile))
if err != nil {
panic(err)
}
Expand All @@ -45,7 +46,7 @@ func main() {
}

canvas = g.From6to16Terrain2()
file15t2, err := os.Create(fmt.Sprintf("16x1_terrain2_%s", outputFile))
file15t2, err := os.Create(fmt.Sprintf("out/16x1_terrain2_%s", outputFile))
if err != nil {
panic(err)
}
Expand All @@ -57,7 +58,7 @@ func main() {
}

canvas = g.From6to28()
file1, err := os.Create(fmt.Sprintf("14x2_%s", outputFile))
file1, err := os.Create(fmt.Sprintf("out/14x2_%s", outputFile))
if err != nil {
panic(err)
}
Expand Down
87 changes: 87 additions & 0 deletions templates/tiled/v1_10/14x2_tiled_1.10.x.tsx.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.10" tiledversion="1.10.2" name="{{.TilesetName}}" tilewidth="{{.TileWidth}}" tileheight="{{.TileHeight}}" tilecount="{{.TileCount}}" columns="{{.Columns}}">
<transformations hflip="1" vflip="1" rotate="1" preferuntransformed="0"/>
<image source="{{.ImageSource}}" width="{{.ImageWidth}}" height="{{.ImageHeight}}"/>
<wangsets>
<wangset name="14x2_Mixed_{{.Terrain1Name}}_to_{{.Terrain2Name}}" type="mixed" tile="-1">
<wangcolor name="{{.Terrain1Name}}" color="#ff0000" tile="-1" probability="1"/>
<wangcolor name="{{.Terrain2Name}}" color="#00ff00" tile="-1" probability="1"/>
<wangtile tileid="0" wangid="1,1,1,1,1,1,1,1"/>
<wangtile tileid="1" wangid="2,1,1,1,1,1,1,1"/>
<wangtile tileid="2" wangid="2,1,2,1,1,1,1,1"/>
<wangtile tileid="3" wangid="2,2,2,1,1,1,1,1"/>
<wangtile tileid="4" wangid="2,1,1,1,2,1,1,1"/>
<wangtile tileid="5" wangid="2,1,2,1,2,1,1,1"/>
<wangtile tileid="6" wangid="2,2,2,1,2,1,1,1"/>
<wangtile tileid="7" wangid="2,1,2,2,2,1,1,1"/>
<wangtile tileid="8" wangid="2,2,2,2,2,1,1,1"/>
<wangtile tileid="9" wangid="2,1,2,1,2,1,2,1"/>
<wangtile tileid="10" wangid="2,2,2,1,2,1,2,1"/>
<wangtile tileid="11" wangid="2,2,2,2,2,1,2,1"/>
<wangtile tileid="12" wangid="2,2,2,1,2,2,2,1"/>
<wangtile tileid="13" wangid="2,2,2,2,2,2,2,1"/>
<wangtile tileid="14" wangid="2,2,2,2,2,2,2,2"/>
<wangtile tileid="15" wangid="1,2,2,2,2,2,2,2"/>
</wangset>
<wangset name="14x2_Corner_{{.Terrain1Name}}_to_{{.Terrain2Name}}" type="corner" tile="-1">
<wangcolor name="{{.Terrain1Name}}" color="#ff0000" tile="-1" probability="1"/>
<wangcolor name="{{.Terrain2Name}}" color="#00ff00" tile="-1" probability="1"/>
<wangtile tileid="0" wangid="0,1,0,1,0,1,0,1"/>
<wangtile tileid="3" wangid="0,2,0,1,0,1,0,1"/>
<wangtile tileid="8" wangid="0,2,0,2,0,1,0,1"/>
<wangtile tileid="12" wangid="0,2,0,1,0,2,0,1"/>
<wangtile tileid="13" wangid="0,2,0,2,0,2,0,1"/>
<wangtile tileid="14" wangid="0,2,0,2,0,2,0,2"/>
</wangset>
<wangset name="14x2_Edge_{{.Terrain1Name}}_to_{{.Terrain2Name}}" type="edge" tile="-1">
<wangcolor name="{{.Terrain1Name}}" color="#ff0000" tile="-1" probability="1"/>
<wangcolor name="{{.Terrain2Name}}" color="#00ff00" tile="-1" probability="1"/>
<wangtile tileid="0" wangid="1,0,1,0,1,0,1,0"/>
<wangtile tileid="1" wangid="2,0,1,0,1,0,1,0"/>
<wangtile tileid="3" wangid="2,0,2,0,1,0,1,0"/>
<wangtile tileid="4" wangid="2,0,1,0,2,0,1,0"/>
<wangtile tileid="8" wangid="2,0,2,0,2,0,1,0"/>
<wangtile tileid="14" wangid="2,0,2,0,2,0,2,0"/>
</wangset>
<wangset name="14x2_Mixed_{{.Terrain2Name}}_to_{{.Terrain1Name}}" type="mixed" tile="-1">
<wangcolor name="{{.Terrain1Name}}" color="#ff0000" tile="-1" probability="1"/>
<wangcolor name="{{.Terrain2Name}}" color="#00ff00" tile="-1" probability="1"/>
<wangtile tileid="0" wangid="1,1,1,1,1,1,1,1"/>
<wangtile tileid="1" wangid="2,1,1,1,1,1,1,1"/>
<wangtile tileid="14" wangid="2,2,2,2,2,2,2,2"/>
<wangtile tileid="15" wangid="1,2,2,2,2,2,2,2"/>
<wangtile tileid="16" wangid="1,2,1,2,2,2,2,2"/>
<wangtile tileid="17" wangid="1,1,1,2,2,2,2,2"/>
<wangtile tileid="18" wangid="1,2,2,2,1,2,2,2"/>
<wangtile tileid="19" wangid="1,2,1,2,1,2,2,2"/>
<wangtile tileid="20" wangid="1,1,1,2,1,2,2,2"/>
<wangtile tileid="21" wangid="1,2,1,1,1,2,2,2"/>
<wangtile tileid="22" wangid="1,1,1,1,1,2,2,2"/>
<wangtile tileid="23" wangid="1,2,1,2,1,2,1,2"/>
<wangtile tileid="24" wangid="1,1,1,2,1,2,1,2"/>
<wangtile tileid="25" wangid="1,1,1,1,1,2,1,2"/>
<wangtile tileid="26" wangid="1,1,1,2,1,1,1,2"/>
<wangtile tileid="27" wangid="1,1,1,1,1,1,1,2"/>
</wangset>
<wangset name="14x2_Corner_{{.Terrain2Name}}_to_{{.Terrain1Name}}" type="corner" tile="-1">
<wangcolor name="{{.Terrain1Name}}" color="#ff0000" tile="-1" probability="1"/>
<wangcolor name="{{.Terrain2Name}}" color="#00ff00" tile="-1" probability="1"/>
<wangtile tileid="0" wangid="0,1,0,1,0,1,0,1"/>
<wangtile tileid="14" wangid="0,2,0,2,0,2,0,2"/>
<wangtile tileid="17" wangid="0,1,0,2,0,2,0,2"/>
<wangtile tileid="22" wangid="0,1,0,1,0,2,0,2"/>
<wangtile tileid="26" wangid="0,1,0,2,0,1,0,2"/>
<wangtile tileid="27" wangid="0,1,0,1,0,1,0,2"/>
</wangset>
<wangset name="14x2_Edge_{{.Terrain2Name}}_to_{{.Terrain1Name}}" type="edge" tile="-1">
<wangcolor name="{{.Terrain1Name}}" color="#ff0000" tile="-1" probability="1"/>
<wangcolor name="{{.Terrain2Name}}" color="#00ff00" tile="-1" probability="1"/>
<wangtile tileid="0" wangid="1,0,1,0,1,0,1,0"/>
<wangtile tileid="14" wangid="2,0,2,0,2,0,2,0"/>
<wangtile tileid="15" wangid="1,0,2,0,2,0,2,0"/>
<wangtile tileid="17" wangid="1,0,1,0,2,0,2,0"/>
<wangtile tileid="18" wangid="1,0,2,0,1,0,2,0"/>
<wangtile tileid="22" wangid="1,0,1,0,1,0,2,0"/>
</wangset>
</wangsets>
</tileset>
7 changes: 4 additions & 3 deletions unpacker.go → unpack/unpacker.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package unpack

import (
"fmt"
Expand Down Expand Up @@ -65,7 +65,7 @@ func (u *Unpacker) From6to16Terrain1() *image.NRGBA {
canvas := image.NewNRGBA(image.Rect(0, 0, u.tileWidth*16, u.tileHeight*1))
// todo optimize to generate automatically and consider scaling for 47 and 255 tilesets
exp := export28TileSet()
quadMap := append(exp[:14], exp[15], exp[14])
quadMap := append(exp[:14], exp[15], exp[14]) // 15 - filled terrain 2, 14 - small terrain 2 patch on top

for idx := 0; idx < 16; idx++ {
u.drawFullTile(canvas, quadMap[idx], idx, 16)
Expand All @@ -77,7 +77,7 @@ func (u *Unpacker) From6to16Terrain2() *image.NRGBA {
canvas := image.NewNRGBA(image.Rect(0, 0, u.tileWidth*16, u.tileHeight*1))
// todo optimize to generate automatically and consider scaling for 47 and 255 tilesets
exp := export28TileSet()
quadMap := append(exp[14:], exp[1], exp[0])
quadMap := append(exp[14:], exp[1], exp[0]) // 0 - filled terrain 1, 1 - small terrain 1 patch on top

for idx := 0; idx < 16; idx++ {
u.drawFullTile(canvas, quadMap[idx], idx, 16)
Expand All @@ -97,6 +97,7 @@ func (u *Unpacker) From6to28() *image.NRGBA {
return canvas
}

// Deprecated: inconsistent behaviour in Tiled
func (u *Unpacker) From28To92(img *image.NRGBA) *image.NRGBA {
//51
//6 x 9 region (54 total spaces, 3 empty)
Expand Down
2 changes: 1 addition & 1 deletion util.go → unpack/util.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package unpack

import (
"image"
Expand Down