pt2game/game.cpp

300 lines
9.9 KiB
C++
Raw Normal View History

#include <assert.h>
#include <stdio.h>
#include "engine.h"
#include "objids.h"
#include "inventory.h"
#include "compiled_structures.h"
#define BGWIDTH 1066
#define BGHEIGHT 800
extern const char _binary_sprite_lobby_raw_start[];
extern const char _binary_sprite_managers_office_raw_start[];
extern const char _binary_sprite_managers_office_safe_raw_start[];
2025-02-18 16:53:24 +00:00
extern const char _binary_sprite_basement_raw_start[];
extern const char _binary_sprite_cloakroom_raw_start[];
extern const char _binary_sprite_hallway1_raw_start[];
extern const char _binary_sprite_hallway2_raw_start[];
extern const char _binary_sprite_hallway3_raw_start[];
extern const char _binary_sprite_item_pager_raw_start[];
extern const char _binary_sprite_stickman_raw_start[];
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);
me->navmesh = &navmesh_lobby;
create_player_startpt(me, fromscene);
if(fromscene == -1) {
push_scene_textbox("Welcome\n\nto\n\ntestgame");
}
break;
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);
me->navmesh = &navmesh_managers_office;
create_player_startpt(me, fromscene);
2025-02-18 16:53:24 +00:00
break;
case SCENE_MANAGERS_OFFICE_SAFE:
scene_add_object(me, OBJID_BACKGROUND, 248, 0, 787, BGHEIGHT, _binary_sprite_managers_office_safe_raw_start);
scene_add_object(me, OBJID_CLOSE_MODAL, 0, 0, 248, 800, nullptr);
scene_add_object(me, OBJID_CLOSE_MODAL, 1035, 0, 1280-1035, 800, nullptr);
me->dim_background = true;
me->use_standard_inventory = false;
break;
2025-02-18 16:53:24 +00:00
case SCENE_BASEMENT:
scene_add_object(me, OBJID_BACKGROUND, 0, 0, BGWIDTH, BGHEIGHT, _binary_sprite_basement_raw_start);
scene_load_predef(me, &predef_basement);
if(!savefile.got_pager_from_basement) {
scene_add_object(me, OBJID_PAGER, 556, 520, 87, 87, _binary_sprite_item_pager_raw_start);
}
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_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;
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;
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;
create_player_startpt(me, fromscene);
break;
}
}
static void transition_scene_on_walk_finish(struct script *scr, int wakeupMode, int arg1, int arg2, int arg3, int arg4) {
scr->id = 0;
if(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT) {
if(scr->vars[0] == SCENE_MANAGERS_OFFICE_SAFE) {
push_scene(scr->vars[0]);
} else {
replace_scene(scr->vars[0]);
}
}
else
assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED);
}
static void start_player_walk_to_point_then_transition_scene(int x, int y, int scene) {
start_player_walk_to_point(x, y);
struct script *scr = scene_add_script(OBJID_PLAYER_WALK_TO_DOOR_SCRIPT, true);
scr->wakeupMode = SCRIPT_WAKEUP_OTHER_SCRIPT;
scr->wakeupArg1 = OBJID_PLAYER_WALK_SCRIPT;
scr->wakeupFn = transition_scene_on_walk_finish;
scr->vars[0] = scene;
}
static void do_popcorn_on_walk_finish(struct script *scr, int wakeupMode, int arg1, int arg2, int arg3, int arg4) {
scr->id = 0;
if(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT) {
if(count_item_in_inventory(INVITEM_POPCORN) >= 3) {
push_scene_textbox(
"You already have\n"
"enough popcorn."
);
} else {
if(add_to_inventory(INVITEM_POPCORN) < 0)
push_scene_textbox("Inventory is full.");
else
push_scene_textbox("You got popcorn.");
}
}
else
assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED);
}
static void get_pager_on_walk_finish(struct script *scr, int wakeupMode, int arg1, int arg2, int arg3, int arg4) {
scr->id = 0;
if(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT) {
struct object *obj = find_object_by_id(OBJID_PAGER);
if(obj) {
if(add_to_inventory(INVITEM_PAGER) < 0) {
push_scene_textbox("Inventory is full.");
} else {
obj->id = 0;
savefile.got_pager_from_basement = true;
push_scene_textbox(
"You found your pager.\n"
"Now you can get out of here."
);
}
}
}
else
assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED);
}
static void start_player_walk_to_point_then(int x, int y, script_wake_fn wake_fn) {
start_player_walk_to_point(x, y);
struct script *scr = scene_add_script(OBJID_PLAYER_WALK_TO_DOOR_SCRIPT, true);
scr->wakeupMode = SCRIPT_WAKEUP_OTHER_SCRIPT;
scr->wakeupArg1 = OBJID_PLAYER_WALK_SCRIPT;
scr->wakeupFn = wake_fn;
}
static void do_leave_lobby_on_walk_finish(struct script *scr, int wakeupMode, int arg1, int arg2, int arg3, int arg4) {
scr->id = 0;
if(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT) {
if(count_item_in_inventory(INVITEM_PAGER) == 0) {
push_scene_textbox(
"You can't leave without\n"
"finding your pager."
);
} else {
push_scene_textbox(
"You got killed in a mugging\n"
"and we rewound time for you,\n"
"as required by the plot to\n"
"keep you inside the theatre."
);
}
}
else
assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED);
}
void onclick(int curscene, struct object *obj) {
if(obj->id == OBJID_CLOSE_MODAL) {
pop_scene();
return;
}
if(obj->id >= OBJID_INVENTORY_SLOTS && obj->id < OBJID_INVENTORY_SLOTS + INVENTORY_SIZE) {
standard_inventory_onclick(obj);
return;
}
switch(curscene) {
case SCENE_LOBBY:
switch(obj->id) {
case OBJID_DOOR_TO_MANAGERS_OFFICE_FROM_LOBBY:
start_player_walk_to_point_then_transition_scene(256, 441, SCENE_MANAGERS_OFFICE);
return;
case OBJID_LEAVE_ROOM:
start_player_walk_to_point_then(obj->x + obj->width/2, obj->y + obj->height, do_leave_lobby_on_walk_finish);
return;
case OBJID_LOBBY_TO_CLOAKROOM:
start_player_walk_to_point_then_transition_scene(777, 441, SCENE_CLOAKROOM);
return;
}
break;
case SCENE_MANAGERS_OFFICE:
switch(obj->id) {
case OBJID_DOOR_TO_LOBBY_FROM_MANAGERS_OFFICE:
2025-02-18 16:53:24 +00:00
start_player_walk_to_point_then_transition_scene(815, 713, SCENE_LOBBY);
return;
case OBJID_MANAGERS_OFFICE_SAFE:
start_player_walk_to_point_then_transition_scene(895, 497, SCENE_MANAGERS_OFFICE_SAFE);
2025-02-18 16:53:24 +00:00
return;
case OBJID_MANAGERS_OFFICE_TRAPDOOR:
start_player_walk_to_point_then_transition_scene(408, 559, SCENE_BASEMENT);
return;
case OBJID_MANAGERS_OFFICE_TO_HALLWAY:
start_player_walk_to_point_then_transition_scene(665, 418, SCENE_HALLWAY1);
return;
2025-02-18 16:53:24 +00:00
}
break;
case SCENE_BASEMENT:
switch(obj->id) {
2025-02-18 16:53:24 +00:00
case OBJID_BASEMENT_LADDER:
start_player_walk_to_point_then_transition_scene(438, 402, SCENE_MANAGERS_OFFICE);
return;
case OBJID_POPCORN_BARREL:
start_player_walk_to_point_then(obj->x + obj->width/2, obj->y + obj->height, do_popcorn_on_walk_finish);
return;
case OBJID_PAGER:
start_player_walk_to_point_then(obj->x + obj->width/2, obj->y + obj->height, get_pager_on_walk_finish);
return;
}
break;
case SCENE_CLOAKROOM:
switch(obj->id) {
case OBJID_LEAVE_ROOM:
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_LOBBY);
return;
}
break;
case SCENE_HALLWAY1:
switch(obj->id) {
case OBJID_LEAVE_ROOM:
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_MANAGERS_OFFICE);
return;
case OBJID_NEXT_ROOM:
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY2);
return;
}
break;
case SCENE_HALLWAY2:
switch(obj->id) {
case OBJID_LEAVE_ROOM:
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY1);
return;
case OBJID_NEXT_ROOM:
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY3);
return;
}
break;
case SCENE_HALLWAY3:
switch(obj->id) {
case OBJID_LEAVE_ROOM:
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY2);
return;
}
break;
}
}