263 lines
6.6 KiB
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);
|
|
}
|
|
|