335 lines
10 KiB
C++
335 lines
10 KiB
C++
#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_managers_office_safe_raw_start[];
|
|
extern const char _binary_sprite_item_pager_raw_start[];
|
|
|
|
extern const char _binary_sprite_stickman_raw_start[];
|
|
|
|
extern const struct level_predef_data predef_basement, predef_lobby, predef_managers_office, predef_cloakroom, predef_hallway1, predef_hallway2, predef_hallway3,
|
|
predef_stairway1, predef_hallwayb1, predef_hallwayb2, predef_hallwayb3;
|
|
|
|
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_load_predef(me, &predef_lobby);
|
|
create_player_startpt(me, fromscene);
|
|
if(fromscene == -1) {
|
|
push_scene_textbox("Welcome\n\nto\n\ntestgame");
|
|
}
|
|
break;
|
|
case SCENE_MANAGERS_OFFICE:
|
|
scene_load_predef(me, &predef_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);
|
|
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;
|
|
case SCENE_BASEMENT:
|
|
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);
|
|
}
|
|
create_player_startpt(me, fromscene);
|
|
break;
|
|
case SCENE_CLOAKROOM:
|
|
scene_load_predef(me, &predef_cloakroom);
|
|
create_player_startpt(me, fromscene);
|
|
break;
|
|
case SCENE_HALLWAY1:
|
|
scene_load_predef(me, &predef_hallway1);
|
|
create_player_startpt(me, fromscene);
|
|
break;
|
|
case SCENE_HALLWAY2:
|
|
scene_load_predef(me, &predef_hallway2);
|
|
create_player_startpt(me, fromscene);
|
|
break;
|
|
case SCENE_HALLWAY3:
|
|
scene_load_predef(me, &predef_hallway3);
|
|
create_player_startpt(me, fromscene);
|
|
break;
|
|
case SCENE_STAIRWAY1:
|
|
scene_load_predef(me, &predef_stairway1);
|
|
create_player_startpt(me, fromscene);
|
|
break;
|
|
case SCENE_HALLWAY_B1:
|
|
scene_load_predef(me, &predef_hallwayb1);
|
|
create_player_startpt(me, fromscene);
|
|
break;
|
|
case SCENE_HALLWAY_B2:
|
|
scene_load_predef(me, &predef_hallwayb2);
|
|
create_player_startpt(me, fromscene);
|
|
break;
|
|
case SCENE_HALLWAY_B3:
|
|
scene_load_predef(me, &predef_hallwayb3);
|
|
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:
|
|
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);
|
|
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;
|
|
}
|
|
break;
|
|
case SCENE_BASEMENT:
|
|
switch(obj->id) {
|
|
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;
|
|
case OBJID_GO_LEFT:
|
|
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_STAIRWAY1);
|
|
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;
|
|
case SCENE_STAIRWAY1:
|
|
switch(obj->id) {
|
|
case OBJID_STAIRWAY1_TOP:
|
|
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY_B2);
|
|
return;
|
|
case OBJID_STAIRWAY1_BOTTOM:
|
|
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY1);
|
|
return;
|
|
}
|
|
break;
|
|
case SCENE_HALLWAY_B1:
|
|
switch(obj->id) {
|
|
case OBJID_GO_RIGHT:
|
|
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY_B2);
|
|
return;
|
|
}
|
|
break;
|
|
case SCENE_HALLWAY_B2:
|
|
switch(obj->id) {
|
|
case OBJID_GO_LEFT:
|
|
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY_B1);
|
|
return;
|
|
case OBJID_GO_RIGHT:
|
|
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY_B3);
|
|
return;
|
|
case OBJID_LEAVE_ROOM:
|
|
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_STAIRWAY1);
|
|
return;
|
|
}
|
|
break;
|
|
case SCENE_HALLWAY_B3:
|
|
switch(obj->id) {
|
|
case OBJID_GO_LEFT:
|
|
start_player_walk_to_point_then_transition_scene(obj->x + obj->width/2, obj->y + obj->height, SCENE_HALLWAY_B2);
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|