[Add] Player death with short cinematic.

This commit is contained in:
Allanis 2013-03-20 20:23:39 +00:00
parent 5c15cf5265
commit ccffdae9fd
7 changed files with 124 additions and 20 deletions

View File

@ -256,9 +256,10 @@ static void input_key(int keynum, double value, int abs) {
}
// Show pilot information.
else if(KEY("info") && NOHYP()) {
if(value == KEY_PRESS) info_menu();
if(value == KEY_PRESS) menu_info();
}
}
#undef KEY
// --Events--

View File

@ -19,11 +19,15 @@
#define OUTFITS_WIDTH 400
#define OUTFITS_HEIGHT 200
#define DEATH_WIDTH 120
#define DEATH_HEIGHT 160
#define BUTTON_WIDTH 80
#define BUTTON_HEIGHT 30
#define MENU_SMALL (1<<0)
#define MENU_INFO (1<<1)
#define MENU_DEATH (1<<2)
#define menu_isOpen(f) (menu_open & (f))
#define menu_Open(f) (menu_open |= (f))
#define menu_Close(f) (menu_open ^= (f))
@ -33,14 +37,16 @@ static int menu_open = 0;
static void menu_small_close(char* str);
static void edit_options(void);
static void exit_game(void);
static void info_menu_close(char* str);
static void menu_info_close(char* str);
static void info_outfits_menu(char* str);
static void info_outfits_menu_close(char* str);
static void menu_death_respawn(char* str);
// Ze ingame menu.
// Small ingame menu.
void menu_small(void) {
if(menu_isOpen(MENU_SMALL)) return; // It's already open..
if(menu_isOpen(MENU_SMALL) || menu_isOpen(MENU_DEATH))
return; // It's already open..
pause();
unsigned int wid;
@ -82,7 +88,7 @@ static void exit_game(void) {
}
// Info menu.
void info_menu(void) {
void menu_info(void) {
if(menu_isOpen(MENU_INFO)) return;
pause();
@ -120,13 +126,13 @@ void info_menu(void) {
"btnMissions", "Missions", NULL);
window_addButton(wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnClose", "Close", info_menu_close);
"btnClose", "Close", menu_info_close);
menu_Open(MENU_INFO);
}
static void info_menu_close(char* str) {
static void menu_info_close(char* str) {
if(strcmp(str, "btnClose")==0)
window_destroy(window_get("Info"));
@ -169,3 +175,25 @@ static void info_outfits_menu_close(char* str) {
window_destroy(window_get(str+5)); // closeFoo -> Foo.
}
// Pilot dead.
void menu_death(void) {
unsigned int wid;
wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT);
window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnNew", "New Game", menu_death_respawn);
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnExit", "Exit", (void(*)(char*)) exit_game);
menu_Open(MENU_DEATH);
}
static void menu_death_respawn(char* str) {
(void)str;
window_destroy(window_get("Death"));
menu_Close(MENU_DEATH);
player_new();
}

View File

@ -2,5 +2,6 @@
void menu_small(void);
void info_menu(void);
void menu_info(void);
void menu_deah(void);

View File

@ -32,13 +32,17 @@ static Fleet* fleet_stack = NULL;
static int nfleets = 0;
// External.
extern void ai_destroy(Pilot* p); // Ai.
extern void ai_think(Pilot* pilot); // Ai.c
extern void ai_create(Pilot* pilot); // ai.c
extern void player_think(Pilot* pilot); // Player.c
extern void player_brokeHyperspace(void); // Player.c
extern double player_faceHyperspace(void); // Player.c
extern int gui_load(const char* name); // Player.c
// AI.
extern void ai_destroy(Pilot* p);
extern void ai_think(Pilot* pilot);
extern void ai_create(Pilot* pilot);
// Player.
extern void player_think(Pilot* pilot);
extern void player_brokeHyperspace(void);
extern double player_faceHyperspace(void);
extern void player_dead(void);
extern void player_destroyed(void);
extern int gui_load(const char* name);
// Internal.
static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t);
static void pilot_update(Pilot* pilot, const double dt);
@ -244,6 +248,7 @@ void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
void pilot_dead(Pilot* p) {
// Basically just set the timers..
if(p->id == PLAYER_ID) player_dead();
p->timer[0] = SDL_GetTicks(); // No need for AI anymore.
p->ptimer = p->timer[0] + 1000 + (unsigned int)sqrt(10*p->armour_max*p->shield_max);
p->timer[1] = p->timer[0]; // Explosion timer.
@ -305,10 +310,12 @@ static void pilot_update(Pilot* pilot, const double dt) {
unsigned int t;
double px, py, vx, vy;
if((pilot != player) && pilot_isFlag(pilot, PILOT_DEAD)) {
if(pilot_isFlag(pilot, PILOT_DEAD)) {
t = SDL_GetTicks();
if(t > pilot->ptimer) {
if(pilot->id == PLAYER_ID)
player_destroyed();
pilot_setFlag(pilot, PILOT_DELETE); // It'll get deleted next frame.
return;
}
@ -338,7 +345,7 @@ static void pilot_update(Pilot* pilot, const double dt) {
spfx_add(spfx_get("ExpS"), px, py, vx, vy, SPFX_LAYER_BACK);
}
}
else if((pilot != player) && (pilot->armour <= 0.)) // PWNED!
else if(pilot->armour <= 0.) // PWNED!
pilot_dead(pilot);
// Pupose fallthrough to get the movement similar to disabled.
@ -733,6 +740,7 @@ unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
// Frees and cleans up a pilot.
static void pilot_free(Pilot* p) {
if(player == p) player = NULL;
solid_free(p->solid);
if(p->outfits) free(p->outfits);
free(p->name);

View File

@ -13,6 +13,8 @@
#include "sound.h"
#include "economy.h"
#include "pause.h"
#include "menu.h"
#include "toolkit.h"
#include "player.h"
#define XML_GUI_ID "GUIs" // XML section identifier.
@ -39,6 +41,9 @@ unsigned int player_target = PLAYER_ID; // Targetted pilot.
// Internal
int planet_target = -1; // Targetted planet.
int hyperspace_target = -1; // Target hyperspace route.
// For death etc.
static unsigned int player_timer = 0;
static Vec2 player_cam;
// Pilot stuff for GUI.
extern Pilot** pilot_stack;
@ -111,6 +116,9 @@ static void rect_parse(const xmlNodePtr parent,
static int gui_parse(const xmlNodePtr parent, const char* name);
static void gui_renderPilot(const Pilot* p);
static void gui_renderBar(const glColour* c, const Rect* r, const double w);
// Externed.
void player_dead(void);
void player_destroyed(void);
// Create a new player.
void player_new(void) {
@ -169,6 +177,9 @@ void player_new(void) {
free(buf);
xmlCleanupParser();
// In case we are respawning.
player_rmFlag(PLAYER_DESTROYED);
// Money.
player_credits = RNG(l, h);
@ -286,6 +297,9 @@ void player_renderBG(void) {
glColour* c;
Planet* planet;
if(player_isFlag(PLAYER_DESTROYED) ||
pilot_isFlag(player, PILOT_DEAD)) return;
if(planet_target >= 0) {
planet = &cur_system->planets[planet_target];
@ -316,6 +330,34 @@ void player_render(void) {
glColour* c;
glFont* f;
if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) {
if(player_isFlag(PLAYER_DESTROYED)) {
if(!toolkit && (SDL_GetTicks() > player_timer))
menu_death();
} else
pilot_render(player);
// Fancy cinematic scene borders.
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); // Translation matrix.
glTranslated(x-(double)gl_screen.w/2., y-(double)gl_screen.h/2., 0);
COLOUR(cBlack);
glBegin(GL_QUADS);
glVertex2d(0., 0.);
glVertex2d(0., gl_screen.h*0.2);
glVertex2d(gl_screen.w, gl_screen.h*0.2);
glVertex2d(gl_screen.w, 0.);
glVertex2d(0., gl_screen.h);
glVertex2d(gl_screen.w, gl_screen.h);
glVertex2d(0., gl_screen.h*0.8);
glEnd();
glPopMatrix(); // Translation matrix.
return;
}
// Render the player target graphics.
if(player_target != PLAYER_ID) p = pilot_get(player_target);
else p = NULL;
@ -880,6 +922,9 @@ void gui_free(void) {
// Used in pilot.c
// Basically uses keyboard input instead of AI input.
void player_think(Pilot* player) {
// Last I checked, the dead didn't think..
if(pilot_isFlag(player, PILOT_DEAD)) return;
// PLAYER_FACE will take over navigation.
if(player_isFlag(PLAYER_FACE)) {
if(player_target != PLAYER_ID)
@ -1128,3 +1173,17 @@ void player_screenshot(void) {
gl_screenshot(filename);
}
// Player go pwned.
void player_dead(void) {
gui_xoff = 0.;
gui_yoff = 0.;
}
// Player blew up in a nice fireball.
void player_destroyed(void) {
vectcpy(&player_cam, &player->solid->pos);
gl_bindCamera(&player_cam);
player_setFlag(PLAYER_DESTROYED);
player_timer = SDL_GetTicks() + 2000;
}

View File

@ -6,6 +6,7 @@
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
#define PLAYER_AFTERBURNER (1<<3) // Player is burning it up.
#define PLAYER_DESTROYED (1<<9) // Player goes BOOM!
#define PLAYER_FACE (1<<10) // Player is facing target.
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.

View File

@ -649,8 +649,12 @@ void space_render(double dt) {
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0);
t = SDL_GetTicks();
if(!player_isFlag(PLAYER_DESTROYED) &&
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
timer = player->ptimer - HYPERSPACE_STARS_BLUR;
if(pilot_isFlag(player, PILOT_HYPERSPACE) && !paused && (timer < t)) {
// Fancy hyperspace effects.
glShadeModel(GL_SMOOTH);
@ -677,8 +681,10 @@ void space_render(double dt) {
for(i = 0; i < nstars; i++) {
if(!paused && !toolkit) {
// Update position.
if(!player_isFlag(PLAYER_DESTROYED)) {
stars[i].x -= VX(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
stars[i].y -= VY(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
}
// Scroll those stars bitch!
if(stars[i].x > gl_screen.w + STAR_BUF) stars[i].x = -STAR_BUF;
else if(stars[i].x < -STAR_BUF) stars[i].x = gl_screen.w + STAR_BUF;