Revert "Première compilation refactoring ExtraData"

This reverts commit 5bdee9b5af.
This commit is contained in:
attilavs2 2024-07-28 12:38:18 +02:00
parent 5bdee9b5af
commit 35a7a5f923
11 changed files with 520 additions and 577 deletions

View file

@ -9,459 +9,402 @@ import os
DEBUG = 0 DEBUG = 0
def convert(input, output, params, target): def convert(input, output, params, target):
if params["custom-type"] == "map": if params["custom-type"] == "map":
print("ERROR : Asset ", params["name"], " has legacy type map") print("ERROR : Asset ", params["name"], " has legacy type map")
return 1 return 1
elif params["custom-type"] == "world": elif params["custom-type"] == "world":
convert_world(input, output, params, target) convert_world(input, output, params, target)
return 0 return 0
elif params["custom-type"] == "custom-image": elif params["custom-type"] == "custom-image":
convert_custom_image(input, output, params, target) convert_custom_image(input, output, params, target)
return 0 return 0
elif params["custom-type"] == "font": elif params["custom-type"] == "font":
convert_font(input, output, params, target) convert_font(input, output, params, target)
return 0 return 0
elif params["custom-type"] == "dialogs": elif params["custom-type"] == "dialogs":
print("ERROR : Asset ", params["name"], " has legacy type dialog") print("ERROR : Asset ", params["name"], " has legacy type dialog")
#convert_dialogs(input, output, params, target) #convert_dialogs(input, output, params, target)
return 0 return 0
else: else:
return 1 return 1
def convert_world(input, output, params, target): def convert_world(input, output, params, target):
print( "WE ARE COMPUTING THE WORLD", input ) print( "WE ARE COMPUTING THE WORLD", input )
data = json.load(open(input, "r")) data = json.load(open(input, "r"))
nbMaps = ["fileName" in i for i in data["maps"]].count(True) nbMaps = ["fileName" in i for i in data["maps"]].count(True)
if DEBUG: print( "We have to treat ", nbMaps, " maps") if DEBUG: print( "We have to treat ", nbMaps, " maps")
if DEBUG: print( "So let's go ... ") if DEBUG: print( "So let's go ... ")
structWorld = fxconv.Structure()
#structExtra = fxconv.Structure()
structWorld = fxconv.Structure() for i in range(nbMaps):
#structExtra = fxconv.Structure() 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 )
for i in range(nbMaps): mapPath = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json"
nameMap = data["maps"][i]["fileName"].replace(".tmx","") if DEBUG: print("Map ", i , " name : ", mapPath )
nameMapFree = nameMap.split("/")[-1]
#count the number of "back" (cd ..) to locate the map on the computer xmin = data["maps"][i]["x"]
nbRetour = nameMap.count("..")+1 if DEBUG: print( "xmin = ", xmin )
#create the map absolute path
nameTMX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".tmx" ymin = data["maps"][i]["y"]
nameJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json" if DEBUG: print( "ymin = ", ymin )
commandline = 'tiled --export-map json ' + nameTMX + ' ' + nameJSON xmax = data["maps"][i]["x"] + data["maps"][i]["width"]
if DEBUG: print( "TILED COMMAND LINE FOR MAPS : ", commandline ) if DEBUG: print( "xmax = ", xmax )
os.system( commandline )
mapPath = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json" ymax = data["maps"][i]["y"] + data["maps"][i]["height"]
if DEBUG: print("Map ", i , " name : ", mapPath ) if DEBUG: print( "ymax = ", ymax )
xmin = data["maps"][i]["x"] map = get_tile_map_data( mapPath, output, params, target, xmin, ymin, xmax, ymax)
if DEBUG: print( "xmin = ", xmin ) if DEBUG: print( "Map = ", map )
structWorld += fxconv.ptr( map )
ymin = data["maps"][i]["y"] structWorld += fxconv.u32(0)
if DEBUG: print( "ymin = ", ymin )
xmax = data["maps"][i]["x"] + data["maps"][i]["width"] #generate !
if DEBUG: print( "xmax = ", xmax ) fxconv.elf(structWorld, output, "_" + params["name"], **target)
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): def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
print( "WE ARE COMPUTING THE MAP : ", input ) print( "WE ARE COMPUTING THE MAP : ", input )
data = json.load(open(input, "r")) data = json.load(open(input, "r"))
#find the tileset in use. it's a relative path (like ../tileset.tsx) #find the tileset in use. it's a relative path (like ../tileset.tsx)
nameTileset = data["tilesets"][0]["source"].replace(".tsx","") nameTileset = data["tilesets"][0]["source"].replace(".tsx","")
if DEBUG: print(nameTileset) if DEBUG: print(nameTileset)
#the name of the tileset without the .something #the name of the tileset without the .something
nameTilesetFree = nameTileset.split("/")[-1] nameTilesetFree = nameTileset.split("/")[-1]
#count the number of "back" (cd ..) to locate the tileset on the computer #count the number of "back" (cd ..) to locate the tileset on the computer
nbRetour = nameTileset.count("..")+1 nbRetour = nameTileset.count("..")+1
#create the tileset absolute path #create the tileset absolute path
tilesetTSX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".tsx" tilesetTSX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".tsx"
tilesetJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".json" 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 )
commandline = 'tiled --export-tileset json ' + tilesetTSX + ' ' + tilesetJSON tileset = open(tilesetJSON, "r")
if DEBUG: print( "TILED COMMAND LINE FOR TILESET : ", commandline ) data_tileset = json.load(tileset)
os.system( commandline ) tileset_size = data_tileset.get("columns")
tileset.close()
tileset = open(tilesetJSON, "r") #find the ID of the first tile in the walkable tileset ()
data_tileset = json.load(tileset) indexWalkable = data["tilesets"][1]["firstgid"]
tileset_size = data_tileset.get("columns") if DEBUG: print(indexWalkable)
tileset.close()
#find the ID of the first tile in the walkable tileset () #Extract from the json the width, height
indexWalkable = data["tilesets"][1]["firstgid"] w, h = data["width"], data["height"]
if DEBUG: print(indexWalkable)
#Extract from the json the width, height #nbTileLayer is the number of "true" layers (without ObjectsLayer)
w, h = data["width"], data["height"] nbTilelayer = ["data" in i for i in data["layers"]].count(True) - 1
if DEBUG: print( nbTilelayer)
#nbTileLayer is the number of "true" layers (without ObjectsLayer) #index of the various layers (may change from one map to another)
nbTilelayer = ["data" in i for i in data["layers"]].count(True) - 1 layer_walkable = 0
if DEBUG: print( nbTilelayer) layer_foreground = 0
layer_background = 0
#index of the various layers (may change from one map to another) #create the structure of the map
layer_walkable = 0 structMap = fxconv.Structure()
layer_foreground = 0
layer_background = 0
#create the structure of the map structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer)
structMap = fxconv.Structure() structMap += fxconv.u32(tileset_size)
structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer) structMap += fxconv.u32(xmin) + fxconv.u32(ymin) + fxconv.u32(xmax) + fxconv.u32(ymax)
structMap += fxconv.u32(tileset_size)
structMap += fxconv.u32(xmin) + fxconv.u32(ymin) + fxconv.u32(xmax) + fxconv.u32(ymax) structMap += fxconv.ref(f"img_{nameTilesetFree}")
structMap += fxconv.ref(f"img_{nameTilesetFree}")
#extraction of the data contained in the layer "Walkable" of the map #extraction of the data contained in the layer "Walkable" of the map
for i in range(nbTilelayer+1): for i in range(nbTilelayer+1):
datavalid = data["layers"][i] datavalid = data["layers"][i]
if datavalid["name"]=="Walkable": if datavalid["name"]=="Walkable":
layer_walkable = i layer_walkable = i
if DEBUG: print( "Walkable Tile Data in layer : ", layer_walkable) if DEBUG: print( "Walkable Tile Data in layer : ", layer_walkable)
break break
elif i==nbTilelayer: elif i==nbTilelayer:
print( "ERROR : No Walkable layer data !!!" ) print( "ERROR : No Walkable layer data !!!" )
walk_data = bytes() walk_data = bytes()
layer = data["layers"][layer_walkable] layer = data["layers"][layer_walkable]
for tile in layer["data"]: for tile in layer["data"]:
#print( tile ) #print( tile )
if tile == 0: walk_data += fxconv.u8(tile) #if walkable_data = 0 then it is a blanck cell so nothing to change 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) 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) structMap += fxconv.ptr(walk_data)
nbextra = 0 nbextra = 0
extradata = fxconv.Structure() extradata = fxconv.Structure()
nbextra, extradata = get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax) nbextra, extradata = get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax)
if (nbextra==0): if (nbextra==0):
structMap += fxconv.u32( 0 ) structMap += fxconv.u32( 0 )
structMap += fxconv.u32( 0 ) structMap += fxconv.u32( 0 )
else: else:
structMap += fxconv.u32( int(nbextra) ) structMap += fxconv.u32( int(nbextra) )
structMap += fxconv.ptr( extradata ) structMap += fxconv.ptr( extradata )
nameDialog = data["properties"][0]["value"] nameDialog = data["properties"][0]["value"]
dialogfile = "/".join(input.split("/")[:-nbRetour]) + "/" + nameDialog dialogfile = "/".join(input.split("/")[:-nbRetour]) + "/" + nameDialog
if DEBUG: print( "THE DIALOGS ARE CONTAINED IN THE FILE : ", dialogfile ) if DEBUG: print( "THE DIALOGS ARE CONTAINED IN THE FILE : ", dialogfile )
nbdiag = 0 nbdiag = 0
diagdata = fxconv.Structure() diagdata = fxconv.Structure()
nbdiag, diagdata = convert_dialogs(dialogfile, output, params, target) nbdiag, diagdata = convert_dialogs(dialogfile, output, params, target)
if (nbdiag==0): if (nbdiag==0):
structMap += fxconv.u32( 0 ) structMap += fxconv.u32( 0 )
structMap += fxconv.u32( 0 ) structMap += fxconv.u32( 0 )
else: else:
structMap += fxconv.u32( int(nbdiag) ) structMap += fxconv.u32( int(nbdiag) )
structMap += fxconv.ptr( diagdata ) structMap += fxconv.ptr( diagdata )
#extraction of the data contained in the layer "Background" and "Foreground" of the map #extraction of the data contained in the layer "Background" and "Foreground" of the map
#import the Background layer of the map #import the Background layer of the map
for i in range(nbTilelayer+1): for i in range(nbTilelayer+1):
datavalid = data["layers"][i] datavalid = data["layers"][i]
if datavalid["name"]=="Background": if datavalid["name"]=="Background":
layer_background = i layer_background = i
if DEBUG: print( "Background Tile Data in layer : ", layer_background) if DEBUG: print( "Background Tile Data in layer : ", layer_background)
break break
elif i==nbTilelayer: elif i==nbTilelayer:
print( "ERROR : No Background layer data !!!" ) print( "ERROR : No Background layer data !!!" )
layer_data = bytes() layer_data = bytes()
layer = data["layers"][layer_background] layer = data["layers"][layer_background]
for tile in layer["data"]: for tile in layer["data"]:
layer_data += fxconv.u16(tile-1) layer_data += fxconv.u16(tile-1)
structMap += fxconv.ptr(layer_data) structMap += fxconv.ptr(layer_data)
#import the foreground layer of the map #import the foreground layer of the map
for i in range(nbTilelayer+1): for i in range(nbTilelayer+1):
datavalid = data["layers"][i] datavalid = data["layers"][i]
if datavalid["name"]=="Foreground": if datavalid["name"]=="Foreground":
layer_foreground = i layer_foreground = i
if DEBUG: print( "Foreground Tile Data in layer : ", layer_foreground) if DEBUG: print( "Foreground Tile Data in layer : ", layer_foreground)
break break
elif i==nbTilelayer: elif i==nbTilelayer:
print( "ERROR : No Foreground layer data !!!" ) print( "ERROR : No Foreground layer data !!!" )
layer_data = bytes() layer_data = bytes()
layer = data["layers"][layer_foreground] layer = data["layers"][layer_foreground]
for tile in layer["data"]: for tile in layer["data"]:
layer_data += fxconv.u16(tile-1) layer_data += fxconv.u16(tile-1)
structMap += fxconv.ptr(layer_data) structMap += fxconv.ptr(layer_data)
return structMap return structMap
def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax): 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 ) if DEBUG: print( "WE ARE COMPUTING THE EXTRA DATA OF THE MAP : ", input )
data = json.load(open(input, "r")) 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")
nblayer = ["id" in i for i in data["layers"]].count(True) - 1 #index of the various layers (may change from one map to another)
if DEBUG: print( "I found ", nblayer, " of extradata") layer_extradata = 0
#index of the various layers (may change from one map to another) #import the foreground layer of the map
layer_extradata = 0 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)
#import the foreground layer of the map #create the structure of the map
for i in range(nblayer+1): structData = fxconv.Structure()
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 nbExtraData = 0
structData = fxconv.Structure() layer = data["layers"][layer_extradata]
for i in layer["objects"]:
#get the type of the item
tpe = i["type"]
nbSign = 0 #we check if the type corresponds to a items of type Point in Tiled
nbNPC = 0 if tpe in ( "SGN", "NPC", "INFO" ):
nbPortal = 0
nbDiag = 0 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"
npcs = fxconv.Structure() #we now fill all the properties of this item
signs = fxconv.Structure() for j in i["properties"]:
portals = fxconv.Structure() #property "dialog"
if j["name"]=="dialogID": dialogID = j[ "value" ]
#property "isQuestion"
elif j["name"]=="needAction": needAction = j[ "value" ]
layer = data["layers"][layer_extradata] else:
for i in layer["objects"]: #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" ] ) )
#get the type of the item else:
tpe = i["type"] if DEBUG: print( "PNJ has no Path" )
#we check if the type corresponds to a items of type Point in Tiled else:
if tpe in ( "SGN", "NPC", "INFO"): print( "UNIDENTIFIED PROPERTY : ", j["name"])
currData = fxconv.Structure()
x = i["x"] + xmin if DEBUG:
y = i["y"] + ymin print( "OBJECT X= ", x, " Y= ", y, "STR= ", dialogID )
nme = i["name"] print( " Type= ", tpe, " Name= ", nme, "Face =", face_type)
print( " Action?= ", needAction )
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" ]
nbDiag += 1
#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 )
currData += fxconv.u32( int(x) ) structData += fxconv.u32( int(x) )
currData += fxconv.u32( int(y) ) structData += fxconv.u32( int(y) )
currData += fxconv.string( nme ) structData += fxconv.string( nme )
currData += fxconv.string( tpe ) structData += fxconv.string( tpe )
currData += fxconv.string(face_type) structData += fxconv.string(face_type)
currData += fxconv.u32( int(dialogID) ) structData += fxconv.u32( int(dialogID) )
currData += fxconv.u32( int(needAction) ) structData += fxconv.u32( int(needAction) )
if path==0: if path==0:
currData += fxconv.u32(0) structData += fxconv.u32(0)
currData += fxconv.u32(0) structData += fxconv.u32(0)
currData += fxconv.u32(0) structData += fxconv.u32(0)
currData += fxconv.u32(0) structData += fxconv.u32(0)
else: else:
o_xdata = fxconv.Structure() o_xdata = fxconv.Structure()
o_xdata += xdata o_xdata += xdata
o_ydata = fxconv.Structure() o_ydata = fxconv.Structure()
o_ydata += ydata o_ydata += ydata
currData += fxconv.u32(path) structData += fxconv.u32(path)
currData += fxconv.u32(path_length) structData += fxconv.u32(path_length)
currData += fxconv.ptr(o_xdata) structData += fxconv.ptr(o_xdata)
currData += fxconv.ptr(o_ydata) structData += fxconv.ptr(o_ydata)
if tpe == "SGN" or tpe == "INFO": #else we do nothing (yet)
nbSign += 1 else:
signs += currData if DEBUG: print( "Skip this object" )
else:
nbNPC += 1 return nbExtraData, structData
signs += currData
elif tpe == "PORTAL":
nbPortal+=1
currData = fxconv.Structure()
x = i["x"] + xmin
y = i["y"] + ymin
h = -1
w = -1
tp_interior = -1
tp_to = -1
for j in i["properties"]:
if j["name"] == "h":
h = j["value"]
if j["name"] == "w":
w = j["value"]
if j["name"] == "tp_interior":
tp_interior = j["value"]
if j["name"] == "tp_to":
tp_to = j["value"]
if w==-1 or h==-1 or tp_interior==-1 or tp_to==-1:
print("ERROR : Invalid portal " + i["ID"])
continue
currData += fxconv.u32(int(x))
currData += fxconv.u32(int(y))
currData += fxconv.u32(int(w))
currData += fxconv.u32(int(h))
currData += fxconv.u16(int(tp_interior))
currData += fxconv.u16(int(tp_to))
portals += currData
#else we do nothing
else:
print( "Unknown object type !" )
structData += fxconv.u32(nbNPC)
structData += fxconv.ptr(npcs)
structData += fxconv.u32(nbSign)
structData += fxconv.ptr(signs)
structData += fxconv.u32(nbPortal)
structData += fxconv.ptr(portals)
return nbDiag, structData
def convert_custom_image(input, output, params, target): def convert_custom_image(input, output, params, target):
scale = int(params.get("scale", 1)) scale = int(params.get("scale", 1))
# Upscale image before converting # Upscale image before converting
im = Image.open(input) im = Image.open(input)
im = im.resize((im.width * scale, im.height * scale), im = im.resize((im.width * scale, im.height * scale),
resample=Image.NEAREST) resample=Image.NEAREST)
o = fxconv.convert_image_cg(im, params) o = fxconv.convert_image_cg(im, params)
fxconv.elf(o, output, "_" + params["name"], **target) fxconv.elf(o, output, "_" + params["name"], **target)
def convert_font(input, output, params, target): def convert_font(input, output, params, target):
o = fxconv.convert_topti(input, params) o = fxconv.convert_topti(input, params)
fxconv.elf(o, output, "_" + params["name"], **target) fxconv.elf(o, output, "_" + params["name"], **target)
def convert_dialogs(input, output, params, target): def convert_dialogs(input, output, params, target):
if DEBUG: print( "WE ARE COMPUTING THE DIALOGS FROM : ", input ) if DEBUG: print( "WE ARE COMPUTING THE DIALOGS FROM : ", input )
data = json.load(open(input, "r")) data = json.load(open(input, "r"))
structDialogs = fxconv.Structure() structDialogs = fxconv.Structure()
nbdialogs = 0 nbdialogs = 0
for d in data["dialogs"]: for d in data["dialogs"]:
if DEBUG: print( int(d[ "ID" ])) if DEBUG: print( int(d[ "ID" ]))
# print( d[ "dialog" ] ) # print( d[ "dialog" ] )
if DEBUG: print( int(d[ "isQuestion" ]) ) if DEBUG: print( int(d[ "isQuestion" ]) )
# print( d[ "choice" ].replace('$', chr(0)) ) # print( d[ "choice" ].replace('$', chr(0)) )
# print( d[ "conclusion1" ] ) # print( d[ "conclusion1" ] )
# print( int(d[ "next1" ] ) ) # print( int(d[ "next1" ] ) )
# print( d[ "conclusion2" ] ) # print( d[ "conclusion2" ] )
# print( int(d[ "next2" ] ) ) # print( int(d[ "next2" ] ) )
# print( int(d[ "nextOther" ]) ) # print( int(d[ "nextOther" ]) )
nbdialogs = nbdialogs + 1 nbdialogs = nbdialogs + 1
structDialogs += fxconv.u32( int(d[ "ID" ] ) ) structDialogs += fxconv.u32( int(d[ "ID" ] ) )
structDialogs += fxconv.string( d[ "dialog" ] ) structDialogs += fxconv.string( d[ "dialog" ] )
structDialogs += fxconv.u32( int(d[ "isQuestion" ] ) ) structDialogs += fxconv.u32( int(d[ "isQuestion" ] ) )
structDialogs += fxconv.string( d[ "choice" ].replace('$', chr(0)) ) structDialogs += fxconv.string( d[ "choice" ].replace('$', chr(0)) )
structDialogs += fxconv.string( d[ "conclusion1" ] ) structDialogs += fxconv.string( d[ "conclusion1" ] )
structDialogs += fxconv.u32( int(d[ "next1" ] ) ) structDialogs += fxconv.u32( int(d[ "next1" ] ) )
structDialogs += fxconv.string( d[ "conclusion2" ] ) structDialogs += fxconv.string( d[ "conclusion2" ] )
structDialogs += fxconv.u32( int(d[ "next2" ] ) ) structDialogs += fxconv.u32( int(d[ "next2" ] ) )
structDialogs += fxconv.u32( int(d[ "nextOther" ] ) ) structDialogs += fxconv.u32( int(d[ "nextOther" ] ) )
return nbdialogs, structDialogs return nbdialogs, structDialogs
#fxconv.elf(structDialogs, output, "_" + params["name"], **target) #fxconv.elf(structDialogs, output, "_" + params["name"], **target)

