Moved tiled lib to a separate repository

This commit is contained in:
mibi88 2024-07-31 18:44:02 +02:00
parent 5d4a862620
commit e801bb5632
4 changed files with 34 additions and 233 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "assets/tinytiled"]
path = assets/tinytiled
url = forgejo@git.planet-casio.com:mibi88/tinytiled.git

View file

@ -1,17 +1,45 @@
"""
This is the main converter script. It uses the tiled.py script to handle the
tiled maps.
We're trying to follow the PEP, so please read PEP 8 (if you haven't already):
https://peps.python.org/pep-0008/, so please write variable names in sneak_case
and class names in PascalCase.
To improve the lisibility of this code, please document your methods, add
comments (yes, it's hard to add the right amount of comments), and add type
hints, to avoid bugs and make it easy to understand how to use them.
To document your methods, you should read PEP 257:
https://peps.python.org/pep-0257/.
Thanks,
Mibi88
"""
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import json import json
import os import os
import sys import sys
# Add the assets folder to the path, to be able to import the tiled script.
sys.path.append("../assets/") sys.path.append("../assets/")
import fxconv import fxconv
from tiled import * from tinytiled import *
# If the output of the converter should be verbose.
VERBOSE = 1 VERBOSE = 1
# The sign types, used to find the sign icon.
SIGN_TYPES = ["SGN", "INFO"] SIGN_TYPES = ["SGN", "INFO"]
# The NPC faces, used to find the face id.
FACES = ["MALE", "FEMALE", "MILKMAN", "POLICE"] FACES = ["MALE", "FEMALE", "MILKMAN", "POLICE"]
# The precision of the fixed point numbers.
# WARNING: The PRECISION define in config.h should contain the same value!
PRECISION = 8 PRECISION = 8
def convert(input, output, params, target): def convert(input: str, output: str, params: dict, target):
"""
This method gets called by fxconv for each asset to convert.
"""
if params["custom-type"] == "tmx": if params["custom-type"] == "tmx":
convert_map(input, output, params, target) convert_map(input, output, params, target)
return 0 return 0

View file

