Indoor maps

This commit is contained in:
mibi88 2024-08-01 13:04:20 +02:00
parent 40bfea66aa
commit 1177626b3c
16 changed files with 150 additions and 75 deletions

View file

@ -72,6 +72,7 @@ set(ASSETS_cg
set(ASSETS_cg_EGA64 set(ASSETS_cg_EGA64
assets-cg/ega64/tileset/tilesetEGA64_CG.png assets-cg/ega64/tileset/tilesetEGA64_CG.png
assets-cg/ega64/tileset/tileset_inEGA64_CG.png
) )
set(ASSETS_fx set(ASSETS_fx
@ -86,6 +87,7 @@ set(ASSETS_fx
set(ASSETS_fx_1b set(ASSETS_fx_1b
assets-fx/1b/tileset/tileset1b.png assets-fx/1b/tileset/tileset1b.png
assets-fx/1b/tileset/tileset_in1b.png
assets-fx/1b/npc/char/npc_male.png assets-fx/1b/npc/char/npc_male.png
assets-fx/1b/npc/char/npc_female.png assets-fx/1b/npc/char/npc_female.png
assets-fx/1b/npc/char/npc_milkman.png assets-fx/1b/npc/char/npc_milkman.png
@ -100,6 +102,7 @@ set(ASSETS_fx_1b
set(ASSETS_fx_2b set(ASSETS_fx_2b
assets-fx/2b/tileset/tileset2b.png assets-fx/2b/tileset/tileset2b.png
assets-fx/2b/tileset/tileset_in2b.png
assets-fx/2b/npc/char/npc_male.png assets-fx/2b/npc/char/npc_male.png
assets-fx/2b/npc/char/npc_female.png assets-fx/2b/npc/char/npc_female.png
assets-fx/2b/npc/char/npc_milkman.png assets-fx/2b/npc/char/npc_milkman.png

View file

@ -1,4 +0,0 @@
tileset1b_CG.png:
type: bopti-image
name: img_tilesetnpp
profile: p8

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

View file

@ -1,5 +0,0 @@
tileset2b_CG.png:
type: bopti-image
name: img_tilesetnpp
profile: p8

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

View file

@ -2,4 +2,8 @@ tilesetEGA64_CG.png:
type: bopti-image type: bopti-image
name: img_tilesetnpp name: img_tilesetnpp
profile: p8 profile: p8
tileset_inEGA64_CG.png:
type: bopti-image
name: img_indoor
profile: p8

View file

@ -2,3 +2,6 @@ tileset1b.png:
type: bopti-image type: bopti-image
name: img_tilesetnpp name: img_tilesetnpp
tileset_in1b.png:
type: bopti-image
name: img_indoor

View file

@ -1,3 +1,7 @@
tileset2b.png: tileset2b.png:
type: bopti-image type: bopti-image
name: img_tilesetnpp name: img_tilesetnpp
tileset_in2b.png:
type: bopti-image
name: img_indoor

View file

@ -70,6 +70,8 @@ def convert_map(input: str, output: str, params: dict, target):
npcs = {} npcs = {}
signs = {} signs = {}
portals = {} portals = {}
indoor = 0
name = os.path.splitext(os.path.basename(input))[0] name = os.path.splitext(os.path.basename(input))[0]
@ -115,7 +117,7 @@ def convert_map(input: str, output: str, params: dict, target):
# Get the outdoor tileset # Get the outdoor tileset
try: try:
if VERBOSE: print("INFO: Getting the outdoor tileset") if VERBOSE: print("INFO: Getting the outdoor tileset")
outdoor_tileset = input_map.get_tileset_by_firstgid(1) outdoor_tileset = input_map.get_tileset_by_name("tilesetnpp")
except Exception as e: except Exception as e:
# Show a simple error message on failure. # Show a simple error message on failure.
sys.stderr.write(f"ERROR: Failed to get the outdoor tileset.\n" sys.stderr.write(f"ERROR: Failed to get the outdoor tileset.\n"
@ -125,12 +127,32 @@ def convert_map(input: str, output: str, params: dict, target):
# Get the walkable tileset # Get the walkable tileset
try: try:
if VERBOSE: print("INFO: Getting the walkable tileset") if VERBOSE: print("INFO: Getting the walkable tileset")
walkable_tileset = input_map.get_tileset_by_firstgid(409) walkable_tileset = input_map.get_tileset_by_name("Walkable")
except Exception as e: except Exception as e:
# Show a simple error message on failure. # Show a simple error message on failure.
sys.stderr.write(f"ERROR: Failed to get the walkable tileset.\n" sys.stderr.write(f"ERROR: Failed to get the walkable tileset.\n"
+ f" Error message: {e}\n") + f" Error message: {e}\n")
sys.exit(1) sys.exit(1)
# Check if this is an indoor map
try:
if VERBOSE: print("INFO: Checking if it is an indoor map")
indoor = int(input_map.get_property("indoor"))
except Exception as e:
# Show a warning
print(f"WARNING: Indoor property not found.\n")
if indoor:
# Get the indoor tileset
try:
if VERBOSE: print("INFO: Getting the indoor tileset (it is an\n"
+ " indoor map)")
indoor_tileset = input_map.get_tileset_by_name("indoor")
except Exception as e:
# Show a simple error message on failure.
sys.stderr.write(f"ERROR: Failed to get the indoor tileset.\n"
+ f" Error message: {e}\n")
sys.exit(1)
# Get the background # Get the background
try: try:
@ -141,7 +163,10 @@ def convert_map(input: str, output: str, params: dict, target):
height = bg_layer.get_height() height = bg_layer.get_height()
if VERBOSE: print(f"INFO: Map size: ({width}, {height}).") if VERBOSE: print(f"INFO: Map size: ({width}, {height}).")
# Get the layer data himself # Get the layer data himself
background_layer = bg_layer.get_data_with_tileset(outdoor_tileset) if indoor:
background_layer = bg_layer.get_data_with_tileset(indoor_tileset)
else:
background_layer = bg_layer.get_data_with_tileset(outdoor_tileset)
# Check if the size of the layer data is correct. # Check if the size of the layer data is correct.
if len(background_layer) != width*height: if len(background_layer) != width*height:
raise Exception("Bad layer size!") raise Exception("Bad layer size!")
@ -157,7 +182,10 @@ def convert_map(input: str, output: str, params: dict, target):
if VERBOSE: print("INFO: Getting the foreground layer") if VERBOSE: print("INFO: Getting the foreground layer")
fg_layer = input_map.get_layer_by_name("Foreground") fg_layer = input_map.get_layer_by_name("Foreground")
# Get the layer data himself # Get the layer data himself
foreground_layer = fg_layer.get_data_with_tileset(outdoor_tileset) if indoor:
foreground_layer = fg_layer.get_data_with_tileset(indoor_tileset)
else:
foreground_layer = fg_layer.get_data_with_tileset(outdoor_tileset)
# Check if the size of the layer data is correct. # Check if the size of the layer data is correct.
if len(foreground_layer) != width*height: if len(foreground_layer) != width*height:
raise Exception("Bad layer size!") raise Exception("Bad layer size!")
@ -252,8 +280,14 @@ def convert_map(input: str, output: str, params: dict, target):
map_struct += fxconv.u32(width) map_struct += fxconv.u32(width)
map_struct += fxconv.u32(height) map_struct += fxconv.u32(height)
map_struct += fxconv.u32(3) map_struct += fxconv.u32(3)
map_struct += fxconv.u32(outdoor_tileset.columns) if indoor: map_struct += fxconv.u32(indoor_tileset.columns)
tileset_name = os.path.splitext(os.path.basename(outdoor_tileset.source))[0] else: map_struct += fxconv.u32(outdoor_tileset.columns)
if indoor:
tileset_name = os.path.splitext(
os.path.basename(indoor_tileset.source))[0]
else:
tileset_name = os.path.splitext(
os.path.basename(outdoor_tileset.source))[0]
map_struct += fxconv.ref(f"img_{tileset_name}") map_struct += fxconv.ref(f"img_{tileset_name}")
# Store the walkable layer # Store the walkable layer
@ -335,6 +369,7 @@ def convert_map(input: str, output: str, params: dict, target):
# separately. # separately.
dialog_name = os.path.splitext(os.path.basename(dialog_file))[0] dialog_name = os.path.splitext(os.path.basename(dialog_file))[0]
map_struct += fxconv.ref(f"_{dialog_name}") map_struct += fxconv.ref(f"_{dialog_name}")
map_struct += fxconv.u32(indoor)
# Store the background layer # Store the background layer
background_data = bytes() background_data = bytes()

1
assets/indoor.png Symbolic link
View file

@ -0,0 +1 @@
../assets-fx/2b/tileset/tileset_in2b.png

4
assets/indoor.tsx Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.8" tiledversion="1.8.2" name="indoor" tilewidth="8" tileheight="8" tilecount="286" columns="22">
<image source="indoor.png" width="176" height="104"/>
</tileset>

View file

@ -1,50 +1,76 @@
<?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="12" height="8" tilewidth="8" tileheight="8" infinite="0" nextlayerid="5" nextobjectid="3"> <map version="1.8" tiledversion="1.8.2" orientation="orthogonal" renderorder="right-down" width="24" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="5" nextobjectid="3">
<properties> <properties>
<property name="dialogFile" type="file" value="interior1_0_dialogs.json"/> <property name="dialogFile" type="file" value="interior1_0_dialogs.json"/>
<property name="mapX" type="int" value="65536"/> <property name="indoor" type="int" value="1"/>
<property name="mapY" type="int" value="65536"/> <property name="mapX" type="int" value="0"/>
<property name="mapY" type="int" value="0"/>
</properties> </properties>
<tileset firstgid="1" source="tilesetnpp.tsx"/> <tileset firstgid="1" source="tilesetnpp.tsx"/>
<tileset firstgid="409" source="Walkable.tsx"/> <tileset firstgid="409" source="Walkable.tsx"/>
<layer id="1" name="Background" width="12" height="8"> <tileset firstgid="413" source="indoor.tsx"/>
<layer id="1" name="Background" width="24" height="16">
<data encoding="csv"> <data encoding="csv">
86,90,91,89,90,91,89,90,91,89,90,92, 425,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,427,
110,114,115,113,114,115,113,114,115,113,114,116, 447,617,624,625,626,628,582,583,584,627,628,618,619,620,621,622,622,622,580,581,622,622,623,449,
86,93,94,1,1,1,1,1,9,10,1,92, 447,639,646,647,648,650,604,605,606,649,650,640,641,642,643,644,644,644,602,603,644,644,645,449,
110,117,118,1,1,1,1,1,33,34,1,116, 447,661,668,669,670,672,668,669,670,672,672,662,663,664,665,671,672,671,671,671,672,666,667,449,
86,1,1,1,1,1,1,1,1,1,1,92, 447,691,692,693,694,691,692,693,694,691,692,691,692,693,694,630,631,630,631,630,631,630,631,449,
110,1,1,1,1,133,2,1,1,1,1,116, 447,413,414,414,414,414,414,414,414,414,414,414,415,416,678,652,653,652,653,652,653,652,653,449,
110,1,1,1,1,2,2,1,1,1,1,92, 447,435,436,436,436,436,436,436,436,436,436,436,437,438,678,678,678,678,678,678,678,678,678,449,
110,114,114,114,114,114,114,114,114,114,114,116 447,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,553,554,555,678,553,554,555,449,
447,678,613,614,678,613,614,678,613,614,678,678,678,678,678,678,575,576,577,678,575,576,577,449,
447,678,635,636,678,635,636,678,635,636,678,678,678,678,678,678,597,598,599,678,597,598,599,449,
447,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,449,
447,678,553,554,555,678,678,553,554,555,678,678,678,678,678,678,553,554,555,678,553,554,555,449,
447,678,575,576,577,678,678,575,576,577,611,612,678,678,611,612,575,576,577,678,575,576,577,449,
447,678,597,598,599,678,678,597,598,599,633,634,675,675,633,634,597,598,599,678,597,598,599,449,
447,678,678,678,678,678,678,678,678,678,655,656,675,675,655,656,678,678,678,678,678,678,678,449,
469,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,471
</data> </data>
</layer> </layer>
<layer id="2" name="Foreground" width="12" height="8"> <layer id="2" name="Foreground" width="24" height="16">
<data encoding="csv"> <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,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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> </data>
</layer> </layer>
<layer id="3" name="Walkable" width="12" height="8"> <layer id="3" name="Walkable" width="24" height="16">
<data encoding="csv"> <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,410,410,410,410,410,410,410,410,410,
410,410,410,410,410,410,410,410,410,410,410,410, 410,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,0,0,0,0,0,0,0,410,
410,410,410,0,0,0,0,0,410,0,0,410, 410,409,409,409,409,409,409,409,409,409,409,410,410,410,410,409,0,0,0,0,0,0,0,410,
410,410,410,0,0,0,0,0,410,0,0,410, 410,410,410,410,410,410,410,410,410,410,410,410,409,409,410,410,410,410,410,410,410,410,410,410,
410,0,0,0,0,0,0,0,0,0,0,410, 410,409,409,409,409,409,409,409,409,409,409,409,409,409,409,410,410,410,410,410,410,410,410,410,
410,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,409,410,410,410,410,410,410,410,410,410,
410,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,409,409,0,0,0,0,0,0,0,410,
410,410,410,410,410,410,410,410,410,410,410,410 410,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,410,410,410,0,410,410,410,410,
410,409,410,410,409,410,410,409,410,410,409,409,409,409,409,409,410,410,410,0,410,410,410,410,
410,409,410,410,409,410,410,409,410,410,409,409,409,409,409,409,410,410,410,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,410,410,410,0,0,410,410,410,0,0,0,0,0,0,410,410,410,0,410,410,410,410,
410,0,410,410,410,0,0,410,410,410,410,410,0,0,410,410,410,410,410,0,410,410,410,410,
410,0,410,410,410,0,0,410,410,410,410,410,0,0,410,410,410,410,410,0,410,410,410,410,
410,0,0,0,0,0,0,0,0,0,410,410,0,0,410,410,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
</data> </data>
</layer> </layer>
<objectgroup id="4" name="ExtraData"> <objectgroup id="4" name="ExtraData">
<object id="2" name="porte" type="PORTAL" x="39.6736" y="40.0979" width="15.8058" height="15.9119"> <object id="2" name="porte" type="PORTAL" x="95.4054" y="103.537" width="15.8058" height="15.9119">
<properties> <properties>
<property name="dest" type="file" value="level0.tmx"/> <property name="dest" type="file" value="level0.tmx"/>
<property name="destPortal" value="taverne"/> <property name="destPortal" value="taverne"/>

View file

@ -143,10 +143,11 @@ typedef struct {
/* 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;
Dialog *dialogs; Dialog *dialogs;
uint32_t indoor;
/* list of all the tiles to draw the background and the foreground layers */ /* list of all the tiles to draw the background and the foreground layers */
uint16_t *layers[]; uint16_t *layers[];
} Map; } Map;
/* This struct will contain all the data of the game. It will make it possible /* This struct will contain all the data of the game. It will make it possible

View file

@ -121,25 +121,25 @@ void map_render_by_layer(Game *game, int layer) {
/* for all Layer (2 in the current configuration: Background is layer 0 and /* for all Layer (2 in the current configuration: Background is layer 0 and
* foreground is layer 1 ) */ * foreground is layer 1 ) */
/* x and y will contain the position in the loop. */ /* x and y will contain the position in the loop. */
unsigned char x, y; int x, y;
/* The positions where we start drawing the tiles will be in tx and /* The positions where we start drawing the tiles will be in tx and
* ty. */ * ty. */
unsigned short int tx, ty; int tx, ty;
/* mx and my will contain how many pixels will be hidden on x and on /* mx and my will contain how many pixels will be hidden on x and on
* y. */ * y. */
unsigned char mx, my; int mx, my;
/* dw and dh contain the amount of tiles that will be drawn on x and on /* dw and dh contain the amount of tiles that will be drawn on x and on
* y. */ * y. */
unsigned char dw = DWIDTH / T_WIDTH + 2, dh = DHEIGHT / T_HEIGHT + 1; int dw = DWIDTH / T_WIDTH + 2, dh = DHEIGHT / T_HEIGHT + 1;
/* mw and mh will contain the height and the width of the map. */ /* mw and mh will contain the height and the width of the map. */
unsigned short int mw = map_level->w * T_WIDTH, int mw = map_level->w * T_WIDTH,
mh = map_level->h * T_HEIGHT; mh = map_level->h * T_HEIGHT;
/* tile contains the tile to draw. */ /* tile contains the tile to draw. */
short int tile; unsigned short int tile;
/* The position where I start drawing */ /* The position where I start drawing */
unsigned short int sx, sy; int sx, sy;
/* The position of the tile in the tileset. */ /* The position of the tile in the tileset. */
unsigned short int xtile, ytile; int xtile, ytile;
/* Fix sx. */ /* Fix sx. */
if(player->x < DWIDTH / 2) { if(player->x < DWIDTH / 2) {
/* If I can't center the player because I'm near the left border of /* If I can't center the player because I'm near the left border of

View file

@ -88,25 +88,28 @@ void player_move(Game *game, Direction direction) {
} }
/* Check if we should change map */ /* Check if we should change map */
Map *target = map_get_for_tile(game, /* Disable map change for indoor maps */
game->map_level->x + player->x / T_WIDTH + if(!game->map_level->indoor){
one_px_mov[direction * 2], Map *target = map_get_for_tile(game,
game->map_level->y + player->y / T_HEIGHT + game->map_level->x + player->x / T_WIDTH +
one_px_mov[direction * 2 + 1]); one_px_mov[direction * 2],
if(target != game->map_level) { game->map_level->y + player->y / T_HEIGHT +
if(target->x > game->map_level->x) { one_px_mov[direction * 2 + 1]);
player->x = 0; 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;
} }
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;
} }
} }