View file

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.2" orientation="orthogonal" renderorder="right-down" width="12" height="8" tilewidth="8" tileheight="8" infinite="0" nextlayerid="5" nextobjectid="2">
<tileset firstgid="1" source="tilesetnpp.tsx"/>
<tileset firstgid="409" source="Walkable.tsx"/>
<layer id="1" name="Background" width="12" height="8">
<data encoding="csv">
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
</data>
</layer>
<layer id="2" name="Foreground" width="12" height="8">
<data encoding="csv">
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<layer id="3" name="Walkable" width="12" height="8">
<data encoding="csv">
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
</data>
</layer>
<objectgroup id="4" name="ExtraData">
<object id="1" name="Porte" type="PORTAL" x="47.862" y="63.6163">
<properties>
<property name="h" value="1"/>
<property name="tp_interior" value="0"/>
<property name="tp_to" value="0"/>
<property name="w" value="2"/>
</properties>
<point/>
</object>
</objectgroup>
</map>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.2" orientation="orthogonal" renderorder="right-down" width="48" height="24" tilewidth="8" tileheight="8" infinite="0" nextlayerid="8" nextobjectid="15"> <map version="1.8" tiledversion="1.8.2" orientation="orthogonal" renderorder="right-down" width="48" height="24" tilewidth="8" tileheight="8" infinite="0" nextlayerid="8" nextobjectid="14">
<editorsettings> <editorsettings>
<export target="level0.json" format="json"/> <export target="level0.json" format="json"/>
</editorsettings> </editorsettings>
@ -117,6 +117,7 @@
<object id="12" name="PNJ3" type="NPC" x="267.25" y="125.75"> <object id="12" name="PNJ3" type="NPC" x="267.25" y="125.75">
<properties> <properties>
<property name="dialogID" type="int" value="12"/> <property name="dialogID" type="int" value="12"/>
<property name="face" value="FEMALE"/>
<property name="hasPath" type="int" value="1"/> <property name="hasPath" type="int" value="1"/>
<property name="needAction" type="int" value="1"/> <property name="needAction" type="int" value="1"/>
<property name="path" type="object" value="13"/> <property name="path" type="object" value="13"/>
@ -126,6 +127,7 @@
<object id="2" name="PNJ2" type="NPC" x="164" y="132"> <object id="2" name="PNJ2" type="NPC" x="164" y="132">
<properties> <properties>
<property name="dialogID" type="int" value="5"/> <property name="dialogID" type="int" value="5"/>
<property name="face" value="MALE"/>
<property name="hasPath" type="int" value="0"/> <property name="hasPath" type="int" value="0"/>
<property name="needAction" type="int" value="1"/> <property name="needAction" type="int" value="1"/>
<property name="path" type="object" value="0"/> <property name="path" type="object" value="0"/>
@ -135,6 +137,7 @@
<object id="10" name="PNJ1" type="NPC" x="252" y="164"> <object id="10" name="PNJ1" type="NPC" x="252" y="164">
<properties> <properties>
<property name="dialogID" type="int" value="7"/> <property name="dialogID" type="int" value="7"/>
<property name="face" value="MILKMAN"/>
<property name="hasPath" type="int" value="1"/> <property name="hasPath" type="int" value="1"/>
<property name="needAction" type="int" value="1"/> <property name="needAction" type="int" value="1"/>
<property name="path" type="object" value="9"/> <property name="path" type="object" value="9"/>
@ -168,14 +171,5 @@
<object id="13" name="Chemin 100pas Client Auberge" type="TRJ" x="267.25" y="126.25"> <object id="13" name="Chemin 100pas Client Auberge" type="TRJ" x="267.25" y="126.25">
<polyline points="0,0 -30.5,16.75 -182.5,15.75 -195.25,-26 -183.25,16.5 -29.25,18.5"/> <polyline points="0,0 -30.5,16.75 -182.5,15.75 -195.25,-26 -183.25,16.5 -29.25,18.5"/>
</object> </object>
<object id="14" name="PorteAuberge" type="PORTAL" x="136.094" y="119.871">
<properties>
<property name="h" value="1"/>
<property name="tp_interior" value="1"/>
<property name="tp_to" value="0"/>
<property name="w" value="2"/>
</properties>
<point/>
</object>
</objectgroup> </objectgroup>
</map> </map>

View file

@ -16,58 +16,58 @@
extern bopti_image_t SignAction_img; extern bopti_image_t SignAction_img;
extern Dialog *dialogRPG; extern Dialog *dialogRPG;
//extern NPC *npcRPG; extern NPC *npcRPG;
//extern uint32_t nbNPC; extern uint32_t nbNPC;
#define MAX_INTERACTION_DISTANCE 12 #define MAX_INTERACTION_DISTANCE 12
void interaction_available(Game *game)
{
uint32_t i;
/*NPCs take priority over signs*/ void game_logic(Game *game) {
for(uint32_t i=0; i<game->map_level->nbNPC; i++){ update_npcs( game );
if(!game->map_level->npcs[i].has_dialogue) 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 */ /* simple distance check along X and Y axis */
/* Be careful to use world coordinates, not local (i.e.map) ones */ /* Be careful to use world coordinates, not local (i.e.map) ones */
if ((abs((int) game->player.wx - if ((abs((int) game->player.wx -
(int) game->map_level->npcs[i].curx*PXSIZE ) (int) game->map_level->extradata[i].x*PXSIZE )
< MAX_INTERACTION_DISTANCE*PXSIZE) < MAX_INTERACTION_DISTANCE*PXSIZE)
&& (abs((int) game->player.wy - && (abs((int) game->player.wy -
(int) game->map_level->npcs[i].cury*PXSIZE ) (int) game->map_level->extradata[i].y*PXSIZE )
< MAX_INTERACTION_DISTANCE*PXSIZE)){ < MAX_INTERACTION_DISTANCE*PXSIZE)
&& strcmp(game->map_level->extradata[i].type, "NPC") != 0){
/* the player can do something */ /* the player can do something */
game->player.canDoSomething = true; game->player.canDoSomething = true;
/* we mark the action for futur treatment in player_action() */ /* we mark the action for futur treatment in player_action() */
game->player.whichAction = i; game->player.whichAction = i;
/* this is an interraction with a NPC */
game->player.isInteractingWithNPC = true;
return;
}
}
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) game->map_level->signs[i].x*PXSIZE )
< MAX_INTERACTION_DISTANCE*PXSIZE)
&& (abs((int) game->player.wy -
(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 future treatment in player_action() */
game->player.whichAction = i;
/* this is not an interraction with a NPC */ /* this is not an interraction with a NPC */
game->player.isInteractingWithNPC = false; game->player.isInteractingWithNPC = false;
return; return;
} }
} }
for(uint32_t i=0; i<nbNPC; 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 )
< 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){
/* 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 = true;
return;
}
}
/* else nothing to be done here */ /* else nothing to be done here */
game->player.canDoSomething = false; game->player.canDoSomething = false;
game->player.whichAction = -1; game->player.whichAction = -1;
@ -75,15 +75,6 @@ void interaction_available(Game *game)
return; 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) { void game_render_indicator(Game *game) {
/* nothing to do for the player so we quit */ /* nothing to do for the player so we quit */
@ -102,7 +93,6 @@ void game_draw(Game *game) {
player_draw(game); player_draw(game);
map_render_by_layer(game, FOREGROUND); map_render_by_layer(game, FOREGROUND);
game_render_indicator(game); game_render_indicator(game);
/*DEBUG*/
dprint(8, 8, C_BLACK, "Lifes: %d", game->player.life); dprint(8, 8, C_BLACK, "Lifes: %d", game->player.life);
dprint(8, 16, C_BLACK, "Mana: %d", game->mana); dprint(8, 16, C_BLACK, "Mana: %d", game->mana);
} }

View file

@ -23,12 +23,7 @@ typedef enum {
P_RIGHTDOWN = 1 P_RIGHTDOWN = 1
} Checkpos; } Checkpos;
typedef struct
{
uint32_t x,y;
uint32_t w,h;
} Collider;
/* Struct that define player parameters */ /* Struct that define player parameters */
typedef struct { typedef struct {
@ -40,7 +35,7 @@ typedef struct {
/* set to true if a action can be done in the current position of the map */ /* set to true if a action can be done in the current position of the map */
bool canDoSomething; bool canDoSomething;
/* indicates which data are relevant to the current action in the */ /* indicates which data are relevant to the current action in the */
/* extradata layer of the map */ /* extradata layer of the map */
int32_t whichAction; int32_t whichAction;
@ -68,68 +63,33 @@ typedef struct {
int32_t nextOther; int32_t nextOther;
} Dialog; } Dialog;
typedef struct
{ typedef struct {
/* position of the item */
uint32_t x; uint32_t x;
uint32_t y; uint32_t y;
/*id of it's icon*/ /* its name */
uint16_t icon;
char *name; char *name;
/* its class (NPC, SGN, INFO, ... )*/
char *type;
char *face;
/* the ID of the first element of the dialog */ /* the ID of the first element of the dialog */
/* (to be aligned with "dialogs.json" IDs)*/ /* (to be aligned with "dialogs.json" IDs)*/
uint32_t dialogID; uint32_t dialogID;
/*if the dialog is interactive or not*/ /* 0 if imperative dialog (story mode) */
/* or 1 if the player need to press [SHIFT] to initiate the sequence*/
uint32_t needAction; uint32_t needAction;
} Sign;
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;
/* id of it's face*/
uint16_t face;
bool paused;
bool has_dialogue;
/* 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 */ /* data for NPC's trajectories */
uint32_t hasPath; uint32_t hasPath;
uint32_t path_length; uint32_t path_length;
uint32_t currentPoint;
int16_t *xpath; int16_t *xpath;
int16_t *ypath; int16_t *ypath;
int type; /* ... this can be extended as per needs ... */
} ExtraData;
int8_t current_group;
int8_t hostile_to_group;
} 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 { typedef struct {
/* width, height and the number of layer of the map */ /* width, height and the number of layer of the map */
@ -152,15 +112,11 @@ typedef struct {
/* this is given by the layer Walkable of the map in Tiled */ /* this is given by the layer Walkable of the map in Tiled */
uint8_t *walkable; uint8_t *walkable;
/* structure that contains all the items on the map to interract with */
uint32_t nbNPC; /* each portion of the map has its own list to avoid scrutinizing too much */
NPC *npcs; /* data when lloking for proximity of items */
uint32_t nbextradata;
uint32_t nbSign; ExtraData *extradata;
Sign *signs;
uint32_t nbPortal;
Portal *portals;
/* structure that contains all the dialogs for that part of the map */ /* structure that contains all the dialogs for that part of the map */
uint32_t nbdialogsdata; uint32_t nbdialogsdata;

View file

@ -106,7 +106,7 @@ int main(void) {
events_bind_variable(&game.handler, (int*)&game.player.life, "life"); events_bind_variable(&game.handler, (int*)&game.player.life, "life");
events_bind_variable(&game.handler, &game.mana, "mana"); events_bind_variable(&game.handler, &game.mana, "mana");
//reload_npc(&game); reload_npc(&game);
#if USB_FEATURE #if USB_FEATURE
usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL}; usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL};

View file

@ -3,7 +3,6 @@
#include "game.h" #include "game.h"
#include <gint/display.h> #include <gint/display.h>
#include <gint/keyboard.h>
extern Map *worldRPG[]; extern Map *worldRPG[];
//extern ExtraData *extraRPG[]; //extern ExtraData *extraRPG[];

View file

@ -14,8 +14,8 @@
extern bopti_image_t demo_PNJ_img; extern bopti_image_t demo_PNJ_img;
//NPC *npcRPG; NPC *npcRPG;
//uint32_t nbNPC = 0; uint32_t nbNPC = 0;
float length( float x, float y ) float length( float x, float y )
{ {
@ -197,8 +197,6 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc)
return 3; return 3;
} }
/*The following functions need to be redone*/
/*
NPC *npc_create() NPC *npc_create()
{ {
//Use temp pointer to avoid breaking the whole npcRPG on failure //Use temp pointer to avoid breaking the whole npcRPG on failure
@ -222,14 +220,14 @@ void npc_remove(NPC *npc)
return; return;
} }
memmove(npc, &npc[1], (nbNPC-pos-1)*sizeof(NPC)); memmove(npc, &npc[1], (nbNPC-pos-1)*sizeof(NPC));
}*/ }
//Refactoring to make adding complexity cleaner //Refactoring to make adding complexity cleaner
void update_npcs([[maybe_unused]] Game *game) void update_npcs([[maybe_unused]] Game *game)
{ {
for( uint32_t u=0; u<game->map_level->nbNPC; u++ ) for( uint32_t u=0; u<nbNPC; u++ )
{ {
update_npc(&game->map_level->npcs[u]); update_npc(&npcRPG[u]);
} }
} }
@ -260,7 +258,7 @@ void update_npc(NPC *npc)
} }
/*void reload_npc(Game *game) void reload_npc(Game *game)
{ {
if (npcRPG!=NULL) if (npcRPG!=NULL)
{ {
@ -276,7 +274,7 @@ void update_npc(NPC *npc)
{ {
ExtraData *Data = &game->map_level->extradata[u]; ExtraData *Data = &game->map_level->extradata[u];
if (strcmp(Data->type, "NPC")==0) //the current data is a NPC if (strcmp(Data->type, "NPC")==0) /* the current data is a NPC */
{ {
nbNPC++; nbNPC++;
} }
@ -290,7 +288,7 @@ void update_npc(NPC *npc)
{ {
ExtraData *Data = &game->map_level->extradata[u]; ExtraData *Data = &game->map_level->extradata[u];
if (strcmp(Data->type, "NPC")==0) //the current data is a NPC if (strcmp(Data->type, "NPC")==0) /* the current data is a NPC */
{ {
npcRPG[currentNPC].curx = (float) Data->x; npcRPG[currentNPC].curx = (float) Data->x;
npcRPG[currentNPC].cury = (float) Data->y; npcRPG[currentNPC].cury = (float) Data->y;
@ -307,37 +305,40 @@ void update_npc(NPC *npc)
currentNPC++; currentNPC++;
} }
} }
}*/ }
void npc_draw(Game *game) { void npc_draw(Game *game) {
Player *pl = &game->player; Player *pl = &game->player;
for (uint32_t u=0; u<game->map_level->nbNPC; u++) for (uint32_t u=0; u<nbNPC; u++)
{ {
NPC *Data = &game->map_level->npcs[u]; NPC *Data = &npcRPG[u];
/* Render the path if in debug*/ /* Render the path if in debug*/
#if DEBUGMODE #if DEBUGMODE
if(!Data->hasPath) continue; /* this NPC has a trajectory */ if (Data->hasPath==1) /* this NPC has a trajectory */
int NbPoints = Data->path_length+1;
for(int v=0; v<NbPoints; v++)
{ {
int NbPoints = Data->path_length+1;
for(int v=0; v<NbPoints; v++)
{
int16_t deltaX1=((int16_t) (Data->x + int16_t deltaX1=((int16_t) (Data->x +
Data->xpath[v % NbPoints]) * PXSIZE) Data->xpath[v % NbPoints]) * PXSIZE)
-(int16_t) pl->wx; -(int16_t) pl->wx;
int16_t deltaY1=((int16_t) (Data->y + int16_t deltaY1=((int16_t) (Data->y +
Data->ypath[v % NbPoints]) * PXSIZE) Data->ypath[v % NbPoints]) * PXSIZE)
-(int16_t) pl->wy; -(int16_t) pl->wy;
int16_t deltaX2=((int16_t) (Data->x + int16_t deltaX2=((int16_t) (Data->x +
Data->xpath[(v+1) % NbPoints]) * PXSIZE) Data->xpath[(v+1) % NbPoints]) * PXSIZE)
-(int16_t) pl->wx; -(int16_t) pl->wx;
int16_t deltaY2=((int16_t) (Data->y + int16_t deltaY2=((int16_t) (Data->y +
Data->ypath[(v+1) % NbPoints]) * PXSIZE) Data->ypath[(v+1) % NbPoints]) * PXSIZE)
-(int16_t) pl->wy; -(int16_t) pl->wy;
dline( pl->px + deltaX1, pl->py + deltaY1,pl->px + deltaX2, dline( pl->px + deltaX1, pl->py + deltaY1,
pl->py + deltaY2,PATH_COLOR); pl->px + deltaX2, pl->py + deltaY2,
PATH_COLOR);
}
} }
#endif // DEBUGMODE #endif // DEBUGMODE
@ -346,3 +347,57 @@ void npc_draw(Game *game) {
dimage( pl->px-P_WIDTH/2+delX, pl->py-P_HEIGHT/2+delY, &demo_PNJ_img); dimage( pl->px-P_WIDTH/2+delX, pl->py-P_HEIGHT/2+delY, &demo_PNJ_img);
} }
} }
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,
&demo_PNJ_img);
}
}
}