@ -1,231 +0,0 @@
import xml.etree.ElementTree as ET
import os
# TODO: Add more doc.
class Tileset:
"""
Handle the tiled tileset.
"""
def __init__(self, element: ET.Element, parent_dir = ""):
firstgid_str = element.get("firstgid")
if firstgid_str == None: raise Exception("firstgid not found!")
self.firstgid = int(firstgid_str)
self.source = element.get("source")
if self.source == None: raise Exception("source not found!")
self.source = parent_dir + self.source
tree = ET.parse(self.source)
self.root = tree.getroot()
tilecount_str = self.root.get("tilecount")
if tilecount_str == None: raise Exception("tilecount not found!")
self.tilecount = int(tilecount_str)
columns_str = self.root.get("columns")
if columns_str == None: raise Exception("columns not found!")
self.columns = int(columns_str)
def is_raw_in_tileset(self, raw: int) -> bool:
if raw >= self.firstgid and raw < self.firstgid+self.tilecount:
return True
return False
def get_tile_from_raw(self, raw: int) -> int:
if not self.is_raw_in_tileset(raw) and raw:
raise Exception(f"Tile {raw} not in tileset!")
return raw-self.firstgid
class Layer:
"""
A class to handle a tiled map layer
"""
def __init__(self, element: ET.Element):
self.element = element
def get_width(self) -> int:
"""
Get the layer width
"""
value = self.element.get("width")
if value == None: raise Exception("Layer width not found")
return int(value)
def get_height(self) -> int:
"""
Get the layer height
"""
value = self.element.get("height")
if value == None: raise Exception("Layer height not found")
return int(value)
def get_raw_data(self) -> list:
"""
Get the data of the map
"""
data_tag = self.element.find("data")
if data_tag == None: raise Exception("Data not found!")
raw_data = data_tag.text.split(",")
int_data = []
for tile in raw_data:
int_data.append(int(tile))
return int_data
def get_data_with_tileset(self, tileset: Tileset):
raw_data = self.get_raw_data()
out_data = []
for i in raw_data:
out_data.append(tileset.get_tile_from_raw(i))
return out_data
class Object:
"""
An group object (see ObjectGroup) object.
"""
def __init__(self, element: ET.Element):
self.element = element
self.name = element.get("name")
if self.name == None: raise Exception("Name attribute missing!")
self.type = element.get("type")
if self.type == None:
self.type = ""
print("WARNING: Type attribute missing!")
x_str = element.get("x")
if x_str == None: raise Exception("X attribute missing!")
self.x = int(float(x_str))
y_str = element.get("y")
if y_str == None: raise Exception("Y attribute missing!")
self.y = int(float(y_str))
self.id = element.get("id")
if self.id == None: raise Exception("ID attribute missing!")
def __get_point(self) -> list:
# Private method to get a point. Used in get_data.
return [self.x, self.y]
def __get_polyline(self) -> list:
# Private method to get a polyline. Used in get_data.
data = self.element.find("polyline").get("points")
if data == None: raise Exception("Data not found!")
data = data.replace(' ', ',').split(',')
out_data = []
for i in data:
out_data.append(int(float(i)))
return out_data
def get_data(self) -> list:
"""
Get the geometric shape of this object.
"""
if self.element.find("point") != None:
# It is a point.
return self.__get_point()
if self.element.find("polyline") != None:
# It is a polyline.
return self.__get_polyline()
raise Exception("Unknown data!")
def get_data_type(self) -> str:
"""
Get the geometric shape of this object.
"""
if self.element.find("point") != None:
# It is a point.
return "point"
if self.element.find("polyline") != None:
# It is a polyline.
return "polyline"
raise Exception("Unknown data!")
def get_property(self, property: str) -> str:
"""
Get the value of a property.
"""
properties = self.element.find("properties")
if properties == None: raise Exception("Properties not found!")
for i in properties:
if i.get("name") == property:
value = i.get("value")
if value == None: raise Exception("Property value not found!")
return value
raise Exception(f"Property {property} not found!")
class ObjectGroup:
"""
Handle tiled object groups. They can contain points, lines and other
geometric shapes that can be very handy to add NPCs, the path they walk on,
as we do it here, in Collab_RPG.
"""
def __init__(self, element: ET.Element):
self.element = element
self.objects = []
for object in self.element.iterfind("object"):
self.objects.append(Object(object))
class Map:
"""
A class to handle the tiled maps.
"""
def __init__(self, input: str):
"""
Loads a tmx map made with tiled.
"""
tree = ET.parse(input)
self.root = tree.getroot()
self.parent_dir = os.path.abspath(input).rpartition('/')[0]
def get_property(self, property: str) -> str:
"""
Get a map property.
"""
properties = self.root.find("properties")
# If properties wasn't found.
if properties == None:
raise Exception("Properties not found!")
for child in properties:
# Look at the name attribute of each property
if child.get("name") == property:
value = child.get("value")
if value == None: raise Exception("Value attribute not found!")
return value
# The dialog file property wasn't found.
raise Exception(f"\"{property}\" property not found!")
def get_layer_by_id(self, layer_id: str) -> Layer:
"""
Get a layer by its id.
"""
for layer in self.root.iterfind("layer"):
if layer.get("id") == layer_id:
return Layer(layer)
raise Exception("Layer not found!")
def get_layer_by_name(self, name: str) -> Layer:
"""
Get a layer by its name.
"""
for layer in self.root.iterfind("layer"):
if layer.get("name") == name:
return Layer(layer)
raise Exception("Layer not found!")
def get_objectgroup_by_id(self, group_id: str) -> Layer:
"""
Get a layer by its id.
"""
for layer in self.root.iterfind("objectgroup"):
if layer.get("id") == group_id:
return ObjectGroup(layer)
raise Exception("Object group not found!")
def get_objectgroup_by_name(self, name: str) -> Layer:
"""
Get a layer by its name.
"""
for layer in self.root.iterfind("objectgroup"):
if layer.get("name") == name:
return ObjectGroup(layer)
raise Exception("Object group not found!")
def get_tileset_by_firstgid(self, firstgid: int) -> Tileset:
for tileset in self.root.iterfind("tileset"):
if tileset.get("firstgid") == str(firstgid):
return Tileset(tileset, self.parent_dir + "/")
raise Exception("Tileset not found!")

1
assets/tinytiled Submodule

@ -0,0 +1 @@
Subproject commit c2c8f1121656e93ff8ca2e56ce3f966d6586aeb1