Player walks to the manager's office door before entering it
parent
04a3a748ce
commit
491a5b3331
1
engine.h
1
engine.h
|
@ -44,6 +44,7 @@ struct object *find_object_by_id(int id);
|
|||
struct script *scene_add_script(int id, bool interrupt_existing);
|
||||
struct script *scene_get_script(int id);
|
||||
bool deliver_script_wakeup(int wakeupMode, int wakeupArg1, int wakeupType, int arg1, int arg2, int arg3, int arg4); // deliver to scripts with given wakeupMode and wakeupArg1. Returns true if scene changed.
|
||||
void start_player_walk_to_point(int x, int y); // x and y are not corrected to lie within navmesh
|
||||
|
||||
// game-specific constants
|
||||
#define SCENE_LOBBY 1
|
||||
|
|
22
game.cpp
22
game.cpp
|
@ -1,3 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "engine.h"
|
||||
|
||||
#define BGWIDTH 1280
|
||||
|
@ -15,6 +17,7 @@ extern struct navmesh navmesh_lobby;
|
|||
#define OBJID_DOOR_TO_LOBBY_FROM_MANAGERS_OFFICE 3
|
||||
// #define OBJID_PLAYER 4
|
||||
// #define SCRIPTID_PLAYER_WALK 5
|
||||
#define OBJID_PLAYER_WALK_TO_DOOR_SCRIPT 6
|
||||
|
||||
void scene_setup(int scene) {
|
||||
switch(scene) {
|
||||
|
@ -32,12 +35,29 @@ void scene_setup(int scene) {
|
|||
}
|
||||
}
|
||||
|
||||
static void transition_scene_on_walk_finish(struct script *scr, int wakeupMode, int arg1, int arg2, int arg3, int arg4) {
|
||||
scr->id = 0;
|
||||
printf("walk finish transition %d %d\n", wakeupMode, scr->vars[0]);
|
||||
if(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT)
|
||||
transition_scene(scr->vars[0]);
|
||||
else
|
||||
assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED);
|
||||
}
|
||||
|
||||
void onclick(int curscene, int objid) {
|
||||
switch(curscene) {
|
||||
case SCENE_LOBBY:
|
||||
switch(objid) {
|
||||
case OBJID_DOOR_TO_MANAGERS_OFFICE_FROM_LOBBY:
|
||||
transition_scene(SCENE_MANAGERS_OFFICE);
|
||||
{
|
||||
start_player_walk_to_point(312, 441);
|
||||
|
||||
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_MANAGERS_OFFICE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -202,12 +202,13 @@ struct object *find_object_by_id(int id) {
|
|||
return nullptr;
|
||||
}
|
||||
struct script *scene_add_script(int id, bool interrupt_existing) {
|
||||
if(interrupt_existing && id != OBJID_PLAYER_WALK_SCRIPT) error(1, 0, "scene_add_script: interrupt not implemented");
|
||||
for(int i = 0; i < MAX_GAME_SCRIPTS; i++) {
|
||||
if(scripts[i].id == id && interrupt_existing) {
|
||||
// interrupt existing script?
|
||||
// player walk script is safe to trivially cancel, at least
|
||||
scripts[i].id = 0;
|
||||
if(deliver_script_wakeup(SCRIPT_WAKEUP_OTHER_SCRIPT, id, SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED, 0, 0, 0, 0))
|
||||
return NULL; // scene changed. this probably crashes the caller. should be tested or we need a better way to cancel all running operations on scene change.
|
||||
}
|
||||
if(scripts[i].id == 0) {
|
||||
memset(&scripts[i], 0, sizeof(scripts[i]));
|
||||
|
@ -294,38 +295,49 @@ static int find_navmesh_tri(int x, int y, int tolerance) {
|
|||
}
|
||||
|
||||
static void update_player_walk_script_on_frame(struct script *scr, int wakeupMode, int, int, int, int);
|
||||
|
||||
static uint32_t player_walk_generation = 0;
|
||||
void start_player_walk_to_point(int targetX, int targetY) {
|
||||
player_walk_generation++;
|
||||
|
||||
struct object *player = find_object_by_id(OBJID_PLAYER);
|
||||
if(!player) error(1, 0, "start_player_walk_to_point: no player object");
|
||||
|
||||
int destTri = find_navmesh_tri(targetX, targetY, 999999);
|
||||
if(destTri == -1) error(1, 0, "start_player_walk_to_point: no navmesh");
|
||||
|
||||
struct script_player_walk *player_walk_script = (struct script_player_walk *)scene_add_script(OBJID_PLAYER_WALK_SCRIPT, true);
|
||||
player_walk_script->targetX = targetX;
|
||||
player_walk_script->targetY = targetY;
|
||||
player_walk_script->targetNavmeshTri = destTri;
|
||||
player_walk_script->wakeupMode = SCRIPT_WAKEUP_VIDEO_FRAME;
|
||||
player_walk_script->wakeupFn = update_player_walk_script_on_frame;
|
||||
|
||||
int sourceTri = find_navmesh_tri(player->x+player->width*2, player->y+player->height, 1000000);
|
||||
player_walk_script->currentNavmeshTri = sourceTri;
|
||||
printf("set course from triangle %d to %d\n", sourceTri, destTri);
|
||||
}
|
||||
|
||||
void handle_tap(int x, int y) {
|
||||
uint32_t gencount = scene_generation_count;
|
||||
uint32_t walkgen = player_walk_generation;
|
||||
for(int i = 0; i < MAX_GAME_OBJECTS; i++) {
|
||||
if(objects[i].id && (unsigned int)(x - objects[i].x) < objects[i].width && (unsigned int)(y - objects[i].y) < objects[i].height) {
|
||||
if(gencount != scene_generation_count) return; // early exit if scene changed
|
||||
onclick(curscene, objects[i].id);
|
||||
if(gencount != scene_generation_count) return; // early exit if scene changed, and don't walk the player either
|
||||
}
|
||||
}
|
||||
|
||||
struct script_player_walk *player_walk_script = (struct script_player_walk *)scene_add_script(OBJID_PLAYER_WALK_SCRIPT, true);
|
||||
|
||||
struct object *player = find_object_by_id(OBJID_PLAYER);
|
||||
if(player) {
|
||||
int destTri = find_navmesh_tri(x, y, 50);
|
||||
if(destTri != -1) {
|
||||
int targetX = x, targetY = y;
|
||||
closest_point_inside_tri(&targetX, &targetY, &cur_navmesh->tris[destTri]);
|
||||
|
||||
player_walk_script->targetX = targetX;
|
||||
player_walk_script->targetY = targetY;
|
||||
player_walk_script->targetNavmeshTri = destTri;
|
||||
player_walk_script->wakeupMode = SCRIPT_WAKEUP_VIDEO_FRAME;
|
||||
player_walk_script->wakeupFn = update_player_walk_script_on_frame;
|
||||
|
||||
int sourceTri = find_navmesh_tri(player->x+player->width*2, player->y+player->height, 1000000);
|
||||
player_walk_script->currentNavmeshTri = sourceTri;
|
||||
printf("set course from triangle %d to %d\n", sourceTri, destTri);
|
||||
} else {
|
||||
player_walk_script->id = 0;
|
||||
if(walkgen == player_walk_generation) { // no other handler moved the player
|
||||
struct object *player = find_object_by_id(OBJID_PLAYER);
|
||||
if(player) {
|
||||
int destTri = find_navmesh_tri(x, y, 50);
|
||||
if(destTri != -1) {
|
||||
int targetX = x, targetY = y;
|
||||
closest_point_inside_tri(&targetX, &targetY, &cur_navmesh->tris[destTri]);
|
||||
start_player_walk_to_point(targetX, targetY);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
player_walk_script->id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,11 +348,13 @@ static int move_towards(int cur, int target, int maxrate) {
|
|||
}
|
||||
|
||||
static void update_player_walk_script_on_frame(struct script *scr, int wakeupMode, int, int, int, int) {
|
||||
int script_id = scr->id;
|
||||
struct script_player_walk *player_walk_script = (struct script_player_walk *)scr;
|
||||
if(!player_walk_script) return;
|
||||
struct object *player = find_object_by_id(OBJID_PLAYER);
|
||||
if(!player) {
|
||||
player_walk_script->id = 0;
|
||||
deliver_script_wakeup(SCRIPT_WAKEUP_OTHER_SCRIPT, script_id, SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED, 0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -349,6 +363,7 @@ static void update_player_walk_script_on_frame(struct script *scr, int wakeupMod
|
|||
player->x = player_walk_script->targetX - player->width/2;
|
||||
player->y = player_walk_script->targetY - player->height;
|
||||
player_walk_script->id = 0;
|
||||
deliver_script_wakeup(SCRIPT_WAKEUP_OTHER_SCRIPT, script_id, SCRIPT_WAKEUP_OTHER_SCRIPT, 0, 0, 0, 0);
|
||||
need_rerender = true;
|
||||
} else {
|
||||
int x = player->x+player->width/2;
|
||||
|
@ -372,6 +387,7 @@ static void update_player_walk_script_on_frame(struct script *scr, int wakeupMod
|
|||
}
|
||||
// shouldn't happen
|
||||
player_walk_script->id = 0;
|
||||
deliver_script_wakeup(SCRIPT_WAKEUP_OTHER_SCRIPT, script_id, SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED, 0, 0, 0, 0);
|
||||
return;
|
||||
center_found:;
|
||||
}
|
||||
|
@ -379,6 +395,7 @@ static void update_player_walk_script_on_frame(struct script *scr, int wakeupMod
|
|||
printf("in triangle %d, next triangle %d\n", nmtri, nextTri);
|
||||
if(x == player_walk_script->targetX && y == player_walk_script->targetY) {
|
||||
player_walk_script->id = 0;
|
||||
deliver_script_wakeup(SCRIPT_WAKEUP_OTHER_SCRIPT, script_id, SCRIPT_WAKEUP_OTHER_SCRIPT, 0, 0, 0, 0);
|
||||
} else {
|
||||
player_walk_script->currentNavmeshTri = nextTri; // even if -1
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue