diff --git a/.gitignore b/.gitignore index f834a6a..2c5a8cf 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,4 @@ __pycache__/ *.sublime-workspace .vscode -level*.json tilesetnpp.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0e66469 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "assets/tinytiled"] + path = assets/tinytiled + url = forgejo@git.planet-casio.com:mibi88/tinytiled.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 355ad71..e00662b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,16 @@ set(SOURCES ) # Shared assets, fx-9860G-only assets and fx-CG-50-only assets set(ASSETS - assets/WorldRPG.world + assets/level0_dialogs.json + assets/level1_dialogs.json + assets/level2_dialogs.json + assets/level3_dialogs.json + assets/level4_dialogs.json + assets/level0.tmx + assets/level1.tmx + assets/level2.tmx + assets/level3.tmx + assets/level4.tmx # ... ) @@ -118,11 +127,11 @@ target_link_libraries(myaddin LibProf::LibProf Gint::Gint) if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G) # fx colormode if("${COLORMODE_fx}" STREQUAL 1b) - target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR1BIT) + target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -g -DCOLOR1BIT) endif() if("${COLORMODE_fx}" STREQUAL 2b) - target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOR2BIT) + target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -g -DCOLOR2BIT) endif() if("${COLORMODE_fx}" STREQUAL 1b) @@ -140,7 +149,7 @@ if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G) elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50) # cg colormode if("${COLORMODE_cg}" STREQUAL EGA64) - target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -DCOLOREGA) + target_compile_options(myaddin PRIVATE -Wall -Wextra -O0 -g -DCOLOREGA) endif() if("${COLORMODE_cg}" STREQUAL 1b) diff --git a/assets-cg/ega64/tileset/fxconv-metadata.txt b/assets-cg/ega64/tileset/fxconv-metadata.txt index e561669..15d8aeb 100644 --- a/assets-cg/ega64/tileset/fxconv-metadata.txt +++ b/assets-cg/ega64/tileset/fxconv-metadata.txt @@ -2,4 +2,4 @@ tilesetEGA64_CG.png: type: bopti-image name: img_tilesetnpp profile: p8 - + \ No newline at end of file diff --git a/assets-cg/ega64/tileset/tilesetEGA64_CG.png b/assets-cg/ega64/tileset/tilesetEGA64_CG.png old mode 100644 new mode 100755 index 4fcde4c..44ba3a7 Binary files a/assets-cg/ega64/tileset/tilesetEGA64_CG.png and b/assets-cg/ega64/tileset/tilesetEGA64_CG.png differ diff --git a/assets-cg/fxconv-metadata.txt b/assets-cg/fxconv-metadata.txt index 86e8216..a8d3e6e 100644 --- a/assets-cg/fxconv-metadata.txt +++ b/assets-cg/fxconv-metadata.txt @@ -1,8 +1,7 @@ *.png: - custom-type: custom-image + custom-type: bopti-image name_regex: (.*)\.png \1_img profile: p8 - scale: 1 font.png: name: fontRPG diff --git a/assets-fx/1b/tileset/tileset1b.png b/assets-fx/1b/tileset/tileset1b.png index c2cc4e9..27ef69d 100644 Binary files a/assets-fx/1b/tileset/tileset1b.png and b/assets-fx/1b/tileset/tileset1b.png differ diff --git a/assets-fx/2b/tileset/tileset2b.png b/assets-fx/2b/tileset/tileset2b.png index df7c4bd..59ffc2b 100644 Binary files a/assets-fx/2b/tileset/tileset2b.png and b/assets-fx/2b/tileset/tileset2b.png differ diff --git a/assets/converters.py b/assets/converters.py index 7143aba..95d2799 100644 --- a/assets/converters.py +++ b/assets/converters.py @@ -1,410 +1,363 @@ -from random import randint -from PIL import Image -import fxconv +""" +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 json -import pathlib -import csv import os - -DEBUG = 0 - -def convert(input, output, params, target): - if params["custom-type"] == "map": - print("ERROR : Asset ", params["name"], " has legacy type map") - return 1 - elif params["custom-type"] == "world": - convert_world(input, output, params, target) - return 0 - elif params["custom-type"] == "custom-image": - convert_custom_image(input, output, params, target) - return 0 - elif params["custom-type"] == "font": - convert_font(input, output, params, target) - return 0 - elif params["custom-type"] == "dialogs": - print("ERROR : Asset ", params["name"], " has legacy type dialog") - #convert_dialogs(input, output, params, target) - return 0 - else: - return 1 - - - -def convert_world(input, output, params, target): - print( "WE ARE COMPUTING THE WORLD", input ) - - data = json.load(open(input, "r")) - nbMaps = ["fileName" in i for i in data["maps"]].count(True) - if DEBUG: print( "We have to treat ", nbMaps, " maps") - if DEBUG: print( "So let's go ... ") - - structWorld = fxconv.Structure() - #structExtra = fxconv.Structure() - - for i in range(nbMaps): - nameMap = data["maps"][i]["fileName"].replace(".tmx","") - nameMapFree = nameMap.split("/")[-1] - #count the number of "back" (cd ..) to locate the map on the computer - nbRetour = nameMap.count("..")+1 - #create the map absolute path - - nameTMX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".tmx" - nameJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json" - - commandline = 'tiled --export-map json ' + nameTMX + ' ' + nameJSON - if DEBUG: print( "TILED COMMAND LINE FOR MAPS : ", commandline ) - os.system( commandline ) - - mapPath = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json" - if DEBUG: print("Map ", i , " name : ", mapPath ) - - xmin = data["maps"][i]["x"] - if DEBUG: print( "xmin = ", xmin ) - - ymin = data["maps"][i]["y"] - if DEBUG: print( "ymin = ", ymin ) - - xmax = data["maps"][i]["x"] + data["maps"][i]["width"] - if DEBUG: print( "xmax = ", xmax ) - - ymax = data["maps"][i]["y"] + data["maps"][i]["height"] - if DEBUG: print( "ymax = ", ymax ) - - map = get_tile_map_data( mapPath, output, params, target, xmin, ymin, xmax, ymax) - if DEBUG: print( "Map = ", map ) - structWorld += fxconv.ptr( map ) - - structWorld += fxconv.u32(0) - - #generate ! - fxconv.elf(structWorld, output, "_" + params["name"], **target) - - -def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax): - print( "WE ARE COMPUTING THE MAP : ", input ) - data = json.load(open(input, "r")) - - #find the tileset in use. it's a relative path (like ../tileset.tsx) - nameTileset = data["tilesets"][0]["source"].replace(".tsx","") - if DEBUG: print(nameTileset) - #the name of the tileset without the .something - nameTilesetFree = nameTileset.split("/")[-1] - #count the number of "back" (cd ..) to locate the tileset on the computer - nbRetour = nameTileset.count("..")+1 - #create the tileset absolute path - tilesetTSX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".tsx" - tilesetJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".json" - - commandline = 'tiled --export-tileset json ' + tilesetTSX + ' ' + tilesetJSON - if DEBUG: print( "TILED COMMAND LINE FOR TILESET : ", commandline ) - os.system( commandline ) - - tileset = open(tilesetJSON, "r") - data_tileset = json.load(tileset) - tileset_size = data_tileset.get("columns") - tileset.close() - - #find the ID of the first tile in the walkable tileset () - indexWalkable = data["tilesets"][1]["firstgid"] - if DEBUG: print(indexWalkable) - - #Extract from the json the width, height - w, h = data["width"], data["height"] - - #nbTileLayer is the number of "true" layers (without ObjectsLayer) - nbTilelayer = ["data" in i for i in data["layers"]].count(True) - 1 - if DEBUG: print( nbTilelayer) - - #index of the various layers (may change from one map to another) - layer_walkable = 0 - layer_foreground = 0 - layer_background = 0 - - #create the structure of the map - structMap = fxconv.Structure() - - structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer) - structMap += fxconv.u32(tileset_size) - - structMap += fxconv.u32(xmin) + fxconv.u32(ymin) + fxconv.u32(xmax) + fxconv.u32(ymax) - - structMap += fxconv.ref(f"img_{nameTilesetFree}") - - - #extraction of the data contained in the layer "Walkable" of the map - for i in range(nbTilelayer+1): - datavalid = data["layers"][i] - if datavalid["name"]=="Walkable": - layer_walkable = i - if DEBUG: print( "Walkable Tile Data in layer : ", layer_walkable) - break - elif i==nbTilelayer: - print( "ERROR : No Walkable layer data !!!" ) - - walk_data = bytes() - layer = data["layers"][layer_walkable] - for tile in layer["data"]: - #print( tile ) - if tile == 0: walk_data += fxconv.u8(tile) #if walkable_data = 0 then it is a blanck cell so nothing to change - else : walk_data += fxconv.u8(tile-indexWalkable) #if !=0 than we need to shift the tile number by considering the first tileID (given by indexwalkable) - structMap += fxconv.ptr(walk_data) - - - - - nbextra = 0 - extradata = fxconv.Structure() - - nbextra, extradata = get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax) - - if (nbextra==0): - structMap += fxconv.u32( 0 ) - structMap += fxconv.u32( 0 ) - else: - structMap += fxconv.u32( int(nbextra) ) - structMap += fxconv.ptr( extradata ) - - - - - nameDialog = data["properties"][0]["value"] - dialogfile = "/".join(input.split("/")[:-nbRetour]) + "/" + nameDialog - if DEBUG: print( "THE DIALOGS ARE CONTAINED IN THE FILE : ", dialogfile ) - - nbdiag = 0 - diagdata = fxconv.Structure() - - nbdiag, diagdata = convert_dialogs(dialogfile, output, params, target) - - if (nbdiag==0): - structMap += fxconv.u32( 0 ) - structMap += fxconv.u32( 0 ) - else: - structMap += fxconv.u32( int(nbdiag) ) - structMap += fxconv.ptr( diagdata ) - - - - #extraction of the data contained in the layer "Background" and "Foreground" of the map - - - #import the Background layer of the map - for i in range(nbTilelayer+1): - datavalid = data["layers"][i] - if datavalid["name"]=="Background": - layer_background = i - if DEBUG: print( "Background Tile Data in layer : ", layer_background) - break - elif i==nbTilelayer: - print( "ERROR : No Background layer data !!!" ) - - layer_data = bytes() - layer = data["layers"][layer_background] - for tile in layer["data"]: - layer_data += fxconv.u16(tile-1) - structMap += fxconv.ptr(layer_data) - - - - #import the foreground layer of the map - for i in range(nbTilelayer+1): - datavalid = data["layers"][i] - if datavalid["name"]=="Foreground": - layer_foreground = i - if DEBUG: print( "Foreground Tile Data in layer : ", layer_foreground) - break - elif i==nbTilelayer: - print( "ERROR : No Foreground layer data !!!" ) - - layer_data = bytes() - layer = data["layers"][layer_foreground] - for tile in layer["data"]: - layer_data += fxconv.u16(tile-1) - structMap += fxconv.ptr(layer_data) - - - return structMap - - - -def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax): - if DEBUG: print( "WE ARE COMPUTING THE EXTRA DATA OF THE MAP : ", input ) - data = json.load(open(input, "r")) - - nblayer = ["id" in i for i in data["layers"]].count(True) - 1 - if DEBUG: print( "I found ", nblayer, " of extradata") - - #index of the various layers (may change from one map to another) - layer_extradata = 0 - - #import the foreground layer of the map - for i in range(nblayer+1): - datavalid = data["layers"][i] - if datavalid["name"]=="ExtraData": - layer_extradata = i - if DEBUG: print( "Extra Data in layer : ", layer_extradata) - break - elif i==nblayer: - print( "ERROR : No ExtraData layer data !!!" ) - return 0, fxconv.u32(0) - - #create the structure of the map - structData = fxconv.Structure() - - nbExtraData = 0 - layer = data["layers"][layer_extradata] - for i in layer["objects"]: - - #get the type of the item - tpe = i["type"] - - #we check if the type corresponds to a items of type Point in Tiled - if tpe in ( "SGN", "NPC", "INFO" ): - - nbExtraData = nbExtraData + 1 - x = i["x"] + xmin - y = i["y"] + ymin - nme = i["name"] - - - dialogID = None - needAction = None - path = 0 - path_length = 0 - xdata = None - ydata = None - face_type = "MALE" - - #we now fill all the properties of this item - for j in i["properties"]: - #property "dialog" - if j["name"]=="dialogID": dialogID = j[ "value" ] - #property "isQuestion" - elif j["name"]=="needAction": needAction = j[ "value" ] - - else: - #Extra properties for NPCs (path and face) - if tpe=="NPC": - if j["name"]=="face": - face_type = j["value"] - elif j["name"]=="hasPath": - pathID = None - path = j[ "value" ] - if path==1: - if DEBUG: print( "PNJ has path - NOW LOOKING FOR RELEVANT DATA" ) - - # we start looking for path data with first the ID of the path Object - for u in i["properties"]: - if u["name"]=="path": - pathID = u[ "value" ] - if DEBUG: print( "path ID is identified : ID= ", pathID ) - - for v in layer["objects"]: - if v[ "id" ] == pathID: - if DEBUG: print( "path data found : " ) - - xdata = bytes() - ydata = bytes() - - for w in v[ "polyline" ]: - path_length = path_length + 1 - if DEBUG: print( "X= ", w[ "x" ], " Y= ", w[ "y" ] ) - xdata += fxconv.u16( int( w[ "x" ] ) ) - ydata += fxconv.u16( int( w[ "y" ] ) ) - - else: - if DEBUG: print( "PNJ has no Path" ) - - else: - print( "UNIDENTIFIED PROPERTY : ", j["name"]) - - if DEBUG: - print( "OBJECT X= ", x, " Y= ", y, "STR= ", dialogID ) - print( " Type= ", tpe, " Name= ", nme, "Face =", face_type) - print( " Action?= ", needAction ) - - - - structData += fxconv.u32( int(x) ) - structData += fxconv.u32( int(y) ) - structData += fxconv.string( nme ) - structData += fxconv.string( tpe ) - structData += fxconv.string(face_type) - structData += fxconv.u32( int(dialogID) ) - structData += fxconv.u32( int(needAction) ) - - if path==0: - structData += fxconv.u32(0) - structData += fxconv.u32(0) - structData += fxconv.u32(0) - structData += fxconv.u32(0) - else: - o_xdata = fxconv.Structure() - o_xdata += xdata - o_ydata = fxconv.Structure() - o_ydata += ydata - - structData += fxconv.u32(path) - structData += fxconv.u32(path_length) - structData += fxconv.ptr(o_xdata) - structData += fxconv.ptr(o_ydata) - - #else we do nothing (yet) - else: - if DEBUG: print( "Skip this object" ) - - return nbExtraData, structData - - -def convert_custom_image(input, output, params, target): - scale = int(params.get("scale", 1)) - - # Upscale image before converting - im = Image.open(input) - im = im.resize((im.width * scale, im.height * scale), - resample=Image.NEAREST) - - o = fxconv.convert_image_cg(im, params) - fxconv.elf(o, output, "_" + params["name"], **target) - - - -def convert_font(input, output, params, target): - o = fxconv.convert_topti(input, params) - fxconv.elf(o, output, "_" + params["name"], **target) - - - -def convert_dialogs(input, output, params, target): - - if DEBUG: print( "WE ARE COMPUTING THE DIALOGS FROM : ", input ) - data = json.load(open(input, "r")) - - structDialogs = fxconv.Structure() - nbdialogs = 0 - - for d in data["dialogs"]: - if DEBUG: print( int(d[ "ID" ])) - # print( d[ "dialog" ] ) - if DEBUG: print( int(d[ "isQuestion" ]) ) - # print( d[ "choice" ].replace('$', chr(0)) ) - # print( d[ "conclusion1" ] ) - # print( int(d[ "next1" ] ) ) - # print( d[ "conclusion2" ] ) - # print( int(d[ "next2" ] ) ) - # print( int(d[ "nextOther" ]) ) - nbdialogs = nbdialogs + 1 - - structDialogs += fxconv.u32( int(d[ "ID" ] ) ) - structDialogs += fxconv.string( d[ "dialog" ] ) - structDialogs += fxconv.u32( int(d[ "isQuestion" ] ) ) - structDialogs += fxconv.string( d[ "choice" ].replace('$', chr(0)) ) - structDialogs += fxconv.string( d[ "conclusion1" ] ) - structDialogs += fxconv.u32( int(d[ "next1" ] ) ) - structDialogs += fxconv.string( d[ "conclusion2" ] ) - structDialogs += fxconv.u32( int(d[ "next2" ] ) ) - structDialogs += fxconv.u32( int(d[ "nextOther" ] ) ) - - return nbdialogs, structDialogs - - #fxconv.elf(structDialogs, output, "_" + params["name"], **target) +import sys +# Add the assets folder to the path, to be able to import the tiled script. +sys.path.append("../assets/") +import fxconv +from tinytiled import * + +# If the output of the converter should be verbose. +VERBOSE = 1 +# The sign types, used to find the sign icon. +SIGN_TYPES = ["SGN", "INFO"] +# The NPC faces, used to find the face id. +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 + +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": + convert_map(input, output, params, target) + return 0 + elif params["custom-type"] == "dialog": + convert_dialog(input, output, params, target) + return 0 + +def convert_map(input: str, output: str, params: dict, target): + """ + Convert a map. + """ + if VERBOSE: print(f"INFO: Converting map {input} -> {output}") + input_map = Map(input) + dialog_file = "" + background_layer = [] + foreground_layer = [] + walkable_layer = [] + map_x = 0 + map_y = 0 + width = 0 + height = 0 + outdoor_tileset = None + walkable_tileset = None + dialog_num = 0 + dialog_ids = [] + + npc_paths = {} + npcs = {} + signs = {} + + map_struct = fxconv.Structure() + + # Get the dialog file + try: + if VERBOSE: print("INFO: Getting the dialog file") + dialog_file = input_map.get_property("dialogFile") + if VERBOSE: print(f"INFO: Dialog file: {dialog_file}.") + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get the dialog file.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Get the map position + try: + if VERBOSE: print("INFO: Getting the map position") + map_x = int(input_map.get_property("mapX")) + map_y = int(input_map.get_property("mapY")) + if VERBOSE: print(f"INFO: Map position: ({map_x}, {map_y}).") + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get the map position.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Get informations about dialogs + try: + if VERBOSE: print("INFO: Getting informations about dialogs") + with open(f"{input_map.parent_dir}/{dialog_file}", "r") as file: + dialog_data = json.load(file) + dialog_num = len(dialog_data["dialogs"]) + for i in dialog_data["dialogs"]: + dialog_ids.append(i["ID"]) + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get informations about dialogs.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Get the outdoor tileset + try: + if VERBOSE: print("INFO: Getting the outdoor tileset") + outdoor_tileset = input_map.get_tileset_by_firstgid(1) + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get the outdoor tileset.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Get the walkable tileset + try: + if VERBOSE: print("INFO: Getting the walkable tileset") + walkable_tileset = input_map.get_tileset_by_firstgid(409) + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get the walkable tileset.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Get the background + try: + if VERBOSE: print("INFO: Getting the background layer") + bg_layer = input_map.get_layer_by_name("Background") + # The bg layer will be used to set the map width and height. + width = bg_layer.get_width() + height = bg_layer.get_height() + if VERBOSE: print(f"INFO: Map size: ({width}, {height}).") + # Get the layer data himself + background_layer = bg_layer.get_data_with_tileset(outdoor_tileset) + # Check if the size of the layer data is correct. + if len(background_layer) != width*height: + raise Exception("Bad layer size!") + if VERBOSE: print("INFO: Layer data has the right size.") + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get the background layer.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Get the foreground + try: + if VERBOSE: print("INFO: Getting the foreground layer") + fg_layer = input_map.get_layer_by_name("Foreground") + # Get the layer data himself + foreground_layer = fg_layer.get_data_with_tileset(outdoor_tileset) + # Check if the size of the layer data is correct. + if len(foreground_layer) != width*height: + raise Exception("Bad layer size!") + if VERBOSE: print("INFO: Layer data has the right size.") + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get the foreground layer.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Get the walkable layer + try: + if VERBOSE: print("INFO: Getting the walkable layer") + wk_layer = input_map.get_layer_by_name("Walkable") + # Get the layer data himself + walkable_layer = wk_layer.get_data_with_tileset(walkable_tileset) + # Check if the size of the layer data is correct. + if len(walkable_layer) != width*height: + raise Exception("Bad layer size!") + if VERBOSE: print("INFO: Layer data has the right size.") + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get the walkable layer.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Get the extra data + try: + if VERBOSE: print("INFO: Getting the extra data") + ed_objgroup = input_map.get_objectgroup_by_name("ExtraData") + # Get the paths the NPCs take. + for object in ed_objgroup.objects: + if object.get_data_type() == "polyline": + npc_paths[object.id] = object.get_data() + # Get the NPCs + for object in ed_objgroup.objects: + if object.get_data_type() == "point" and object.type == "NPC": + path = [0, 0] + if int(object.get_property("hasPath")): + if object.get_property("path") in npc_paths: + path = npc_paths[object.get_property("path")] + else: + raise Exception("Path required but not found!") + dialog_id = 0 + has_dialog = 0 + try: + dialog_id = int(object.get_property("dialogID")) + has_dialog = 1 + except: + pass + data = { + "position": object.get_data(), + "name": object.name, + "needAction": int(object.get_property("needAction")), + "dialogID": dialog_id, + "hasDialog": has_dialog, + "face": FACES.index(object.get_property("face")), + "path": path + } + npcs[object.id] = data + # Get the signs + for object in ed_objgroup.objects: + if object.get_data_type() == "point" and object.type in SIGN_TYPES: + data = { + "position": object.get_data(), + "name": object.name, + "needAction": int(object.get_property("needAction")), + "dialogID": int(object.get_property("dialogID")), + "icon": SIGN_TYPES.index(object.type) + } + signs[object.id] = data + except Exception as e: + # Show a simple error message on failure. + sys.stderr.write(f"ERROR: Failed to get the extra data.\n" + + f" Error message: {e}\n") + sys.exit(1) + # Generate the structs + # Map struct + map_struct += fxconv.u32(map_x) + map_struct += fxconv.u32(map_y) + map_struct += fxconv.u32(width) + map_struct += fxconv.u32(height) + map_struct += fxconv.u32(3) + map_struct += fxconv.u32(outdoor_tileset.columns) + tileset_name = os.path.splitext(os.path.basename(outdoor_tileset.source))[0] + map_struct += fxconv.ref(f"img_{tileset_name}") + + # Store the walkable layer + walkable_data = bytes() + for i in walkable_layer: + if i < 0: i = 0 + walkable_data += fxconv.u8(i) + map_struct += fxconv.ptr(walkable_data) + + # Load NPCs + map_struct += fxconv.u32(len(npcs)) + npc_struct = fxconv.Structure() + for i in npcs.values(): + # Convert currentpos to a fixed point value. + npc_struct += fxconv.u32((i["position"][0]+i["path"][0])< 2) + npc_struct += fxconv.u32(len(i["path"])//2) + npc_struct += fxconv.u32(0) + + xpath = bytes() + ypath = bytes() + x = True + for n in i["path"]: + if x: xpath += fxconv.u16(n) + else: ypath += fxconv.u16(n) + x = not x + + npc_struct += fxconv.ptr(xpath) + npc_struct += fxconv.ptr(ypath) + + npc_struct += fxconv.u32(0) # TODO: Type + npc_struct += fxconv.u8(0) # TODO: Group + npc_struct += fxconv.u8(0) # TODO: Hostile to + npc_struct += fxconv.u16(0) # TODO: Padding (what is it ?) + map_struct += fxconv.ptr(npc_struct) + # Load signs + map_struct += fxconv.u32(len(signs)) + sign_struct = fxconv.Structure() + for i in signs.values(): + # Create a sign struct for each sign. + sign_struct += fxconv.u32(i["position"][0]) + sign_struct += fxconv.u32(i["position"][1]) + sign_struct += fxconv.u32(i["icon"]) + sign_struct += fxconv.string(i["name"]) + sign_struct += fxconv.u32(i["dialogID"]) + sign_struct += fxconv.u32(i["needAction"]) + map_struct += fxconv.ptr(sign_struct) + # Load portals + map_struct += fxconv.u32(0) # TODO: Portal support in-game + map_struct += fxconv.ptr(bytes()) + map_struct += fxconv.u32(dialog_num) + + # Get the name of the dialog file and create a reference to it: it is built + # separately. + dialog_name = os.path.splitext(os.path.basename(dialog_file))[0] + map_struct += fxconv.ref(f"_{dialog_name}") + + # Store the background layer + background_data = bytes() + for i in background_layer: + background_data += fxconv.u16(i) + map_struct += fxconv.ptr(background_data) + + # Store the foreground layer + foreground_data = bytes() + for i in foreground_layer: + foreground_data += fxconv.u16(i) + map_struct += fxconv.ptr(foreground_data) + + # Create the fxconv object + name = os.path.splitext(os.path.basename(input))[0] + fxconv.elf(map_struct, output, f"_{name}", **target) + +def convert_dialog(input: str, output: str, params: dict, target): + """ + Convert a JSON dialog file. + """ + if VERBOSE: print(f"INFO: Converting dialog file {input} -> {output}") + + # Load the JSON dialog file. + dialog_data = None + try: + with open(input, "r") as file: + dialog_data = json.load(file) + except Exception as e: + sys.stderr.write(f"ERROR: Failed parse json.\n" + + f" Error message: {e}\n") + sys.exit(1) + + # Create the dialog struct + dialog_struct = fxconv.Structure() + try: + for i in dialog_data["dialogs"]: + # Create a dialog structure for each dialog. + dialog_id = i["ID"] + dialog_struct += fxconv.u32(dialog_id) + dialog_struct += fxconv.string(i["dialog"]) + dialog_struct += fxconv.u32(i["isQuestion"]) + dialog_struct += fxconv.string(i["choice"].replace('$', '\0')) + dialog_struct += fxconv.string(i["conclusion1"]) + dialog_struct += fxconv.u32(i["next1"]) + dialog_struct += fxconv.string(i["conclusion2"]) + dialog_struct += fxconv.u32(i["next2"]) + dialog_struct += fxconv.u32(i["nextOther"]) + # Save this struct + name = os.path.splitext(os.path.basename(input))[0] + fxconv.elf(dialog_struct, output, f"__{name}", **target) + except Exception as e: + # Show an error message if the conversion fails. + sys.stderr.write(f"ERROR: Failed convert dialogs.\n" + + f" Error message: {e}\n") + sys.exit(1) diff --git a/assets/fxconv-metadata.txt b/assets/fxconv-metadata.txt index 822cad1..423d18e 100644 --- a/assets/fxconv-metadata.txt +++ b/assets/fxconv-metadata.txt @@ -1,7 +1,39 @@ -WorldRPG.world: - custom-type: world - name: worldRPG +level0.tmx: + custom-type: tmx + name: level0 -#DialogsRPG.json: -# custom-type: dialogs -# name: dialogRPG +level1.tmx: + custom-type: tmx + name: level1 + +level2.tmx: + custom-type: tmx + name: level2 + +level3.tmx: + custom-type: tmx + name: level3 + +level4.tmx: + custom-type: tmx + name: level4 + +level0_dialogs.json: + custom-type: dialog + name: level0_dialogs + +level1_dialogs.json: + custom-type: dialog + name: level1_dialogs + +level2_dialogs.json: + custom-type: dialog + name: level2_dialogs + +level3_dialogs.json: + custom-type: dialog + name: level3_dialogs + +level4_dialogs.json: + custom-type: dialog + name: level4_dialogs diff --git a/assets/interior1-0.tmx b/assets/interior1-0.tmx new file mode 100644 index 0000000..3456a8b --- /dev/null +++ b/assets/interior1-0.tmx @@ -0,0 +1,52 @@ + + + + + + +86,90,91,89,90,91,89,90,91,89,90,92, +110,114,115,113,114,115,113,114,115,113,114,116, +86,93,94,1,1,1,1,1,9,10,1,92, +110,117,118,1,1,1,1,1,33,34,1,116, +86,1,1,1,1,1,1,1,1,1,1,92, +110,1,1,1,1,1,1,1,1,1,1,116, +110,1,1,1,1,133,2,1,1,1,1,92, +110,1,1,1,1,2,2,1,1,1,1,116 + + + + +0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0 + + + + +410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,0,0,0,0,0,410,0,0,410, +410,410,410,0,0,0,0,0,410,0,0,410, +410,0,0,0,0,0,0,0,0,0,0,410, +410,0,0,0,0,0,0,0,0,0,0,410, +410,0,0,0,0,0,0,0,0,0,0,410, +410,0,0,0,0,0,0,0,0,0,0,410 + + + + + + + + + + + + + + diff --git a/assets/level0.tmx b/assets/level0.tmx index ddf75ad..f61d568 100644 --- a/assets/level0.tmx +++ b/assets/level0.tmx @@ -1,32 +1,34 @@ - + - + + + 2,297,298,299,300,2,386,297,298,299,300,2,2,2,2,2,2,337,338,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,297,298,299,2,2,2,345,346,347,348,2,337,338, -253,205,229,205,229,280,179,180,179,156,156,156,158,157,179,180,253,361,362,2,2,2,2,2,2,2,2,297,298,299,300,2,2,2,2,25,358,359,117,118,28,369,370,371,372,2,361,362, -301,2,2,2,2,2,385,2,2,2,2,2,2,2,2,2,301,2,386,2,2,2,2,2,2,2,2,2,2,2,2,297,298,299,300,382,9,10,134,135,360,393,394,395,396,337,338,2, -325,149,150,151,152,2,2,327,374,375,327,2,2,185,374,375,325,387,2,297,298,299,300,2,2,2,2,2,2,2,2,2,2,2,2,406,33,34,2,219,384,2,2,2,2,361,362,2, -257,2,2,385,2,2,385,2,265,266,2,2,208,209,352,353,257,2,2,2,2,2,2,297,298,299,300,2,2,2,2,25,358,359,358,97,407,408,407,408,100,358,358,359,28,131,2,2, -281,176,2,2,2,2,176,385,289,290,2,2,232,233,376,377,281,2,326,2,154,153,190,2,2,2,2,2,2,2,2,382,2,2,2,121,59,60,60,61,124,2,2,2,360,132,2,2, -2,2,2,2,2,385,2,2,265,266,2,385,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,297,298,299,300,406,2,2,2,145,83,84,84,85,148,2,2,2,384,132,2,2, -2,2,2,2,326,2,385,2,265,266,2,2,2,2,2,2,2,2,2,2,2,2,190,2,2,2,2,2,2,385,2,406,404,405,2,169,107,108,108,109,172,2,402,403,384,132,2,2, -2,2,2,2,2,2,2,2,289,290,2,258,259,260,238,239,260,260,261,262,262,263,264,2,2,2,2,2,2,2,385,382,134,135,2,2,2,2,2,2,2,2,134,135,360,132,297,298, -2,2,2,2,2,2,2,2,265,266,2,282,283,284,285,285,285,285,285,285,286,287,288,297,298,299,300,2,117,118,2,382,373,2,217,2,190,373,373,190,2,219,2,373,384,132,2,2, -297,298,299,300,2,2,2,2,290,2,2,306,307,308,309,308,309,308,309,310,310,311,312,131,2,339,340,2,134,135,2,97,407,408,408,408,408,19,18,407,408,408,407,408,100,132,2,2, +253,205,229,205,229,280,179,180,179,156,156,156,158,157,179,180,253,361,362,2,2,2,2,2,2,2,2,297,298,299,300,2,2,2,2,25,26,27,117,118,28,369,370,371,372,2,361,362, +301,2,2,2,2,2,385,2,2,2,2,2,2,2,2,2,301,2,386,2,2,2,2,2,2,2,2,2,2,2,2,297,298,299,300,49,9,10,134,135,52,393,394,395,396,337,338,2, +325,149,150,151,152,2,2,327,374,375,327,2,2,185,374,375,325,387,2,297,298,299,300,2,2,2,2,2,2,2,2,2,2,2,2,73,33,34,74,219,76,2,2,2,2,361,362,2, +257,2,2,385,2,2,385,2,265,266,2,2,208,209,352,353,257,2,2,2,2,2,2,297,298,299,300,2,2,2,2,25,26,27,27,97,98,99,98,99,100,26,26,27,28,131,2,2, +281,176,2,2,2,2,176,385,289,290,2,2,232,233,376,377,281,2,326,2,154,153,190,2,2,2,2,2,2,2,2,49,2,2,2,121,59,60,60,61,124,2,2,2,52,132,2,2, +2,2,2,2,2,385,2,2,265,266,2,385,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,297,298,299,300,73,2,2,2,145,83,84,84,85,148,2,2,2,76,132,2,2, +2,2,2,2,326,2,385,2,265,266,2,2,2,2,2,2,2,2,2,2,2,2,190,2,2,2,2,2,2,385,2,49,404,405,2,169,107,108,108,109,172,2,402,403,76,132,2,2, +2,2,2,2,2,2,2,2,289,290,2,258,259,260,238,239,260,260,261,262,262,263,264,2,2,2,2,2,2,2,385,49,134,135,2,2,2,2,2,2,2,2,134,135,52,132,297,298, +2,2,2,2,2,2,2,2,265,266,2,282,283,284,285,285,285,285,285,285,286,287,288,297,298,299,300,2,117,118,2,73,373,2,217,2,190,373,373,190,2,219,2,373,76,132,2,2, +297,298,299,300,2,2,2,2,290,2,2,306,307,308,309,308,309,308,309,310,310,311,312,131,2,339,340,2,134,135,2,97,98,99,99,98,99,2,2,98,98,99,98,99,100,132,2,2, 2,2,2,386,2,2,2,2,2,2,2,330,331,332,333,332,333,332,333,334,334,335,336,132,2,363,364,2,2,2,2,121,122,122,122,123,124,81,82,121,122,123,122,123,124,132,2,2, 2,2,2,386,297,298,299,300,2,290,2,162,163,164,165,162,163,164,165,162,163,164,165,132,2,2,2,2,2,2,2,145,146,146,146,147,148,57,58,145,146,147,146,147,148,132,2,2, -2,2,2,2,2,2,2,2,2,2,2,86,87,88,89,186,187,188,189,86,87,88,89,132,385,2,2,2,2,2,2,169,170,170,170,171,172,81,82,169,170,171,14,15,42,358,359,359, -2,2,2,2,270,271,271,271,272,2,2,110,111,112,113,210,211,212,213,110,111,112,113,133,2,2,2,2,2,2,2,2,2,2,2,2,2,290,265,265,266,266,38,39,19,2,2,2, -298,299,300,2,294,1,1,1,296,2,2,2,2,2,2,234,290,265,237,2,2,2,339,340,385,2,2,2,2,2,2,327,2,2,2,160,161,386,266,289,290,265,62,63,406,2,2,2, -2,2,2,2,294,1,1,1,296,2,2,160,161,265,266,266,265,266,290,2,2,2,363,364,2,297,298,299,300,2,2,2,2,2,2,2,2,266,290,2,2,2,2,2,97,407,408,408, +2,2,2,2,2,2,2,2,2,2,2,86,87,88,89,186,187,188,189,86,87,88,89,132,385,2,2,2,2,2,2,169,170,170,170,171,172,81,82,169,170,171,14,15,27,26,27,27, +2,2,2,2,270,271,271,271,272,2,2,110,111,112,113,210,211,212,213,110,111,112,113,133,2,2,2,2,2,2,2,2,2,2,2,2,2,290,265,265,266,266,38,39,2,2,2,51, +298,299,300,2,294,1,1,1,296,2,2,2,2,2,2,234,290,265,237,2,2,2,339,340,385,2,2,2,2,2,2,327,2,2,2,160,161,386,266,289,290,265,62,63,73,74,75,75, +2,2,2,2,294,1,1,1,296,2,2,160,161,265,266,266,265,266,290,2,2,2,363,364,2,297,298,299,300,2,2,2,2,2,2,2,2,266,290,2,2,2,2,2,97,98,99,99, 2,2,2,2,318,319,319,319,320,2,386,266,266,289,290,265,266,241,265,266,266,265,266,241,385,2,2,2,241,265,266,266,265,386,265,266,266,265,266,2,2,2,2,2,121,122,123,123, 2,2,2,2,2,2,2,2,2,385,289,290,386,265,265,2,2,241,289,290,265,266,290,266,265,266,266,386,266,289,290,265,266,290,289,385,265,266,290,2,2,2,2,2,145,146,147,147, 2,2,2,2,2,2,2,2,2,2,2,2,2,265,386,2,2,2,2,2,2,2,241,241,289,290,265,266,290,241,2,2,2,2,2,2,21,22,23,24,2,2,254,255,169,170,171,171, @@ -68,28 +70,28 @@ 0,0,410,410,0,0,0,0,410,410,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,410,410,410,410,0,410,410, 410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,410,410,410,410,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,410,410, -410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,410,0,0,0,0,410,410,410,410,410,410,410,0, +410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,410,0,0,0,0,410,410,410,410,410,410,410,0, 410,410,410,410,410,0,0,410,410,410,410,0,0,0,410,410,410,410,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,0,0,410,410,0, -410,0,0,412,0,0,0,0,0,0,0,0,410,411,411,411,410,0,0,0,0,0,0,0,410,410,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0, +410,0,0,0,0,0,0,0,0,0,0,0,410,411,411,411,410,0,0,0,0,0,0,0,410,410,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0, 410,0,0,0,0,0,0,0,0,0,0,0,411,411,411,411,410,0,410,0,410,410,410,0,0,0,0,0,0,0,0,410,0,0,0,410,410,410,410,410,410,0,0,0,410,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,410,0,0,0,410,410,410,410,410,410,0,0,0,410,0,0,0, -0,0,0,0,410,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,412,0,410,410,410,0,410,410,0,0,410,410,0,410,410,410,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,412,410,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,410, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,410,0,0,0,410,410,410,410,410,410,0,0,0,410,0,0,0, +0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,410,410,0,410,410,0,0,410,410,0,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,410, 0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,410,410,0,0,410,410,0,410,0,0,0,0,410,0,0,410,0,0,0,0,410,0,0,0, 0,410,410,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,0,0,0,0,0,410,410,410,410,410,410,0,0,410,410,410,410,410,410,0,0,0, -0,0,0,412,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,410,0,0,0,0,410,410,410,410,410,410,0,0,410,410,410,410,410,410,0,0,0, -0,0,0,412,0,410,410,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0,410,410,410,410,410,410,0,0,410,410,410,410,410,410,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,412,0,0,0,0,0,0,410,410,410,410,410,410,0,0,410,410,410,410,0,0,410,410,410, +0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,410,0,0,0,0,410,410,410,410,410,410,0,0,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,410,410,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0,410,410,410,410,410,410,0,0,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0,410,410,410,410,410,410,0,0,410,410,410,410,0,0,410,410,410, 0,0,0,0,412,412,412,412,412,0,0,410,410,410,410,410,0,0,410,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -410,410,0,0,412,412,412,412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,412,0,0,0,0,0,0,410,0,0,0,410,410,0,0,0,0,0,0,410,410,0,0,0, +410,410,0,0,412,412,412,412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,410,0,0,0,410,410,0,0,0,0,0,0,410,0,0,0,0, 0,0,0,0,412,412,412,412,412,0,0,410,410,0,0,0,0,0,0,0,0,0,410,410,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410, 0,0,0,0,412,412,412,412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,410,410,410,410,410,410, 410,410,0,0,0,0,0,410,410,410,410,410,0,0,0,0,410,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,0,0,0,0,0, -0,0,412,0,0,0,0,410,410,410,410,410,0,0,0,0,410,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,410,410,410,410,410,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,410,410,410,410,410,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,410,410,0,410,410,410,410,410,0,0,0,0,410,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,410,410,0,410,410,410,410,410,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0 @@ -171,5 +173,14 @@ + + + + + + + + + diff --git a/assets/DialogsLvl0.json b/assets/level0_dialogs.json similarity index 100% rename from assets/DialogsLvl0.json rename to assets/level0_dialogs.json diff --git a/assets/level1.tmx b/assets/level1.tmx index 12cbec9..7412c7c 100644 --- a/assets/level1.tmx +++ b/assets/level1.tmx @@ -1,7 +1,9 @@ - + + + @@ -20,10 +22,10 @@ 2,2,269,1,1,1,1,1,1,319,319,269,1,1,1,316,271,316,271,317,1,1,1,1,319,319,319,268,268,319,319,319,268,319,320,2,2,318,319,320,268,269,1,1,1,1,1,1, 2,2,2,269,1,1,1,1,320,2,2,2,269,1,1,1,1,1,1,1,1,1,267,2,2,2,2,2,2,2,2,2,2,2,2,2,2,219,2,2,2,318,319,320,269,1,1,1, 2,2,2,2,319,268,319,320,2,2,2,2,318,319,269,1,1,1,1,1,1,267,2,2,2,2,313,265,242,266,241,219,314,313,242,241,2,2,219,2,2,2,2,2,2,269,1,1, -359,358,359,358,359,28,2,2,2,2,2,2,2,2,318,319,319,268,268,319,319,320,2,2,2,219,2,2,2,2,266,241,289,290,266,265,2,2,2,297,298,299,300,2,2,318,319,320, -2,2,2,18,407,100,132,2,2,2,2,2,2,2,2,2,2,2,2,314,265,2,2,2,2,313,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, -2,2,2,42,16,17,133,2,2,2,2,2,2,2,2,2,2,2,241,219,290,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, -408,407,407,408,40,41,290,314,297,298,299,300,2,2,2,2,2,219,219,289,2,297,298,299,300,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,297,298,299,300,2, +27,26,27,26,27,28,2,2,2,2,2,2,2,2,318,319,319,268,268,319,319,320,2,2,2,219,2,2,2,2,266,241,289,290,266,265,2,2,2,297,298,299,300,2,2,318,319,320, +2,50,51,51,99,100,132,2,2,2,2,2,2,2,2,2,2,2,2,314,265,2,2,2,2,313,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,74,75,76,16,17,133,2,2,2,2,2,2,2,2,2,2,2,241,219,290,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +98,98,99,100,40,41,290,314,297,298,299,300,2,2,2,2,2,219,219,289,2,297,298,299,300,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,297,298,299,300,2, 121,122,123,124,64,65,265,289,313,289,241,265,219,2,2,2,2,290,314,2,2,2,2,2,2,2,297,298,299,300,2,2,2,2,402,403,2,374,375,2,404,405,2,2,2,2,2,2, 145,146,147,148,132,2,2,2,2,2,2,314,314,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 169,170,171,172,133,2,2,2,2,2,2,2,2,297,298,299,300,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,385,2,2,2,2,2,2,2,2,2,2,2,2, @@ -79,13 +81,13 @@ 410,410,410,410,410,410,0,0,0,0,0,0,0,0,412,412,412,412,412,412,412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,412,412,412, 0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -410,410,409,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0, +0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0, 410,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,410,410,0,410,410,0,410,410,0,0,0,0,0,0, 410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -410,410,410,410,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,0,0,0,410,410,0, +410,410,410,410,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,0,0,0,410,410,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 @@ -107,7 +109,7 @@ - + diff --git a/assets/DialogsLvl1.json b/assets/level1_dialogs.json similarity index 100% rename from assets/DialogsLvl1.json rename to assets/level1_dialogs.json diff --git a/assets/level2.tmx b/assets/level2.tmx index bf66b1c..4e5e341 100644 --- a/assets/level2.tmx +++ b/assets/level2.tmx @@ -1,7 +1,9 @@ - + + + @@ -11,13 +13,13 @@ 2,2,2,2,2,386,2,2,2,2,2,277,2,386,266,2,349,385,385,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,297,298,299,300,2,2,2, 298,299,300,2,2,2,2,385,385,2,2,301,2,266,290,2,349,2,385,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,386,2,2,256,2,265,266,2,257,2,2,2,2,2,2,2,2,2,2,2,297,298,299,300,297,298,299,258,259,262,330,333,333,336,262,263,264,2,2,2, -2,2,2,2,2,2,2,2,386,386,2,281,2,266,290,2,280,2,2,2,2,2,2,2,2,2,386,2,2,2,2,2,2,2,2,283,283,5,91,87,88,92,5,312,288,2,385,2, -2,2,2,2,2,2,2,2,2,2,2,2,2,290,266,2,2,2,385,2,297,298,299,300,2,2,2,2,2,2,2,9,10,2,2,283,283,5,115,111,112,113,5,312,312,131,2,2, -2,2,2,2,2,2,2,2,2,2,2,2,2,386,266,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,33,34,385,2,283,283,5,114,114,115,114,5,312,312,132,385,2, -2,386,2,2,2,2,2,2,2,2,2,2,2,313,290,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,282,283,5,5,5,5,5,5,312,288,132,2,2, -2,2,2,297,298,299,300,2,345,346,347,348,2,265,266,2,2,374,375,151,152,149,150,151,152,149,150,374,375,149,150,151,152,2,2,282,283,5,5,5,5,5,5,287,288,132,2,2, -2,2,2,2,2,2,2,386,369,370,371,372,2,266,290,208,209,352,353,2,2,385,2,2,2,2,385,2,2,2,2,2,2,2,2,282,283,5,5,5,5,5,5,312,312,132,2,2, -2,2,2,2,2,2,386,2,393,394,395,396,2,290,266,232,233,376,377,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,282,283,5,5,5,5,5,5,312,288,132,2,2, +2,2,2,2,2,2,2,2,386,386,2,281,2,266,290,2,280,2,2,2,2,2,2,2,2,2,386,2,2,2,2,2,2,2,2,283,283,3,91,87,88,92,3,312,288,2,385,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,290,266,2,2,2,385,2,297,298,299,300,2,2,2,2,2,2,2,9,10,2,2,283,283,3,115,111,112,113,3,312,312,131,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,386,266,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,33,34,385,2,283,283,3,114,114,115,114,3,312,312,132,385,2, +2,386,2,2,2,2,2,2,2,2,2,2,2,313,290,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,282,283,3,3,3,3,3,3,312,288,132,2,2, +2,2,2,297,298,299,300,2,345,346,347,348,2,265,266,2,2,374,375,151,152,149,150,151,152,149,150,374,375,149,150,151,152,2,2,282,283,3,3,3,3,3,3,287,288,132,2,2, +2,2,2,2,2,2,2,386,369,370,371,372,2,266,290,208,209,352,353,2,2,385,2,2,2,2,385,2,2,2,2,2,2,2,2,282,283,3,3,3,3,3,3,312,312,132,2,2, +2,2,2,2,2,2,386,2,393,394,395,396,2,290,266,232,233,376,377,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,282,283,3,3,3,3,3,3,312,288,132,2,2, 2,2,2,2,2,385,2,2,2,2,2,2,2,386,313,2,2,149,149,374,375,149,150,151,152,374,375,151,152,149,150,151,152,2,2,282,330,308,308,308,308,308,308,311,312,132,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,266,290,2,2,2,2,2,2,2,2,2,2,385,2,2,385,2,2,2,2,2,2,330,331,331,331,331,331,331,331,331,336,132,2,2, 2,297,298,299,300,2,2,2,2,2,2,2,2,265,266,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,90,91,92,162,163,164,165,90,91,92,132,2,2, @@ -63,30 +65,30 @@ -0,0,0,0,412,0,0,0,0,0,0,410,0,0,0,0,410,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410, -0,0,0,0,0,412,0,0,0,0,0,410,0,0,0,0,410,412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0, -410,410,0,0,0,0,0,412,412,0,0,410,0,0,0,0,410,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,412,0,0,410,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0, -0,0,0,0,0,0,0,0,412,412,0,410,0,0,0,0,410,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,412,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,412,0, -0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410, +0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0, +410,410,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, 0,0,0,0,410,410,0,0,410,410,410,410,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, -0,0,0,0,0,0,0,412,410,410,410,410,0,0,0,410,411,411,411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, -0,0,0,0,0,0,412,0,410,410,410,410,0,0,0,411,411,411,411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, -0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,410,411,411,411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,411,411,411,411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, 0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,410,410,410,410,410,410,410,410,410,0,0,0, -0,412,412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,410,410,410,410,0,0,0, -0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0, -0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,412,0,0,0,0,0,0,0,0,0,0,0,410,410,412,0,0,0,0,0,0,412,412,0, -0,412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,410,410,410,410,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,410,410,410,410,0,0,0,412,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,412,412,412,0,0,0,412,0,0,0,0,0,412,0,0,412,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,410,410,410,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/assets/DialogsLvl2.json b/assets/level2_dialogs.json similarity index 100% rename from assets/DialogsLvl2.json rename to assets/level2_dialogs.json diff --git a/assets/level3.tmx b/assets/level3.tmx index aff26aa..2a6a92e 100644 --- a/assets/level3.tmx +++ b/assets/level3.tmx @@ -1,7 +1,9 @@ - + + + @@ -64,29 +66,29 @@ 0,0,0,0,410,410,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,412,0,0,410,410,0,0,0,0,410,0,0,412,0,0,412,0,410,410,410,410,410,410,410,410,410,410,0,410,410, -410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,410,410, -410,412,412,412,0,412,412,412,412,0,412,412,412,412,410,0,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0, -410,412,412,412,0,412,412,412,412,0,412,412,412,412,410,0,410,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0, -410,412,412,412,0,412,412,412,412,0,412,412,412,412,410,0,410,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,0,410,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,0,410,410, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,410,410, +410,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0, +410,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,410,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0, +410,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,410,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,0, 410,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,410,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,410,0,0,410,410,410,410,0,0,410,0,0,0, 410,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,410,0,0,0,0,0,0,0,0,0,410,0,0,0,410,410,0,0,0,410,410,410,410,0,0,410,410,410,410,0,0,0, -410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,410,410,410,410,0,0,0,410,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,410,410,410,410,410,410,410,410,0,410,410,410,410,0,410,410,410,410,0,0,410,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,412,0,0,410, +410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,410,410,410,410,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,410,410,410,410,410,410,410,410,0,410,410,410,410,0,410,410,410,410,0,0,410,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,0,0,410, 0,0,410,0,0,0,0,0,0,410,0,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,410,0,0,0,0,0,0,410,0,410,410,410,410,0,0,0,0,0,0,412,410,410,0,412,0,0,0,0,0,0,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0, +0,0,410,0,0,0,0,0,0,410,0,410,410,410,410,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,0, 0,0,410,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0, 0,0,410,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0, 0,0,410,0,0,410,410,410,410,410,0,0,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,410,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0, 0,0,410,410,410,410,0,0,410,410,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,0,0,0,0,410,0,0,0,0,410,410,0,0, -0,0,0,0,0,0,0,0,0,0,0,412,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,410,410,410,410,410,0,0,0,0,0,0,0,0, -0,0,0,412,0,0,0,0,410,410,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,410,410,410,0,0,410,410,0,0,0,0,0,0,412,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,0,0,410,410,410,410,410,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,410,410,410,410,0,0,410,410,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,410,410,410,410,410,0,0,0,0,0,0,0,0,0,0,0,410,410,0,410,410,410,410,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,412,0,0,410,410,410,410,0,0, -0,0,0,0,0,0,0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,410,410,0,0,0,0,0,410,410,410,410,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,410,410,410,410,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,410,410,0,0,0,0,0,410,410,410,410,0,0, 0,0,410,410,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,0,410,410,410,410,0,410,410,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,412,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,0,410,410,410,410,0,0,0,0,0,0,0,410,0,0,0,412,0,0 +0,0,0,0,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,0,0,0,0,0,410,0,0,0,0,0,0 diff --git a/assets/DialogsLvl3.json b/assets/level3_dialogs.json similarity index 100% rename from assets/DialogsLvl3.json rename to assets/level3_dialogs.json diff --git a/assets/level4.tmx b/assets/level4.tmx index e9fdb07..3b84d5a 100644 --- a/assets/level4.tmx +++ b/assets/level4.tmx @@ -1,31 +1,33 @@ - + + + -385,386,2,2,385,386,385,2,2,2,2,2,2,2,2,2,385,386,385,265,266,385,386,385,386,385,121,122,123,122,123,122,124,2,2,2,2,2,2,2,2,386,2,2,2,2,2,2, -385,386,385,386,385,386,385,386,2,2,218,219,385,386,385,386,385,386,385,289,241,385,386,385,386,385,145,146,147,147,146,147,148,385,386,385,385,386,2,2,2,217,218,219,385,2,2,386, -385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,313,314,25,358,359,358,359,145,146,146,146,147,146,148,358,359,28,385,386,385,386,385,217,218,219,385,386,385,386, -385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,387,265,266,382,2,2,176,2,169,170,170,170,171,170,172,2,176,360,385,386,385,386,385,217,218,219,363,364,385,386, -385,386,385,386,176,386,385,386,385,386,385,386,385,386,385,386,385,386,385,289,290,97,98,19,2,2,121,122,59,60,61,123,124,2,2,384,385,149,150,151,152,153,154,386,176,177,178,386, -385,385,386,218,385,386,386,219,218,219,385,176,385,386,217,218,219,386,385,313,314,121,122,406,2,2,145,146,83,84,85,147,148,2,2,360,385,386,385,386,385,386,385,386,385,386,385,386, -385,386,25,26,26,26,26,238,239,28,385,386,385,386,217,218,219,386,385,265,241,14,15,43,254,255,169,170,107,108,109,171,172,254,255,360,385,387,149,150,151,152,153,154,385,217,218,219, -385,386,73,74,74,74,74,74,75,76,385,386,385,386,25,26,27,28,385,289,290,38,39,19,2,2,2,2,2,2,2,176,2,2,177,384,385,386,385,386,385,386,385,386,385,217,218,219, -385,386,97,98,98,98,98,98,99,100,385,386,385,386,73,74,75,76,385,313,314,62,63,97,407,407,408,407,407,408,407,407,408,98,99,100,385,149,150,151,152,153,154,218,219,386,385,386, +385,386,6,6,385,386,385,6,6,6,6,6,6,6,6,6,385,386,385,265,266,385,386,385,386,385,121,122,123,122,123,122,124,6,6,6,6,6,6,6,6,386,6,6,6,6,6,6, +385,386,385,386,385,386,385,386,6,6,218,219,385,386,385,386,385,386,385,289,241,385,386,385,386,385,145,146,147,147,146,147,148,385,386,385,385,386,6,6,6,217,218,219,385,6,6,386, +385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,313,314,25,26,27,26,27,145,146,146,146,147,146,148,26,27,28,385,386,385,386,385,217,218,219,385,386,385,386, +385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,387,265,266,49,50,51,176,2,169,170,170,170,171,170,172,2,176,52,385,386,385,386,385,217,218,219,363,364,385,386, +385,386,385,386,176,386,385,386,385,386,385,386,385,386,385,386,385,386,385,289,290,97,98,19,50,50,121,122,59,60,61,123,124,50,50,76,385,149,150,151,152,153,154,386,176,177,178,386, +385,385,386,218,385,386,386,219,218,219,385,176,385,386,217,218,219,386,385,313,314,121,122,73,50,50,145,146,83,84,85,147,148,50,50,52,385,386,385,386,385,386,385,386,385,386,385,386, +385,386,25,26,26,26,26,26,27,28,385,386,385,386,217,218,219,386,385,265,241,14,15,49,50,177,169,170,107,108,109,171,172,50,51,52,385,387,149,150,151,152,153,154,385,217,218,219, +385,386,73,74,74,74,74,74,75,76,385,386,385,386,25,26,27,28,385,289,290,38,39,73,74,75,50,2,2,2,2,176,2,74,177,76,385,386,385,386,385,386,385,386,385,217,218,219, +385,386,97,98,98,98,98,98,99,100,385,386,385,386,73,74,75,76,385,313,314,62,63,97,98,99,98,99,98,99,98,99,98,98,99,100,385,149,150,151,152,153,154,218,219,386,385,386, 385,386,162,163,163,163,163,163,164,165,385,386,385,386,97,98,99,100,385,265,266,2,2,197,198,199,200,197,198,199,200,197,198,199,200,197,385,386,385,386,385,386,217,361,362,386,385,386, -25,26,86,87,88,89,186,187,188,189,359,358,359,26,87,88,187,188,28,241,290,160,161,221,222,223,224,221,222,223,224,221,222,223,224,221,385,386,385,386,385,386,385,386,385,386,385,386, -49,50,110,111,112,113,210,211,212,213,177,2,11,12,111,112,211,212,52,313,314,2,2,245,246,247,248,245,246,247,248,245,246,247,248,245,385,386,385,386,385,386,385,386,385,386,385,386, -73,74,75,74,75,176,234,235,236,237,2,2,35,36,75,74,74,75,76,265,266,265,266,265,266,265,266,241,266,313,314,265,266,265,266,265,241,265,266,313,314,265,266,265,266,265,266,265, -97,98,99,98,99,407,408,407,408,407,408,408,407,98,99,98,98,99,100,289,290,289,313,241,290,289,290,289,290,289,290,289,313,241,290,289,290,289,290,289,290,289,290,313,314,313,290,289, +25,26,86,87,88,89,186,187,188,189,27,26,27,26,87,88,187,188,28,241,290,160,161,221,222,223,224,221,222,223,224,221,222,223,224,221,385,386,385,386,385,386,385,386,385,386,385,386, +49,50,110,111,112,113,210,211,212,213,177,50,11,12,111,112,211,212,52,313,314,2,2,245,246,247,248,245,246,247,248,245,246,247,248,245,385,386,385,386,385,386,385,386,385,386,385,386, +73,74,75,74,75,176,234,235,236,237,75,74,35,36,75,74,74,75,76,265,266,265,266,265,266,265,266,241,266,313,314,265,266,265,266,265,241,265,266,313,314,265,266,265,266,265,266,265, +97,98,99,98,99,98,99,98,99,98,99,98,99,98,99,98,98,99,100,289,290,289,313,241,290,289,290,289,290,289,290,289,313,241,290,289,290,289,290,289,290,289,290,313,314,313,290,289, 121,122,14,15,16,17,14,15,16,17,14,15,16,17,122,59,60,61,124,265,266,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385, 145,146,38,39,40,41,38,39,40,41,38,39,40,41,146,83,84,85,148,289,290,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385, 169,170,62,63,64,65,62,63,64,65,62,63,64,65,170,107,108,109,172,265,266,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385, 385,386,187,188,87,88,187,188,87,88,187,188,87,88,265,266,266,289,290,241,290,385,386,385,386,385,386,385,386,385,386,385,386,304,305,385,386,385,386,385,386,385,386,385,386,385,386,385, -385,386,211,212,111,112,211,212,111,112,211,212,111,112,289,290,241,313,314,313,314,21,22,23,24,217,386,385,217,218,219,217,386,328,329,385,386,176,386,217,218,219,386,385,386,385,386,385, +385,386,211,212,111,112,211,212,111,112,211,212,111,112,289,290,241,313,314,313,314,176,386,385,386,217,386,385,217,218,219,217,386,328,329,385,386,176,386,217,218,219,386,385,386,385,386,385, 385,386,289,241,265,266,289,290,241,266,289,290,265,266,241,290,385,386,385,385,386,45,46,47,48,217,386,385,217,218,219,217,386,385,386,385,386,385,386,217,218,219,386,385,386,385,386,385, 385,386,313,314,289,290,241,314,289,290,313,241,289,290,313,314,385,386,385,385,386,69,70,71,72,217,386,385,217,218,219,217,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385, 385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,386,385,385,386,385,386,385,386,385,304,305,386,176,386,385,386,385,386,385,386,385,386,385,386,385,386,385,217,304,305,385, @@ -40,9 +42,9 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,339,340,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125,126,127,128,129,130,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,206,207,0,0,0,0,0,0,0,206,207,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,214,215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,231,0,0,0,0,0,0,0,230,231,0,0,0,125,126,127,128,129,130,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125,126,127,128,129,130,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,231,0,0,0,0,0,0,0,230,231,0,0,0,125,126,127,128,129,130,0,0,0,0, +0,0,0,0,0,0,0,214,215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,0,0,0,0,0,0,0,254,255,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,238,239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125,126,127,128,129,130,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,337,338,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,136,137,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -53,7 +55,7 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,22,23,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -63,25 +65,25 @@ -412,412,409,409,412,412,412,409,409,409,409,409,409,409,409,409,412,412,412,0,0,412,412,412,412,412,410,410,410,410,410,410,410,409,409,409,409,409,409,409,409,412,409,409,409,409,409,409, -412,412,412,412,412,412,412,412,409,409,412,412,412,412,412,412,412,412,412,0,0,412,412,412,412,412,410,0,0,0,0,0,410,412,412,412,412,412,409,409,409,412,412,412,412,409,409,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,412,412,412,412,412,410,410,410,410,410,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,412,412,412,412,412,410,0,0,0,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,410,410,410,410,410,410,0,0,0,0,0,410,410,410,410,412,412,412,412,412,412,412,412,410,410,412,412, 412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,410,0,0,410,0,0,0,0,410,0,0,0,0,0,410,0,0,410,412,412,412,412,412,412,412,412,410,410,412,412, 412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,410,0,0,0,0,410,0,410,410,410,0,410,0,0,410,412,410,410,410,410,410,410,412,412,412,412,412, -412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,410,410,0,0,0,410,0,410,410,410,0,410,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,0,0,410,410,0,0,0,410,0,410,0,410,0,410,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,410,410,410,410,410,410,410,410,412,412,412,412,412,412,412,412,412,0,0,0,0,0,410,410,410,410,410,0,410,410,410,410,410,410,412,410,410,410,410,410,410,410,412,412,412,412, 412,412,410,0,0,0,0,0,0,410,412,412,412,412,410,410,410,410,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,410,0,0,0,0,0,0,410,412,412,412,412,410,0,0,410,412,0,0,0,410,410,0,0,0,0,0,0,0,0,0,0,0,410,412,410,410,410,410,410,410,410,410,412,412,412, 412,412,410,0,0,0,410,410,410,410,412,412,412,412,410,410,410,410,412,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,412,412,412,412,412,412,412,410,410,412,412,412, -410,410,410,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,410,410,410,0,0,0,0,0,0,0,0,0,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412, +410,410,410,0,0,0,410,0,0,410,410,410,410,410,410,410,0,0,410,0,0,410,410,410,0,0,0,0,0,0,0,0,0,0,0,410,412,412,412,412,412,412,412,412,412,412,412,412, 410,0,410,410,410,410,410,0,0,410,0,0,0,0,410,410,0,0,410,0,0,0,0,410,410,410,410,410,410,410,410,410,410,410,410,410,412,412,412,412,412,412,412,412,412,412,412,412, 410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,0,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, -410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,410,410,410,0,0,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,410,0,410,410,0,0,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, 410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,0,410,410,0,0,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, -412,412,410,410,410,410,410,410,410,410,410,410,410,410,0,0,0,0,0,0,0,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412, -412,412,409,409,410,410,0,0,410,410,0,0,410,410,0,0,0,0,0,0,0,410,410,410,410,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,0,0,410,410,0,0,410,410,0,0,410,410,0,0,0,0,0,0,0,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,0,0,410,410,0,0,410,410,0,0,410,410,0,0,0,0,0,0,0,410,410,410,410,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,412,412,412,412,410,410,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,0,0,0,0,0,0,0,0,0,0,0,0,0,0,412,412,412,412,412,410,410,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, 412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,410,410,412, @@ -100,7 +102,7 @@ - + @@ -117,7 +119,7 @@ - + diff --git a/assets/DialogsLvl4.json b/assets/level4_dialogs.json similarity index 100% rename from assets/DialogsLvl4.json rename to assets/level4_dialogs.json diff --git a/assets/tileset.png b/assets/tileset.png deleted file mode 120000 index 2378d17..0000000 --- a/assets/tileset.png +++ /dev/null @@ -1 +0,0 @@ -../assets-fx/2b/tileset/tileset2b.png \ No newline at end of file diff --git a/assets/tileset.png b/assets/tileset.png new file mode 100644 index 0000000..2c2ad04 Binary files /dev/null and b/assets/tileset.png differ diff --git a/src/config.h b/src/config.h index 83dbca1..2f7a890 100644 --- a/src/config.h +++ b/src/config.h @@ -3,6 +3,7 @@ #define USB_FEATURE 0 #define DEBUGMODE 0 +#define PRECISION 8 #include diff --git a/src/game.c b/src/game.c index 503b331..88686bf 100644 --- a/src/game.c +++ b/src/game.c @@ -7,57 +7,59 @@ #include #include #include -#include #include #include extern bopti_image_t SignAction_img; extern Dialog *dialogRPG; -extern NPC *npcRPG; -extern uint32_t nbNPC; +// extern NPC *npcRPG; +// extern uint32_t nbNPC; #define MAX_INTERACTION_DISTANCE 12 -void game_logic(Game *game) { +void interaction_available(Game *game) { + uint32_t i; - update_npcs(game); + /*NPCs take priority over signs*/ + + for(uint32_t i = 0; i < game->map_level->nbNPC; i++) { + if(!game->map_level->npcs[i].has_dialog) + continue; - /* we check if interactions are possible close to the player */ - for(uint32_t i = 0; i < game->map_level->nbextradata; i++) { /* simple distance check along X and Y axis */ /* Be careful to use world coordinates, not local (i.e.map) ones */ - if((abs((int)game->player.wx - - (int)game->map_level->extradata[i].x * PXSIZE) < + if((abs((int)game->player.x - + (int)(game->map_level->npcs[i].curx >> PRECISION) * PXSIZE) < MAX_INTERACTION_DISTANCE * PXSIZE) && - (abs((int)game->player.wy - - (int)game->map_level->extradata[i].y * PXSIZE) < - MAX_INTERACTION_DISTANCE * PXSIZE) && - strcmp(game->map_level->extradata[i].type, "NPC") != 0) { + (abs((int)game->player.y - + (int)(game->map_level->npcs[i].cury >> PRECISION) * PXSIZE) < + MAX_INTERACTION_DISTANCE * PXSIZE)) { /* the player can do something */ game->player.canDoSomething = true; /* we mark the action for futur treatment in player_action() */ game->player.whichAction = i; - /* this is not an interraction with a NPC */ - game->player.isInteractingWithNPC = false; + /* this is an interraction with a NPC */ + game->player.isInteractingWithNPC = true; return; } } - for(uint32_t i = 0; i < nbNPC; i++) { + for(i = 0; i < game->map_level->nbSign; i++) { /* simple distance check along X and Y axis */ /* Be careful to use world coordinates, not local (i.e.map) ones */ - if((abs((int)game->player.wx - (int)npcRPG[i].curx * PXSIZE) < + if((abs((int)game->player.x - + (int)game->map_level->signs[i].x * PXSIZE) < MAX_INTERACTION_DISTANCE * PXSIZE) && - (abs((int)game->player.wy - (int)npcRPG[i].cury * PXSIZE) < - MAX_INTERACTION_DISTANCE * PXSIZE) && - strcmp(game->map_level->extradata[i].type, "NPC") != 0) { + (abs((int)game->player.y - + (int)game->map_level->signs[i].y * PXSIZE) < + MAX_INTERACTION_DISTANCE * PXSIZE)) { /* the player can do something */ game->player.canDoSomething = true; - /* we mark the action for futur treatment in player_action() */ + /* we mark the action for future treatment in player_action() */ game->player.whichAction = i; /* this is not an interraction with a NPC */ - game->player.isInteractingWithNPC = true; + game->player.isInteractingWithNPC = false; return; } } @@ -69,6 +71,15 @@ void game_logic(Game *game) { return; } +void game_logic(Game *game) { + + update_npcs(game); + + /* we check if interactions are possible close to the player */ + + interaction_available(game); +} + void game_render_indicator(Game *game) { /* nothing to do for the player so we quit */ if(game->player.canDoSomething == false) @@ -79,16 +90,18 @@ void game_render_indicator(Game *game) { } void game_draw(Game *game) { + /* Draw everything. */ + dclear(C_WHITE); map_render_by_layer(game, BACKGROUND); npc_draw(game); player_draw(game); map_render_by_layer(game, FOREGROUND); game_render_indicator(game); + /*DEBUG*/ dprint(8, 8, C_BLACK, "Lifes: %d", game->player.life); dprint(8, 16, C_BLACK, "Mana: %d", game->mana); } - /* Key management */ void game_get_inputs(Game *game) { diff --git a/src/game.h b/src/game.h index 4af3152..992d0bd 100644 --- a/src/game.h +++ b/src/game.h @@ -11,11 +11,16 @@ typedef enum { D_UP, D_DOWN, D_LEFT, D_RIGHT } Direction; typedef enum { P_LEFTUP = -1, P_CENTER = 0, P_RIGHTDOWN = 1 } Checkpos; +typedef struct { + uint32_t x, y; + uint32_t w, h; + +} Collider; + /* Struct that define player parameters */ typedef struct { - int16_t x, y; /* The position of the player int the current map */ + int16_t x, y; /* The position of the player in the current map */ uint16_t px, py; /* The position of the player on screen */ - int16_t wx, wy; /* position of the player in the world */ int8_t life; /* How many lives the player still has between 0 and 100. */ int8_t speed; /* The speed of the movement of the player. */ @@ -52,42 +57,73 @@ typedef struct { /* position of the item */ uint32_t x; uint32_t y; - /* its name */ + /*id of it's icon*/ + uint32_t icon; + char *name; - /* its class (NPC, SGN, INFO, ... )*/ - char *type; - char *face; /* the ID of the first element of the dialog */ /* (to be aligned with "dialogs.json" IDs)*/ uint32_t dialogID; - /* 0 if imperative dialog (story mode) */ - /* or 1 if the player need to press [SHIFT] to initiate the sequence*/ + /*if the dialog is interactive or not*/ uint32_t needAction; +} Sign; + +typedef struct { + /* current coordinates of the NPC */ + uint32_t curx; + uint32_t cury; + + /* initial coordinates of the NPC (needed to get absolute coordinates of + * path) */ + uint32_t x; + uint32_t y; + /* id of it's face */ + uint16_t face; + + uint8_t paused; + + uint8_t has_dialog; + /* the ID of the first element of the dialog */ + /* (to be aligned with "dialogs.json" IDs)*/ + uint32_t dialogID; + /*if the dialog is interactive or not*/ + uint32_t needAction; + + char *name; /* data for NPC's trajectories */ uint32_t hasPath; uint32_t path_length; + uint32_t currentPoint; int16_t *xpath; int16_t *ypath; - /* ... this can be extended as per needs ... */ -} ExtraData; + int type : 32; + + uint8_t current_group; + uint8_t hostile_to_group; + + uint16_t __padding; +} NPC; + +typedef struct { + Collider collider; + /*if the portal tps to an interior or exterior map*/ + uint16_t tp_interior; + /*Id of the interior/exterior map to transport the player to*/ + uint16_t tp_to; +} Portal; typedef struct { /* width, height and the number of layer of the map */ + uint32_t x; + uint32_t y; uint32_t w; uint32_t h; uint32_t nblayers; uint32_t tileset_size; - /* world coordinates of the upper left and bootom right*/ - /* corners of the current map to be multiplied in game by PXSIZE */ - uint32_t xmin; - uint32_t ymin; - uint32_t xmax; - uint32_t ymax; - /* the tileset to use */ bopti_image_t *tileset; @@ -95,12 +131,14 @@ typedef struct { /* this is given by the layer Walkable of the map in Tiled */ uint8_t *walkable; - /* structure that contains all the items on the map to interract with */ - /* each portion of the map has its own list to avoid scrutinizing too much - */ - /* data when lloking for proximity of items */ - uint32_t nbextradata; - ExtraData *extradata; + uint32_t nbNPC; + NPC *npcs; + + uint32_t nbSign; + Sign *signs; + + uint32_t nbPortal; + Portal *portals; /* structure that contains all the dialogs for that part of the map */ uint32_t nbdialogsdata; @@ -108,6 +146,7 @@ typedef struct { /* list of all the tiles to draw the background and the foreground layers */ uint16_t *layers[]; + } Map; /* This struct will contain all the data of the game. It will make it possible diff --git a/src/main.c b/src/main.c index fd1256a..6029129 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,4 @@ - #include "config.h" -#include "events.h" -#include "npc.h" #include #include @@ -18,33 +15,37 @@ #include #endif // GRAYMODEOK +#if DEBUGMODE +#include +#endif /*DEBUGMODE*/ + #include "dialogs.h" #include "game.h" #include "mapdata.h" #include #include +#include extern bopti_image_t player_face_img; extern Map *worldRPG[]; /* Game data (defined in "game.h")*/ -Game game = {NULL, - {12 * PXSIZE, 36 * PXSIZE, 0, 0, 12 * PXSIZE, 36 * PXSIZE, 100, - SPEED, false, 0, false, false, true}, - {{}, {}, 0}, - false, - false, - false, - 0 +Game game = { + NULL, + {12 * PXSIZE, 36 * PXSIZE, 0, 0, 100, SPEED, false, 0, false, false, true}, + {{}, {}, 0}, + false, + false, + false, + 0, - /* debug variables*/ - , - false, - false, - false, - 100}; + /* debug variables*/ + false, + false, + false, + 100}; /* screen capture management code. TODO: Clean this up! */ @@ -92,6 +93,10 @@ int update_time(void) { int main(void) { +#if DEBUGMODE + gdb_start_on_exception(); +#endif /*DEBUGMODE*/ + __printf_enable_fp(); int timer; @@ -106,7 +111,7 @@ int main(void) { events_bind_variable(&game.handler, (int *)&game.player.life, "life"); events_bind_variable(&game.handler, &game.mana, "mana"); - reload_npc(&game); + // reload_npc(&game); #if USB_FEATURE usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL}; @@ -119,52 +124,57 @@ int main(void) { dgray(DGRAY_ON); #endif +#if DEBUGMODE + dupdate(); + getkey(); +#endif + do { - /*clears & renders everything */ + /* clear screen */ + dclear(C_WHITE); + + /* render the map */ game_draw(&game); - dprint(0,30,0,"draw time : %d", game.frame_duration); - -#if DEBUGMODE && GINT_RENDER_RGB - if(game.debug_map) { - dfont(NULL); - drect(5, 5, 390, 55, C_WHITE); - dprint(10, 10, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 0, - worldRPG[0]->xmin, worldRPG[0]->ymin, worldRPG[0]->xmax, - worldRPG[0]->ymax); - dprint(10, 20, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 1, - worldRPG[1]->xmin, worldRPG[1]->ymin, worldRPG[1]->xmax, - worldRPG[1]->ymax); - dprint(10, 30, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 2, - worldRPG[2]->xmin, worldRPG[2]->ymin, worldRPG[2]->xmax, - worldRPG[2]->ymax); - dprint(10, 40, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 3, - worldRPG[3]->xmin, worldRPG[3]->ymin, worldRPG[3]->xmax, - worldRPG[3]->ymax); - } - if(game.debug_player) { - dfont(NULL); - drect(5, 55, 390, 75, C_WHITE); - dprint(10, 60, C_BLUE, "X= %d - Y= %d / Wx= %d - Wy= %d", - game.player.x, game.player.y, game.player.wx, - game.player.wy); - } - if(game.debug_extra) { - dfont(NULL); - for(int i = 0; i < game.map_level->nbextradata; i++) - dprint(10, 90 + i * 15, C_RED, - "X= %d - Y= %d - T: %d - ID: %d - S: %c", - game.map_level->extradata[i].x, - game.map_level->extradata[i].y, - game.map_level->extradata[i].dialogID, - game.map_level - ->dialogs[game.map_level->extradata[i].dialogID] - .ID, - game.map_level - ->dialogs[game.map_level->extradata[i].dialogID] - .conclusion1[0]); - } -#endif + /*#if DEBUGMODE && GINT_RENDER_RGB + if (game.debug_map) + { + dfont( NULL ); + drect( 5, 5,390, 55, C_WHITE ); + dprint(10, 10, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", + 0, worldRPG[0]->xmin, worldRPG[0]->ymin, + worldRPG[0]->xmax, worldRPG[0]->ymax); + dprint(10, 20, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", + 1, worldRPG[1]->xmin, worldRPG[1]->ymin, + worldRPG[1]->xmax, worldRPG[1]->ymax); + dprint(10, 30, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", + 2, worldRPG[2]->xmin, worldRPG[2]->ymin, + worldRPG[2]->xmax, worldRPG[2]->ymax); + dprint(10, 40, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", + 3, worldRPG[3]->xmin, worldRPG[3]->ymin, + worldRPG[3]->xmax, worldRPG[3]->ymax); + } + if (game.debug_player) + { + dfont( NULL ); + drect( 5, 55,390, 75, C_WHITE ); + dprint( 10, 60, C_BLUE, "X= %d - Y= %d / Wx= %d - Wy= %d", + game.player.x, game.player.y, game.player.wx, + game.player.wy ); + } + if (game.debug_extra) + { + dfont( NULL ); + for (int i=0; inbextradata; i++ ) + dprint( 10, 90+i*15, C_RED, "X= %d - Y= %d - T: %d - ID: %d + - S: %c", game.map_level->extradata[i].x, + game.map_level->extradata[i].y, + game.map_level->extradata[i].dialogID, + game.map_level->dialogs[ + game.map_level->extradata[i].dialogID ].ID, game.map_level->dialogs[ + game.map_level->extradata[i].dialogID ].conclusion1[0] ); + } + #endif*/ /* start the logic of the game */ game_logic(&game); diff --git a/src/map.c b/src/map.c index ea9be31..0314811 100644 --- a/src/map.c +++ b/src/map.c @@ -4,8 +4,16 @@ #include "game.h" #include +#include + +extern Map level0; +extern Map level1; +extern Map level2; +extern Map level3; +extern Map level4; + +Map *worldRPG[] = {&level0, &level1, &level2, &level3, &level4, NULL}; -extern Map *worldRPG[]; // extern ExtraData *extraRPG[]; void map_render(Game *game) { @@ -217,25 +225,17 @@ short int map_get_walkable(Game *game, int x, int y) { : MAP_OUTSIDE; } -/* return the pointer to the map containing the given position */ -Map *map_get_for_coordinates(Game *game, int x, int y) { - /* check if the current map contains the point */ - if(x >= (int)game->map_level->xmin && x < (int)game->map_level->xmax && - y >= (int)game->map_level->ymin && y < (int)game->map_level->ymax) { - return game->map_level; - } - - /* else we check in worldRPG if there is a mal containing that point */ +Map *map_get_for_tile(Game *game, int x, int y) { int i = 0; - Map *current = worldRPG[i]; + Map *map = worldRPG[i]; do { - if(x >= (int)current->xmin && x < (int)current->xmax && - y >= (int)current->ymin && y < (int)current->ymax) - return current; + int rx = x - map->x; + int ry = y - map->y; + if(rx >= 0 && rx < (int)map->w && ry >= 0 && ry < (int)map->h) { + return map; + } i++; - current = worldRPG[i]; - } while(current != NULL); - - /* else we return NULL cause the point is a not within a map */ - return NULL; + map = worldRPG[i]; + } while(map != NULL); + return game->map_level; } diff --git a/src/map.h b/src/map.h index 70a4b0e..249f148 100644 --- a/src/map.h +++ b/src/map.h @@ -50,13 +50,6 @@ short int map_get_tile(Game *game, int x, int y, int l); */ short int map_get_walkable(Game *game, int x, int y); -/* map_get_for_coordinates() - * - * return the pointer to the map containing the given position. - * game: The game struct. - * x: The coordinates to look at. - * y: The coordinates to look at. - */ -Map *map_get_for_coordinates(Game *game, int x, int y); +Map *map_get_for_tile(Game *game, int x, int y); #endif diff --git a/src/npc.c b/src/npc.c index d8abd3e..5479ba0 100644 --- a/src/npc.c +++ b/src/npc.c @@ -16,8 +16,8 @@ extern bopti_image_t tiny_npc_female; extern bopti_image_t tiny_npc_milkman; extern bopti_image_t tiny_npc_police; -NPC *npcRPG; -uint32_t nbNPC = 0; +// NPC *npcRPG; +// uint32_t nbNPC = 0; float length(float x, float y) { return sqrtf(x * x + y * y); } @@ -108,8 +108,8 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { int32_t w = full_map->w; int32_t h = full_map->h; - int32_t x = floor(npc->curx) / T_WIDTH; - int32_t y = floor(npc->cury) / T_HEIGHT; + int32_t x = (npc->curx >> PRECISION) / T_WIDTH; + int32_t y = (npc->cury >> PRECISION) / T_HEIGHT; dest_x /= T_WIDTH; dest_y /= T_HEIGHT; int32_t spos = y * w + x; @@ -201,34 +201,10 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { return 3; } -NPC *npc_create() { - // Use temp pointer to avoid breaking the whole npcRPG on failure - void *temp = realloc(npcRPG, (nbNPC + 1) * sizeof(NPC)); - if(temp == NULL) - return NULL; - npcRPG = temp; - nbNPC++; - NPC *npc = &npcRPG[nbNPC - 1]; - npc->xpath = malloc(2); - npc->ypath = malloc(2); - return npc; -} - -void npc_remove(NPC *npc) { - uint32_t pos = ((uint32_t)npc - (uint32_t)npcRPG) / sizeof(NPC); - if(pos > nbNPC - 1) - return; - if(pos == nbNPC - 1) { - nbNPC--; - return; - } - memmove(npc, &npc[1], (nbNPC - pos - 1) * sizeof(NPC)); -} - // Refactoring to make adding complexity cleaner -void update_npcs([[maybe_unused]] Game *game) { - for(uint32_t u = 0; u < nbNPC; u++) { - update_npc(&npcRPG[u]); +void update_npcs(Game *game) { + for(uint32_t u = 0; u < game->map_level->nbNPC; u++) { + update_npc(&game->map_level->npcs[u]); } } @@ -237,8 +213,10 @@ void update_npc(NPC *npc) { if(!npc->hasPath || npc->paused == true) return; - float vecX = (float)(npc->xpath[npc->currentPoint] + npc->x) - npc->curx; - float vecY = (float)(npc->ypath[npc->currentPoint] + npc->y) - npc->cury; + float vecX = (float)(npc->xpath[npc->currentPoint] + npc->x) - + (npc->curx >> PRECISION); + float vecY = (float)(npc->ypath[npc->currentPoint] + npc->y) - + (npc->cury >> PRECISION); float vecN = length(vecX, vecY); if(vecN > 0.5f) { @@ -249,158 +227,49 @@ void update_npc(NPC *npc) { npc->currentPoint = npc->currentPoint % npc->path_length; } - npc->curx += vecX; - npc->cury += vecY; -} - -void reload_npc(Game *game) { - if(npcRPG != NULL) { - free(npcRPG); - npcRPG = NULL; - } - - nbNPC = 0; - - for(uint32_t u = 0; u < game->map_level->nbextradata; u++) { - ExtraData *Data = &game->map_level->extradata[u]; - - if(strcmp(Data->type, "NPC") == 0) /* the current data is a NPC */ - { - nbNPC++; - } - } - - npcRPG = (NPC *)malloc(nbNPC * sizeof(NPC)); - if(npcRPG == NULL) - return; - int currentNPC = 0; - - for(uint32_t u = 0; u < game->map_level->nbextradata; u++) { - ExtraData *Data = &game->map_level->extradata[u]; - - if(strcmp(Data->type, "NPC") == 0) /* the current data is a NPC */ - { - npcRPG[currentNPC].curx = (float)Data->x; - npcRPG[currentNPC].cury = (float)Data->y; - npcRPG[currentNPC].x = Data->x; - npcRPG[currentNPC].y = Data->y; - npcRPG[currentNPC].dialogID = Data->dialogID; - npcRPG[currentNPC].currentPoint = 1; - npcRPG[currentNPC].hasPath = Data->hasPath; - npcRPG[currentNPC].path_length = Data->path_length; - npcRPG[currentNPC].xpath = Data->xpath; - npcRPG[currentNPC].ypath = Data->ypath; - npcRPG[currentNPC].paused = false; - npcRPG[currentNPC].face = Data->face; - currentNPC++; - } - } + npc->curx += vecX * (float)(1 << PRECISION); + npc->cury += vecY * (float)(1 << PRECISION); } void npc_draw(Game *game) { Player *pl = &game->player; size_t i; - const Face npc_sprites[FACES] = {{"MALE", &tiny_npc_male}, - {"FEMALE", &tiny_npc_female}, - {"MILKMAN", &tiny_npc_milkman}, - {"POLICE", &tiny_npc_police}}; + const bopti_image_t *npc_sprites[FACES] = { + &tiny_npc_male, &tiny_npc_female, &tiny_npc_milkman, &tiny_npc_police}; - for(uint32_t u = 0; u < nbNPC; u++) { - NPC *Data = &npcRPG[u]; + for(uint32_t u = 0; u < game->map_level->nbNPC; u++) { + NPC *Data = &game->map_level->npcs[u]; /* Render the path if in debug*/ #if DEBUGMODE - if(Data->hasPath == 1) /* this NPC has a trajectory */ - { - int NbPoints = Data->path_length + 1; - for(int v = 0; v < NbPoints; v++) { + if(!Data->hasPath) + continue; /* this NPC has a trajectory */ + int NbPoints = Data->path_length + 1; + for(int v = 0; v < NbPoints; v++) { - int16_t deltaX1 = - ((int16_t)(Data->x + Data->xpath[v % NbPoints]) * PXSIZE) - - (int16_t)pl->wx; - int16_t deltaY1 = - ((int16_t)(Data->y + Data->ypath[v % NbPoints]) * PXSIZE) - - (int16_t)pl->wy; - int16_t deltaX2 = - ((int16_t)(Data->x + Data->xpath[(v + 1) % NbPoints]) * - PXSIZE) - - (int16_t)pl->wx; - int16_t deltaY2 = - ((int16_t)(Data->y + Data->ypath[(v + 1) % NbPoints]) * - PXSIZE) - - (int16_t)pl->wy; + int16_t deltaX1 = + ((int16_t)(Data->x + Data->xpath[v % NbPoints]) * PXSIZE) - + (int16_t)pl->wx; + int16_t deltaY1 = + ((int16_t)(Data->y + Data->ypath[v % NbPoints]) * PXSIZE) - + (int16_t)pl->wy; + int16_t deltaX2 = + ((int16_t)(Data->x + Data->xpath[(v + 1) % NbPoints]) * + PXSIZE) - + (int16_t)pl->wx; + int16_t deltaY2 = + ((int16_t)(Data->y + Data->ypath[(v + 1) % NbPoints]) * + PXSIZE) - + (int16_t)pl->wy; - dline(pl->px + deltaX1, pl->py + deltaY1, pl->px + deltaX2, - pl->py + deltaY2, PATH_COLOR); - } + dline(pl->px + deltaX1, pl->py + deltaY1, pl->px + deltaX2, + pl->py + deltaY2, PATH_COLOR); } #endif // DEBUGMODE - int16_t delX = ((int16_t)(Data->curx * PXSIZE)) - (int16_t)pl->wx; - int16_t delY = ((int16_t)(Data->cury * PXSIZE)) - (int16_t)pl->wy; - bopti_image_t *face = &tiny_npc_male; - for(i = 0; i < FACES; i++) { - if(!strcmp(npc_sprites[i].name, Data->face)) { - face = npc_sprites[i].face; - } - } + int16_t delX = ((Data->curx * PXSIZE) >> PRECISION) - (int16_t)pl->x; + int16_t delY = ((Data->cury * PXSIZE) >> PRECISION) - (int16_t)pl->y; + bopti_image_t *face = npc_sprites[Data->face]; dimage(pl->px - P_WIDTH / 2 + delX, pl->py - P_HEIGHT / 2 + delY, face); } } - -void OLD_npc_draw(Game *game) { - Player *player = &game->player; - - for(uint32_t u = 0; u < game->map_level->nbextradata; - u++) // uint pour enlever un warning - { - ExtraData *Data = &game->map_level->extradata[u]; - - if(strcmp(Data->type, "NPC") == 0) /* the current data is a NPC */ - { - - /* TODO : This is for debugging purpose, JUste to render the path */ - /* to be followed by the NPC when this will be implemented */ - -#if DEBUGMODE - - if(Data->hasPath == 1) /* this NPC has a trajectory */ - { - int NbPoints = Data->path_length + 1; - for(int v = 0; v < NbPoints; v++) { - - int16_t deltaX1 = - ((int16_t)(Data->x + Data->xpath[v % NbPoints]) * - PXSIZE) - - (int16_t)player->wx; - int16_t deltaY1 = - ((int16_t)(Data->y + Data->ypath[v % NbPoints]) * - PXSIZE) - - (int16_t)player->wy; - - int16_t deltaX2 = - ((int16_t)(Data->x + Data->xpath[(v + 1) % NbPoints]) * - PXSIZE) - - (int16_t)player->wx; - int16_t deltaY2 = - ((int16_t)(Data->y + Data->ypath[(v + 1) % NbPoints]) * - PXSIZE) - - (int16_t)player->wy; - - dline(player->px + deltaX1, player->py + deltaY1, - player->px + deltaX2, player->py + deltaY2, - PATH_COLOR); - } - } - -#endif // DEBUGMODE - - int16_t deltaX = - ((int16_t)(Data->x * PXSIZE)) - (int16_t)player->wx; - int16_t deltaY = - ((int16_t)(Data->y * PXSIZE)) - (int16_t)player->wy; - dimage(player->px - P_WIDTH / 2 + deltaX, - player->py - P_HEIGHT / 2 + deltaY, &tiny_npc_male); - } - } -} diff --git a/src/npc.h b/src/npc.h index 3eff7c8..d12161c 100644 --- a/src/npc.h +++ b/src/npc.h @@ -16,37 +16,6 @@ enum { }; -typedef struct { - /* current coordinates of the NPC */ - float curx, cury; - - /* initial coordinates of the NPC (needed to get absolute coordinates of - * path) */ - uint32_t x; - uint32_t y; - /* the ID of the first element of the dialog */ - /* (to be aligned with "dialogs.json" IDs)*/ - uint32_t dialogID; - /* the number of the target point of the path */ - /* Note: it must keep the value 0 if NPC has no path assigned */ - uint32_t currentPoint; - /* data of the path */ - uint32_t hasPath; - uint32_t path_length; - int16_t *xpath; - int16_t *ypath; - - int type; - - int8_t current_group; - int8_t hostile_to_group; - - /* is the current NPC in pause (during dialog) */ - bool paused; - - char *face; -} NPC; - // Frees then malloc()s a new path to npc // Useful if you want to safely edit a path int npc_clear_path(NPC *npc); diff --git a/src/player.c b/src/player.c index 8b49fa0..6751d15 100644 --- a/src/player.c +++ b/src/player.c @@ -17,10 +17,8 @@ extern bopti_image_t npc_police; extern bopti_image_t SGN_Icon_img; extern bopti_image_t INFO_Icon_img; -const Face faces[FACES] = {{"MALE", &npc_male}, - {"FEMALE", &npc_female}, - {"MILKMAN", &npc_milkman}, - {"POLICE", &npc_police}}; +const bopti_image_t *faces[FACES] = {&npc_male, &npc_female, &npc_milkman, + &npc_police}; const char one_px_mov[8] = { 0, -1, /* Up */ @@ -89,80 +87,67 @@ void player_move(Game *game, Direction direction) { player->y += dy; } - player->wx = game->map_level->xmin * PXSIZE + player->x; - player->wy = game->map_level->ymin * PXSIZE + player->y; + /* Check if we should change map */ + Map *target = map_get_for_tile(game, + game->map_level->x + player->x / T_WIDTH + + one_px_mov[direction * 2], + game->map_level->y + player->y / T_HEIGHT + + one_px_mov[direction * 2 + 1]); + if(target != game->map_level) { + if(target->x > game->map_level->x) { + player->x = 0; + } + if(target->x < game->map_level->x) { + player->x = target->w * T_WIDTH; + } + if(target->y > game->map_level->y) { + player->y = 0; + } + if(target->y < game->map_level->y) { + player->y = target->h * T_HEIGHT; + } + game->map_level = target; + } } void player_action(Game *game) { - register size_t i; - /* already doing something (action IS NOT with an NPC) */ - if(game->player.isDoingAction) + /* already doing something, or can't do anything*/ + if(game->player.isDoingAction || !game->player.canDoSomething) return; - if(game->player.canDoSomething && !game->player.isInteractingWithNPC) { + if(!game->player.isInteractingWithNPC) { /* we can do something */ /* we indicate that the player is occupied */ game->player.isDoingAction = true; - ExtraData *currentData = - &game->map_level->extradata[game->player.whichAction]; - - /* we use the correct image as per the class of the item */ + Sign *sign = &game->map_level->signs[game->player.whichAction]; bopti_image_t *face; - /* we use the correct image as per the class of the item */ + /* we use the correct image as per the type of the item */ - if(strcmp("INFO", currentData->type) == 0) { + if(sign->icon) face = &INFO_Icon_img; - } else if(strcmp("SGN", currentData->type) == 0) { + else face = &SGN_Icon_img; - } else { - /* It's a NPC */ - /* (Mibi88) TODO: Use string hash + strcmp if the hashes match for - * fast string comparison. */ - face = NULL; - for(i = 0; i < FACES; i++) { - Face current_face = faces[i]; - if(!strcmp(current_face.name, currentData->face)) { - face = current_face.face; - } - } - if(!face) - face = &npc_male; - } - uint32_t dialogStart = currentData->dialogID; + uint32_t dialogStart = sign->dialogID; dialogs_initiate_sequence(game, face, dialogStart); /* when done we release the occupied status of the player */ game->player.isDoingAction = false; - } else if(game->player.canDoSomething && - game->player.isInteractingWithNPC) { + } else { /* we can do something (action IS with an NPC) */ /* we indicate that the player is occupied */ game->player.isDoingAction = true; - NPC *currentNPC = &npcRPG[game->player.whichAction]; + NPC *currentNPC = &game->map_level->npcs[game->player.whichAction]; /* we use the correct image as per the class of the item */ - - ExtraData *currentData = - &game->map_level->extradata[game->player.whichAction]; bopti_image_t *face = &npc_male; + /* It's a NPC */ - /* (Mibi88) TODO: Use string hash + strcmp if the hashes match for - * fast string comparison. */ - face = NULL; - for(i = 0; i < FACES; i++) { - Face current_face = faces[i]; - if(!strcmp(current_face.name, currentNPC->face)) { - face = current_face.face; - } - if(!face) - face = &npc_male; - } - dtext(2, 64, C_BLACK, currentData->type); + face = (bopti_image_t *)faces[currentNPC->face]; uint32_t dialogStart = currentNPC->dialogID; /* we set this NPC to paused to avoid changing its position while @@ -200,57 +185,6 @@ bool player_collision(Game *game, Direction direction, int player_tile_x = player->x + dx; int player_tile_y = player->y + dy; - /* check where the player is expected to go on the next move */ - /* if outside the map, we check if there is a map on the other */ - /* side of the current map*/ - if(map_get_walkable(game, player_tile_x, player_tile_y) == MAP_OUTSIDE) { - // we compute the expected world coordinates accordingly - // while taking care of the scaling between fx and cg models (PXSIZE) - int worldX = (player->wx + dx) / PXSIZE; - int worldY = (player->wy + dy) / PXSIZE; - Map *map = map_get_for_coordinates(game, worldX, worldY); - if(map != NULL && map != game->map_level) { - Map *backupmap = game->map_level; - int backupx = player->x; - int backupy = player->y; - int backupwx = player->wx; - int backupwy = player->wy; - - game->map_level = map; - - player->wx = worldX * PXSIZE; - player->wy = worldY * PXSIZE; - - player->x = (worldX - map->xmin) * PXSIZE; - player->y = (worldY - map->ymin) * PXSIZE; - - int on_walkable = map_get_walkable(game, player->x / T_WIDTH, - player->y / T_HEIGHT); - - int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) - ? walkable_speed[on_walkable] - : 0; - - /* if he's on a hard tile and we need to revert the changes as */ - /* tile on the next side of the border is not walkable */ - - if(!speed) { - game->map_level = backupmap; - player->x = backupx; - player->y = backupy; - player->wx = backupwx; - player->wy = backupwy; - return true; /* He will collide with it. */ - } - - /* we update the list of NPCs in the current map */ - /* to follow the trajectories */ - reload_npc(game); - - return false; - } - } - /* Handle a negative position differently than a positive one. */ if(player_tile_x < 0) player_tile_x = player_tile_x / T_WIDTH - 1; @@ -267,6 +201,7 @@ bool player_collision(Game *game, Direction direction, int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ? walkable_speed[on_walkable] : 0; + // speed = SPEED; /* if he's on a hard tile */ if(!speed) { diff --git a/src/player.h b/src/player.h index a0a2800..a34bd75 100644 --- a/src/player.h +++ b/src/player.h @@ -34,7 +34,8 @@ void player_draw(Game *game); */ void player_move(Game *game, Direction direction); -/* (Mibi88) TODO: Describe this function please, I've no idea what she's for! */ +/*Tries to do an action based on previously set flags (called if the shift key + * is pressed)*/ void player_action(Game *game); /* player_collision()