mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2024-12-28 04:23:42 +01:00
Moved tiled lib to a separate repository
This commit is contained in:
parent
5d4a862620
commit
e801bb5632
4 changed files with 34 additions and 233 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "assets/tinytiled"]
|
||||||
|
path = assets/tinytiled
|
||||||
|
url = forgejo@git.planet-casio.com:mibi88/tinytiled.git
|
|
@ -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
|
||||||
|
|
231
assets/tiled.py
231
assets/tiled.py
|
@ -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
1
assets/tinytiled
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit c2c8f1121656e93ff8ca2e56ce3f966d6586aeb1
|
Loading…
Reference in a new issue