From 5990166a921af3eb44ea3015607197623c61726d Mon Sep 17 00:00:00 2001 From: immibis Date: Wed, 19 Feb 2025 17:21:26 +0100 Subject: [PATCH] Player start positions are defined in the navmesh file, next to the navmesh and clickregions. --- compile_navmesh.py | 7 +++++ compiled_structures.h | 5 +++ engine.h | 15 ++------- game.cpp | 61 +++++++++++++++++++++---------------- navmesh/basement.tmx | 7 ++++- navmesh/cloakroom.tmx | 7 ++++- navmesh/hallway1.tmx | 10 +++++- navmesh/hallway2.tmx | 10 +++++- navmesh/hallway3.tmx | 7 ++++- navmesh/lobby.tmx | 23 ++++++++++---- navmesh/managers_office.tmx | 13 +++++++- navmesh/world.world | 55 +++++++++++++++++++++++++++++++++ objids.h | 14 ++++++++- pinetab2_framework.cpp | 7 +++-- 14 files changed, 185 insertions(+), 56 deletions(-) create mode 100644 navmesh/world.world diff --git a/compile_navmesh.py b/compile_navmesh.py index aead5d9..f081ea9 100644 --- a/compile_navmesh.py +++ b/compile_navmesh.py @@ -151,4 +151,11 @@ for object in tree.findall("objectgroup[@name='clickable']/object"): out.write("\t\t},\n"); out.write("\t\t{0}\n") out.write("\t},\n") # clickregions end +out.write("\t(const struct level_predef_point[]){\n") # points start +for object in tree.findall("objectgroup[@name='points']/object"): + x,y=int(object.attrib["x"]),int(object.attrib["y"]) + # Note: name can contain commas to populate multiple ID fields, or arithmetic expressions + out.write(f"\t\t{{{x},{y},{object.attrib['name']}}},\n") +out.write("\t\t{0}\n") +out.write("\t},\n") # points end out.write("};\n") diff --git a/compiled_structures.h b/compiled_structures.h index 0304c13..3f5bf87 100644 --- a/compiled_structures.h +++ b/compiled_structures.h @@ -34,8 +34,13 @@ struct level_clickregion { int num_edges; const struct level_clickregion_edge *edges; }; +struct level_predef_point { + int x, y; + int id; +}; struct level_predef_data { const struct level_clickregion *clickregions; // terminated by null entry + const struct level_predef_point *points; // terminated by x=0 y=0 }; diff --git a/engine.h b/engine.h index fd7a7c3..66d0b05 100644 --- a/engine.h +++ b/engine.h @@ -38,7 +38,8 @@ extern struct scene { scene_render_fn render_fn; // default standard_scene_render scene_animtimer_fn animtimer_fn; // default null scene_handle_tap_fn handle_tap_fn; // default standard_handle_tap - struct navmesh *navmesh; // defaults to non-null pointer to empty navmesh + const struct navmesh *navmesh; // defaults to non-null pointer to empty navmesh + const struct level_predef_data *predef; bool use_standard_inventory; // defaults to true bool dim_background; // defaults to false, because most scenes overwrite the whole screen @@ -97,18 +98,6 @@ extern bool need_rerender; void fillrect(int x1, int y1, int width, int height, uint32_t pixel); void blit(int x, int y, int width, int height, uint32_t *pixels); - -// game-specific constants -#define SCENE_LOBBY 1 -#define SCENE_MANAGERS_OFFICE 2 -#define SCENE_MANAGERS_OFFICE_SAFE 3 -#define SCENE_BASEMENT 4 -#define SCENE_TEXTBOX 5 -#define SCENE_HALLWAY1 6 -#define SCENE_HALLWAY2 7 -#define SCENE_HALLWAY3 8 -#define SCENE_CLOAKROOM 9 - // game.cpp void scene_setup(scene *s, int scene, int fromscene); void onclick(int curscene, struct object *obj); diff --git a/game.cpp b/game.cpp index 3c15730..eca60bf 100644 --- a/game.cpp +++ b/game.cpp @@ -3,7 +3,7 @@ #include "engine.h" #include "objids.h" #include "inventory.h" - +#include "compiled_structures.h" #define BGWIDTH 1066 @@ -21,25 +21,45 @@ extern const char _binary_sprite_item_pager_raw_start[]; extern const char _binary_sprite_stickman_raw_start[]; -extern struct navmesh navmesh_lobby, navmesh_managers_office, navmesh_basement, navmesh_cloakroom, navmesh_hallway1, navmesh_hallway2, navmesh_hallway3; -extern struct level_predef_data predef_basement, predef_lobby, predef_managers_office, predef_cloakroom, predef_hallway1, predef_hallway2, predef_hallway3; +extern const struct navmesh navmesh_lobby, navmesh_managers_office, navmesh_basement, navmesh_cloakroom, navmesh_hallway1, navmesh_hallway2, navmesh_hallway3; +extern const struct level_predef_data predef_basement, predef_lobby, predef_managers_office, predef_cloakroom, predef_hallway1, predef_hallway2, predef_hallway3; static void create_player(scene *me, int x, int y) { const int WIDTH=51, HEIGHT=111; scene_add_object(me, OBJID_PLAYER, x-WIDTH/2, y-HEIGHT, WIDTH, HEIGHT, _binary_sprite_stickman_raw_start); } +static const struct level_predef_point *find_level_predef_point(const struct level_predef_data *predef, int id) { + for(const struct level_predef_point *pt = predef->points; pt->x || pt->y; pt++) { + if(pt->id == id) + return pt; + } + return nullptr; +} + +static void create_player_startpt(scene *me, int fromscene) { + int x, y; + assert(me->predef); + const struct level_predef_point *pt = (fromscene < 0 ? nullptr : find_level_predef_point(me->predef, OBJID_PLAYER_START+fromscene)); + if(!pt) + pt = find_level_predef_point(me->predef, OBJID_PLAYER_START_DEFAULT); + if(pt) { + x = pt->x; + y = pt->y; + } else { + x = BGWIDTH/2; + y = BGHEIGHT/2; + } + create_player(me, x, y); +} + void scene_setup(scene *me, int scene, int fromscene) { switch(scene) { case SCENE_LOBBY: scene_add_object(me, OBJID_BACKGROUND, 0, 0, BGWIDTH, BGHEIGHT, _binary_sprite_lobby_raw_start); scene_load_predef(me, &predef_lobby); - switch(fromscene) { - case SCENE_MANAGERS_OFFICE: create_player(me, 256, 445); break; - case SCENE_CLOAKROOM: create_player(me, 777, 443); break; - default: create_player(me, 424, 675); break; - } me->navmesh = &navmesh_lobby; + create_player_startpt(me, fromscene); if(fromscene == -1) { push_scene_textbox("Welcome\n\nto\n\ntestgame"); } @@ -47,13 +67,8 @@ void scene_setup(scene *me, int scene, int fromscene) { case SCENE_MANAGERS_OFFICE: scene_add_object(me, OBJID_BACKGROUND, 0, 0, BGWIDTH, BGHEIGHT, _binary_sprite_managers_office_raw_start); scene_load_predef(me, &predef_managers_office); - switch(fromscene) { - case SCENE_LOBBY: create_player(me, 804, 708); break; - case SCENE_BASEMENT: create_player(me, 408, 559); break; - case SCENE_HALLWAY1: create_player(me, 664, 419); break; - default: create_player(me, 424, 675); break; - } me->navmesh = &navmesh_managers_office; + create_player_startpt(me, fromscene); break; case SCENE_MANAGERS_OFFICE_SAFE: scene_add_object(me, OBJID_BACKGROUND, 248, 0, 787, BGHEIGHT, _binary_sprite_managers_office_safe_raw_start); @@ -68,40 +83,32 @@ void scene_setup(scene *me, int scene, int fromscene) { if(!savefile.got_pager_from_basement) { scene_add_object(me, OBJID_PAGER, 556, 520, 87, 87, _binary_sprite_item_pager_raw_start); } - create_player(me, 435, 404); me->navmesh = &navmesh_basement; + create_player_startpt(me, fromscene); break; case SCENE_CLOAKROOM: scene_add_object(me, OBJID_BACKGROUND, 0, 0, BGWIDTH, BGHEIGHT, _binary_sprite_cloakroom_raw_start); scene_load_predef(me, &predef_cloakroom); me->navmesh = &navmesh_cloakroom; - create_player(me, 361, 714); + create_player_startpt(me, fromscene); break; case SCENE_HALLWAY1: scene_add_object(me, OBJID_BACKGROUND, 0, 0, BGWIDTH, BGHEIGHT, _binary_sprite_hallway1_raw_start); scene_load_predef(me, &predef_hallway1); me->navmesh = &navmesh_hallway1; - switch(fromscene) { - case SCENE_MANAGERS_OFFICE: default: create_player(me, 531, 714); break; - case SCENE_HALLWAY2: create_player(me, 553, 75); break; - } + create_player_startpt(me, fromscene); break; case SCENE_HALLWAY2: scene_add_object(me, OBJID_BACKGROUND, 0, 0, BGWIDTH, BGHEIGHT, _binary_sprite_hallway2_raw_start); scene_load_predef(me, &predef_hallway2); me->navmesh = &navmesh_hallway2; - switch(fromscene) { - case SCENE_HALLWAY1: default: create_player(me, 531, 714); break; - case SCENE_HALLWAY3: create_player(me, 553, 75); break; - } + create_player_startpt(me, fromscene); break; case SCENE_HALLWAY3: scene_add_object(me, OBJID_BACKGROUND, 0, 0, BGWIDTH, BGHEIGHT, _binary_sprite_hallway3_raw_start); scene_load_predef(me, &predef_hallway3); me->navmesh = &navmesh_hallway3; - switch(fromscene) { - case SCENE_HALLWAY2: default: create_player(me, 531, 714); break; - } + create_player_startpt(me, fromscene); break; } } diff --git a/navmesh/basement.tmx b/navmesh/basement.tmx index 52c0163..817b592 100644 --- a/navmesh/basement.tmx +++ b/navmesh/basement.tmx @@ -1,5 +1,5 @@ - + @@ -18,4 +18,9 @@ + + + + + diff --git a/navmesh/cloakroom.tmx b/navmesh/cloakroom.tmx index b30a1c8..c06e40a 100644 --- a/navmesh/cloakroom.tmx +++ b/navmesh/cloakroom.tmx @@ -1,5 +1,5 @@ - + @@ -11,4 +11,9 @@ + + + + + diff --git a/navmesh/hallway1.tmx b/navmesh/hallway1.tmx index 2ee6704..2942b58 100644 --- a/navmesh/hallway1.tmx +++ b/navmesh/hallway1.tmx @@ -1,5 +1,5 @@ - + @@ -36,4 +36,12 @@ + + + + + + + + diff --git a/navmesh/hallway2.tmx b/navmesh/hallway2.tmx index f1860d8..9269051 100644 --- a/navmesh/hallway2.tmx +++ b/navmesh/hallway2.tmx @@ -1,5 +1,5 @@ - + @@ -39,4 +39,12 @@ + + + + + + + + diff --git a/navmesh/hallway3.tmx b/navmesh/hallway3.tmx index b707fe8..c5b0621 100644 --- a/navmesh/hallway3.tmx +++ b/navmesh/hallway3.tmx @@ -1,5 +1,5 @@ - + @@ -41,4 +41,9 @@ + + + + + diff --git a/navmesh/lobby.tmx b/navmesh/lobby.tmx index 348442b..8753e35 100644 --- a/navmesh/lobby.tmx +++ b/navmesh/lobby.tmx @@ -1,13 +1,8 @@ - + - - - - - @@ -31,4 +26,20 @@ + + + + + + + + + + + + + + + + diff --git a/navmesh/managers_office.tmx b/navmesh/managers_office.tmx index fafb315..4c251ee 100644 --- a/navmesh/managers_office.tmx +++ b/navmesh/managers_office.tmx @@ -1,5 +1,5 @@ - + @@ -48,4 +48,15 @@ + + + + + + + + + + + diff --git a/navmesh/world.world b/navmesh/world.world new file mode 100644 index 0000000..6747a92 --- /dev/null +++ b/navmesh/world.world @@ -0,0 +1,55 @@ +{ + "maps": [ + { + "fileName": "hallway2.tmx", + "height": 800, + "width": 1088, + "x": 0, + "y": 0 + }, + { + "fileName": "hallway1.tmx", + "height": 800, + "width": 1088, + "x": 0, + "y": 800 + }, + { + "fileName": "hallway3.tmx", + "height": 800, + "width": 1088, + "x": 0, + "y": -800 + }, + { + "fileName": "managers_office.tmx", + "height": 640, + "width": 960, + "x": 0, + "y": 1600 + }, + { + "fileName": "basement.tmx", + "height": 800, + "width": 1280, + "x": -672, + "y": 2400 + }, + { + "fileName": "lobby.tmx", + "height": 800, + "width": 1280, + "x": 736, + "y": 2400 + }, + { + "fileName": "cloakroom.tmx", + "height": 800, + "width": 1088, + "x": 1280, + "y": 1600 + } + ], + "onlyShowAdjacentMaps": false, + "type": "world" +} diff --git a/objids.h b/objids.h index 4cb3b57..28c77f2 100644 --- a/objids.h +++ b/objids.h @@ -18,4 +18,16 @@ #define OBJID_LOBBY_TO_CLOAKROOM 18 #define OBJID_MANAGERS_OFFICE_TO_HALLWAY 19 -#define OBJID_INVENTORY_SLOTS 0x10000000 // + slot number +#define OBJID_INVENTORY_SLOTS 0x01000000 // + slot number +#define OBJID_PLAYER_START 0x02000000 // + previous scene number +#define OBJID_PLAYER_START_DEFAULT 0x02ffffff + +#define SCENE_LOBBY 1 +#define SCENE_MANAGERS_OFFICE 2 +#define SCENE_MANAGERS_OFFICE_SAFE 3 +#define SCENE_BASEMENT 4 +#define SCENE_TEXTBOX 5 +#define SCENE_HALLWAY1 6 +#define SCENE_HALLWAY2 7 +#define SCENE_HALLWAY3 8 +#define SCENE_CLOAKROOM 9 diff --git a/pinetab2_framework.cpp b/pinetab2_framework.cpp index 6da73ab..80b2242 100644 --- a/pinetab2_framework.cpp +++ b/pinetab2_framework.cpp @@ -229,6 +229,7 @@ struct object *scene_add_object(struct scene *sc, int id, int x, int y, int widt } void scene_load_predef(struct scene *sc, const struct level_predef_data *predef) { + sc->predef = predef; for(const struct level_clickregion *cr = predef->clickregions; cr->num_edges; cr++) { struct object *obj = scene_add_object(sc, cr->id, cr->x, cr->y, cr->width, cr->height, nullptr); obj->clickregion = cr; @@ -352,7 +353,7 @@ static double is_point_in_tri(int x, int y, const struct navmesh_tri *tri) { static int find_navmesh_tri(int x, int y, int tolerance) { int best_tri = -1; double best_dist = tolerance; - struct navmesh *cur_navmesh = top_scene.navmesh; + const struct navmesh *cur_navmesh = top_scene.navmesh; for(int i = 0; i < cur_navmesh->num_tris; i++) { double dist = is_point_in_tri(x, y, &cur_navmesh->tris[i]); if(dist == 0) @@ -392,7 +393,7 @@ void start_player_walk_to_point(int targetX, int targetY) { void standard_handle_tap(struct scene *scene, int x, int y) { uint32_t walkgen = player_walk_generation; int sceneid = scene->id; - struct navmesh *cur_navmesh = top_scene.navmesh; + const struct navmesh *cur_navmesh = top_scene.navmesh; struct object *objects = top_scene.objects; for(int i = 0; i < MAX_OBJECTS_PER_SCENE; i++) { if(!objects[i].id) continue; @@ -443,7 +444,7 @@ static void update_player_walk_script_on_frame(struct script *scr, int wakeupMod deliver_script_wakeup(SCRIPT_WAKEUP_OTHER_SCRIPT, script_id, SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED, 0, 0, 0, 0); return; } - struct navmesh *cur_navmesh = top_scene.navmesh; + const struct navmesh *cur_navmesh = top_scene.navmesh; if(player_walk_script->currentNavmeshTri == -1) { // something weird happened. just teleport player and end movement.