View file

@ -18,6 +18,37 @@ 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 //Frees then malloc()s a new path to npc
//Useful if you want to safely edit a path //Useful if you want to safely edit a path
int npc_clear_path(NPC *npc); int npc_clear_path(NPC *npc);
@ -31,13 +62,12 @@ int npc_append_path(uint16_t x, uint16_t y, NPC *npc);
//Returns non-zero on failure //Returns non-zero on failure
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc); int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc);
/*
//realloc()s npcRPG to adequate size and returns a pointer to the new element //realloc()s npcRPG to adequate size and returns a pointer to the new element
//Returns NULL on failure //Returns NULL on failure
NPC *npc_create(); NPC *npc_create();
//Pops the NPC from npcRPG //Pops the NPC from npcRPG
void npc_remove(NPC *npc);*/ void npc_remove(NPC *npc);
/* Draws the player player. This function should be called after drawing the /* Draws the player player. This function should be called after drawing the
* map! */ * map! */

View file

@ -51,8 +51,8 @@ const char damage_taken_walkable[WALKABLE_TILE_MAX] = {
extern bopti_image_t demo_player_img; extern bopti_image_t demo_player_img;
//extern NPC *npcRPG; extern NPC *npcRPG;
//extern uint32_t nbNPC; extern uint32_t nbNPC;
void player_draw(Game *game) { void player_draw(Game *game) {
@ -106,51 +106,78 @@ void player_move(Game *game, Direction direction) {
} }
void player_action(Game *game) { void player_action(Game *game) {
register size_t i;
/* already doing something (action IS NOT with an NPC) */
if(game->player.isDoingAction) return;
/* already doing something, or can't do anything*/ if(game->player.canDoSomething && !game->player.isInteractingWithNPC){
if(game->player.isDoingAction || !game->player.canDoSomething) return;
if(!game->player.isInteractingWithNPC)
{
/* we can do something */ /* we can do something */
/* we indicate that the player is occupied */ /* we indicate that the player is occupied */
game->player.isDoingAction = true; game->player.isDoingAction = true;
Sign *sign = &game->map_level->signs[game->player.whichAction]; ExtraData *currentData = &game->map_level->extradata[game->player.whichAction];
/* we use the correct image as per the class of the item */
bopti_image_t *face; bopti_image_t *face;
/* we use the correct image as per the type of the item */ /* we use the correct image as per the class of the item */
if(sign->icon) if (strcmp("INFO", currentData->type)==0){
face = &INFO_Icon_img; face = &INFO_Icon_img;
else }else if (strcmp("SGN", currentData->type)==0){
face = &SGN_Icon_img; 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++){
struct Face current_face = faces[i];
if(!strcmp(current_face.name, currentData->face)){
face = current_face.face;
}
}
if(!face) face = &npc_male;
}
uint32_t dialogStart = sign->dialogID; uint32_t dialogStart = currentData->dialogID;
dialogs_initiate_sequence(game, face, dialogStart); dialogs_initiate_sequence(game, face, dialogStart);
/* when done we release the occupied status of the player */ /* when done we release the occupied status of the player */
game->player.isDoingAction = false; game->player.isDoingAction = false;
} }else if(game->player.canDoSomething && game->player.isInteractingWithNPC){
else
{
/* we can do something (action IS with an NPC) */ /* we can do something (action IS with an NPC) */
/* we indicate that the player is occupied */ /* we indicate that the player is occupied */
game->player.isDoingAction = true; game->player.isDoingAction = true;
NPC *currentNPC = &game->map_level->npcs[game->player.whichAction]; NPC *currentNPC = &npcRPG[game->player.whichAction];
/* we use the correct image as per the class of the item */ /* we use the correct image as per the class of the item */
/*TODO*/
bopti_image_t *face = &npc_male;
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++){
struct 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);
uint32_t dialogStart = currentNPC->dialogID; uint32_t dialogStart = currentNPC->dialogID;
/* we set this NPC to paused to avoid changing its position while /* we set this NPC to paused to avoid changing its position while
* talking (the rest of the NPCs pursue their action) */ * talking (the rest of the NPCs pursue their action) */
currentNPC->paused = true; currentNPC->paused = true;
dialogs_initiate_sequence(game, face, dialogStart); dialogs_initiate_sequence(game, face, dialogStart);
/* when done we release the occupied status of the player */ /* when done we release the occupied status of the player */
@ -211,10 +238,10 @@ bool player_collision(Game *game, Direction direction,
int on_walkable = map_get_walkable(game, player->x/T_WIDTH, int on_walkable = map_get_walkable(game, player->x/T_WIDTH,
player->y/T_HEIGHT); player->y/T_HEIGHT);
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ? int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
walkable_speed[on_walkable] : 0; walkable_speed[on_walkable] : 0;
/* if he's on a hard tile and we need to revert the changes as */ /* 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 */ /* tile on the next side of the border is not walkable */
@ -229,7 +256,7 @@ bool player_collision(Game *game, Direction direction,
/* we update the list of NPCs in the current map */ /* we update the list of NPCs in the current map */
/* to follow the trajectories */ /* to follow the trajectories */
//reload_npc(game); reload_npc(game);
return false; return false;
} }

View file

@ -6,6 +6,7 @@
#include "game.h" #include "game.h"
#include "memory.h" #include "memory.h"
/* Structure 'Player' has been moved to game.h */ /* Structure 'Player' has been moved to game.h */
/* to avoid circular references between map.h, game.h and player.h */ /* to avoid circular references between map.h, game.h and player.h */
/* only methods propotypes are now in dedicated header files */ /* only methods propotypes are now in dedicated header files */
@ -27,7 +28,7 @@ void player_draw(Game *game);
*/ */
void player_move(Game *game, Direction direction); void player_move(Game *game, Direction direction);
/*Tries to do an action based on previously set flags (called if the shift key is pressed)*/ /* (Mibi88) TODO: Describe this function please, I've no idea what she's for! */
void player_action(Game *game); void player_action(Game *game);
/* player_collision() /* player_collision()