Lephisto/src/board.c

263 lines
6.6 KiB
C

#include "lephisto.h"
#include "log.h"
#include "pilot.h"
#include "player.h"
#include "toolkit.h"
#include "space.h"
#include "rng.h"
#include "economy.h"
#include "hook.h"
#include "board.h"
#define BOARDING_WIDTH 300 /**< Boarding window width. */
#define BOARDING_HEIGHT 200 /**< Boarding window height. */
#define BUTTON_WIDTH 50 /**< Boarding button width. */
#define BUTTON_HEIGHT 30 /**< Boarding button height. */
static void board_exit(unsigned int wdw, char* str);
static void board_stealCreds(unsigned int wdw, char* str);
static void board_stealCargo(unsigned int wdw, char* str);
static void board_stealFuel(unsigned int wdw, char* str);
static int board_fail(unsigned int wdw);
static void board_update(unsigned int wdw);
/**
* @fn void player_board(void)
*
* @brief Attempt to board the players target.
*
* Creates the window on success.
*/
void player_board(void) {
Pilot* p;
unsigned int wdw;
if(player->target == PLAYER_ID) {
player_message("You need a target to board first!");
return;
}
p = pilot_get(player->target);
if(!pilot_isDisabled(p)) {
player_message("You cannot board a ship that is not disabled!");
return;
}
else if(vect_dist(&player->solid->pos, &p->solid->pos) >
p->ship->gfx_space->sw * PILOT_SIZE_APROX) {
player_message("You are too far away to board your target.");
return;
}
else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
pow2(VY(player->solid->vel)-VY(p->solid->vel))) >
(double)pow2(MAX_HYPERSPACE_VEL)) {
player_message("You are going too fast to board the ship.");
return;
}
else if(pilot_isFlag(p, PILOT_BOARDED)) {
player_message("Your target cannot be boarded again.");
return;
}
/* Pilot will be boarded. */
pilot_setFlag(p, PILOT_BOARDED);
player_message("Boarding ship %s.", p->name);
/* Tweak some values. */
p->fuel = (double)RNG(100, p->fuel_max);
/* Create the boarding window. */
wdw = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
window_addText(wdw, 20, -30, 120, 60,
0, "txtCargo", &gl_smallFont, &cDConsole,
"SCreds:\n"
"Cargo:\n"
"Fuel:");
window_addButton(wdw, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnStealCredits", "Credits", board_stealCreds);
window_addButton(wdw, 20+BUTTON_WIDTH+20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnStealCargo", "Cargo", board_stealCargo);
window_addButton(wdw, 20+2*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnStealCargo", "Fuel", board_stealFuel);
window_addButton(wdw, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnBoardingClose", "Leave", board_exit);
board_update(wdw);
/* Run hook if needed. */
pilot_runHook(p, PILOT_HOOK_BOARD);
}
/**
* @brief Closes the boarding window.
* @param wdw Window triggered the function.
* @param str Unused.
*/
static void board_exit(unsigned int wdw, char* str) {
(void) str;
window_destroy(wdw);
}
/**
* @brief Attempt to steal the boarding ships credits.
* @param wdw Window triggered the function.
* @param str Unused.
*/
static void board_stealCreds(unsigned int wdw, char* str) {
(void)str;
Pilot* p;
p = pilot_get(player->target);
if(p->credits == 0) {
/* Can't steal from the poor. ;) */
player_message("The ship has no SCreds.");
return;
}
if(board_fail(wdw)) return;
player->credits += p->credits;
p->credits = 0;
board_update(wdw); /* Update the lack of credits. */
player_message("You manage to steal the ship's Scred.");
}
/**
* @brief Attempt to steal the boarded ships cargo.
* @param wdw Window triggering the function.
* @param str Unused.
*/
static void board_stealCargo(unsigned int wdw, char* str) {
(void)str;
int q;
Pilot* p;
p = pilot_get(player->target);
if(p->ncommodities==0) {
/* No cargo. */
player_message("The ship has no cargo.");
return;
}
else if(pilot_cargoFree(player) <= 0) {
player_message("You have no room for cargo.");
return;
}
if(board_fail(wdw)) return;
/** Steal as much as possible until full - @todo: Allow the player to choose. */
q = 1;
while((p->ncommodities > 0) && (q != 0)) {
q = pilot_addCargo(player, p->commodities[0].commodity,
p->commodities[0].quantity);
pilot_rmCargo(p, p->commodities[0].commodity, q);
}
board_update(wdw);
player_message("You manage to steal the ship's cargo.");
}
/**
* @brief
*/
static void board_stealFuel(unsigned int wdw, char* str) {
(void)str;
Pilot* p;
p = pilot_get(player->target);
if(player->fuel <= 0.) { /* Urgh.. They don't have any fuel. */
player_message("The ship has no fuel.");
return;
}
else if(player->fuel == player->fuel_max) {
player_message("Your ship is at maximum fuel capacity.");
return;
}
if(board_fail(wdw)) return;
/* Steal fuel. */
player->fuel += p->fuel;
/* Make sure doesn't overflow. */
if(player->fuel > player->fuel_max) {
p->fuel = player->fuel_max - player->fuel;
player->fuel = player->fuel_max;
}
board_update(wdw);
player_message("You manage to steal the ships fuel.");
}
/**
* @brief Check to see if the hijack attempt failed.
* @return 1 on failure to board. Otherwise 0.
*/
static int board_fail(unsigned int wdw) {
Pilot* p;
p = pilot_get(player->target);
/* Fail chance. */
if(RNGF() > (0.5 *
(10. + (double)p->ship->crew/10.+(double)player->ship->crew)))
return 0;
if(RNGF() < 0.4) { /* 40% of instadeath! */
/* 33% of instant death. */
p->armour = -1;
player_message("You have tripped the ship's self destruct mechanism!");
} else
/* You just got locked out!! */
player_message("The ship's security system locks %s out!",
(player->ship->crew > 0) ? "your crew" : "you");
board_exit(wdw, NULL);
return 1;
}
/**
* @brief Updates the boarding window.
*/
static void board_update(unsigned int wdw) {
int i, j;
char str[PATH_MAX];
char cred[10];
Pilot* p;
p = pilot_get(player->target);
j = 0;
/* Credits. */
credits2str(cred, p->credits, 2);
j += snprintf(&str[j], PATH_MAX-j, "%s\n", cred);
/* Commodities. */
if(p->ncommodities == 0)
j += snprintf(&str[j], PATH_MAX-j, "none\n");
else {
for(i = 0; i < p->ncommodities; i++)
j += snprintf(&str[j], PATH_MAX-j,
"%d %s\n",
p->commodities[i].quantity, p->commodities[i].commodity->name);
}
/* Fuel. */
if(p->fuel <= 0.)
j += snprintf(&str[j], PATH_MAX-j, "none\n");
else
j += snprintf(&str[j], PATH_MAX-j, "%.0f Units\n", p->fuel);
window_modifyText(wdw, "txtData", str);
}