From 88fed6f40ca618e33e473219208fd3f697983b53 Mon Sep 17 00:00:00 2001 From: Allanis Date: Sat, 16 Mar 2013 22:14:53 +0000 Subject: [PATCH] [Add] ai now controls ship's credits/loot. Some more API calls and cargo stuff. --- scripts/ai/merchant.lua | 4 +++ scripts/ai/militia.lua | 1 + src/ai.c | 48 ++++++++++++++++++++++++++++- src/board.c | 17 +++++------ src/pilot.c | 67 +++++++++++++++++++++++++++++++++++++++-- src/pilot.h | 14 +++++++++ src/player.c | 35 ++++++++++++++++++--- 7 files changed, 168 insertions(+), 18 deletions(-) diff --git a/scripts/ai/merchant.lua b/scripts/ai/merchant.lua index 501db19..db2fe90 100644 --- a/scripts/ai/merchant.lua +++ b/scripts/ai/merchant.lua @@ -37,6 +37,10 @@ function attacked(attacker) end end +function create() + ai.setcredits(ai.rnd(200, ai.shipprice()/100)) +end + -- Runs away. function runaway() target = ai.targetid() diff --git a/scripts/ai/militia.lua b/scripts/ai/militia.lua index 9facf9b..46a87b1 100644 --- a/scripts/ai/militia.lua +++ b/scripts/ai/militia.lua @@ -31,6 +31,7 @@ function attacked(attacker) end function create() + ai.setcredits(ai.rnd(1000, ai.shipprice()/200)) if ai.rnd(0, 2)==0 then ai.broadcast("This area is under militia survellance.") end diff --git a/src/ai.c b/src/ai.c index 23ae9b3..1a5b9ae 100644 --- a/src/ai.c +++ b/src/ai.c @@ -136,9 +136,14 @@ static int ai_hostile(lua_State* L); // hostile(number). // Timers. static int ai_settimer(lua_State* L); // settimer(number, number) static int ai_timeup(lua_State* L); // boolean timeup(number) -// Misc. +// Messages. static int ai_comm(lua_State* L); // comm(string) static int ai_broadcast(lua_State* L); // broadcast(string) +// Loot. +static int ai_credits(lua_State* L); // credits(number). +static int ai_cargo(lua_State* L); // cargo(name, quantity). +static int ai_shipprice(lua_State* L); // shipprice(). +// Random. static int ai_rng(lua_State* L); // rng(number, number) static const luaL_Reg ai_methods[] = { @@ -186,6 +191,11 @@ static const luaL_Reg ai_methods[] = { // Messages. { "comm", ai_comm }, { "broadcast", ai_broadcast }, + // Loot. + { "setcredits", ai_credits }, + { "setcargo", ai_cargo }, + { "shipprice", ai_shipprice }, + // Random. { "rnd", ai_rng }, { 0, 0 } // End. }; @@ -197,6 +207,11 @@ static double pilot_turn = 0.; static int pilot_flags = 0; static int pilot_target = 0; +// Ai status: 'Create' functions that can't be used elsewhere. +#define AI_STATUS_NORMAL 1 +#define AI_STATUS_CREATE 2 +static int ai_status = AI_STATUS_NORMAL; + // Destroy the AI part of the pilot. void ai_destroy(Pilot* p) { if(p->task) @@ -348,7 +363,9 @@ void ai_attacked(Pilot* attacked, const unsigned int attacker) { void ai_create(Pilot* pilot) { cur_pilot = pilot; L = cur_pilot->ai->L; + ai_status = AI_STATUS_CREATE; AI_LCALL("create"); + ai_status = AI_STATUS_NORMAL; } // ===================== @@ -864,6 +881,35 @@ static int ai_broadcast(lua_State* L) { return 0; } +// Set the pilots credits. +static int ai_credits(lua_State* L) { + MIN_ARGS(1); + if(ai_status != AI_STATUS_CREATE) return 0; + + if(lua_isnumber(L,1)) + cur_pilot->credits = (int)lua_tonumber(L,1); + + return 0; +} + +// Set the pilots cargo. +static int ai_cargo(lua_State* L) { + MIN_ARGS(2); + if(ai_status != AI_STATUS_CREATE) return 0; + + if(lua_isstring(L,1) && lua_isnumber(L,2)) + pilot_addCargo(cur_pilot, commodity_get(lua_tostring(L,1)), + (int)lua_tonumber(L,2)); + + return 0; +} + +// Get the pilot's ship value. +static int ai_shipprice(lua_State* L) { + lua_pushnumber(L, cur_pilot->ship->price); + return 1; +} + // Return a number between low and high. static int ai_rng(lua_State* L) { MIN_ARGS(2); diff --git a/src/board.c b/src/board.c index a337808..5366ebb 100644 --- a/src/board.c +++ b/src/board.c @@ -12,7 +12,6 @@ extern unsigned int player_target; -static unsigned int board_credits = 0; // Penniez on the ship. static unsigned int board_wid = 0; static void board_exit(char* str); @@ -57,9 +56,6 @@ void player_board(void) { pilot_setFlag(p, PILOT_BOARDED); player_message("Boarding ship %s", p->name); - // Calculate credits based on ship price. - board_credits = RNG(20*p->ship->price, 50*p->ship->price)/1000; - // Create the boarding window. board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT); @@ -67,7 +63,7 @@ void player_board(void) { 0, "txtCargo", &gl_smallFont, &cDConsole, "SCreds:\n" "Cargo:\n"); - credits2str(cred, board_credits, 2); + credits2str(cred, p->credits, 2); snprintf(str, 128, "%s\n" "%s\n", @@ -93,7 +89,7 @@ static void board_stealCreds(char* str) { p = pilot_get(player_target); - if(board_credits == 0) { + if(p->credits == 0) { // Can't steal from the poor. ;) player_message("The ship has no SCreds left"); return; @@ -105,8 +101,8 @@ static void board_stealCreds(char* str) { return; } - player_credits += board_credits; - board_credits = 0; + player_credits += p->credits; + p->credits = 0; board_update(); // Update the lack of credits. player_message("You manage to steal the ship's Scred"); } @@ -131,8 +127,11 @@ static void board_fail(void) { static void board_update(void) { char str[128]; char cred[10]; + Pilot* p; - credits2str(cred, board_credits, 2); + p = pilot_get(player_target); + + credits2str(cred, p->credits, 2); snprintf(str, 128, "%s\n" diff --git a/src/pilot.c b/src/pilot.c index fbfb588..efc649f 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -484,6 +484,63 @@ int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) { return 0; } +// Try to add quantity of cargo to pilot, return quantity actually added. +int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) { + int i, q; + + q = quantity; + for(i = 0; i < pilot->ncommodities; i++) + if(pilot->commodities[i].commodity == cargo) { + if(pilot->cargo_free < quantity) + q = pilot->cargo_free; + pilot->commodities[i].quantity += q; + pilot->cargo_free -= q; + return q; + } + + // Must add another one. + pilot->commodities = realloc(pilot->commodities, + sizeof(PilotCommodity) * pilot->ncommodities); + pilot->commodities[pilot->ncommodities].commodity = cargo; + if(pilot->cargo_free < quantity) + q = pilot->cargo_free; + pilot->commodities[pilot->ncommodities].quantity = q; + pilot->cargo_free -= q; + pilot->ncommodities++; + + return q; +} + +// Try to get rid of quantity cargo from pilot, +// return quantity actually removed. +int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) { + int i, q; + + q = quantity; + for(i = 0; i < pilot->ncommodities; i++) + if(pilot->commodities[i].commodity == cargo) { + if(quantity > pilot->commodities[i].quantity) { + q = pilot->commodities[i].quantity; + + // Remove cargo. + memmove(pilot->commodities+i, pilot->commodities+i+1, + sizeof(PilotCommodity)*(pilot->ncommodities-i)); + pilot->ncommodities--; + pilot->commodities = realloc(pilot->commodities, + sizeof(PilotCommodity)*pilot->ncommodities); + } else + pilot->commodities[i].quantity -= q; + + pilot->cargo_free += q; + return q; + } + + WARN("Trying to remove %d cargo '%s' from pilot '%s' when it doesn't exist", + quantity, cargo->name, pilot->name); + + return -1; +} + // ==Init pilot.=========================================== // ship : Ship pilot is flying. // name : Pilot's name, if NULL, ships name will be used. @@ -544,8 +601,11 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction, } } - // Sound source. - // Eh.... + // Cargo. + pilot->credits = 0; + pilot->commodities = NULL; + pilot->ncommodities = 0; + pilot->cargo_free = pilot->ship->cap_cargo; // Set flags and functions. if(flags & PILOT_PLAYER) { @@ -597,8 +657,9 @@ unsigned int pilot_create(Ship* ship, char* name, Faction* faction, // Frees and cleans up a pilot. static void pilot_free(Pilot* p) { solid_free(p->solid); - free(p->outfits); + if(p->outfits) free(p->outfits); free(p->name); + if(p->commodities) free(p->commodities); ai_destroy(p); free(p); } diff --git a/src/pilot.h b/src/pilot.h index b484f29..5a45cc9 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -5,6 +5,7 @@ #include "outfit.h" #include "faction.h" #include "sound.h" +#include "economy.h" #include "ship.h" #define PLAYER_ID 1 @@ -48,6 +49,11 @@ typedef struct PilotOutfit_ { unsigned int timer; // Used to store last used weapon time. } PilotOutfit; +typedef struct PilotCommodity_ { + Commodity* commodity; + int quantity; +} PilotCommodity; + // Primary pilot structure. typedef struct Pilot_ { unsigned int id; // Pilots id. @@ -75,6 +81,12 @@ typedef struct Pilot_ { PilotOutfit* secondary; // Secondary weapon. PilotOutfit* ammo; // Secondary ammo (if needed). + // Cargo. + int credits; // Moniez the pilot has. + PilotCommodity* commodities; // Commodity and quantity. + int ncommodities; + int cargo_free; + // Misc. uint32_t flags; // Used for AI etc. unsigned int ptimer; // Generic timer for internal pilot use. @@ -120,6 +132,8 @@ void pilot_setAmmo(Pilot* p); double pilot_face(Pilot* p, const float dir); int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity); int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity); +int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity); +int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity); // Creation. void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction, diff --git a/src/player.c b/src/player.c index ea19120..56ab199 100644 --- a/src/player.c +++ b/src/player.c @@ -481,15 +481,40 @@ void player_render(void) { } // Misc. - gl_print(NULL, gui.misc.x + 8, gui.misc.y - 8 - gl_defFont.h, + j = gui.misc.y - 8 - gl_smallFont.h; + gl_print(NULL, gui.misc.x + 8, j, &cConsole, "SCreds:"); credits2str(str, player_credits, 2); - i = gl_printWidth(&gl_smallFont, "%s", str); - gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 15 - i, - gui.misc.y - 8 - gl_defFont.h, NULL, "%s", str); - + i = gl_printWidth(&gl_smallFont, str); + gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 15 - i, j, + NULL, str); + + // Cargo and co. + if(player->ncommodities > 0) { + j -= gl_smallFont.h - 5; + gl_print(&gl_smallFont, + gui.misc.x + 8, j, &cConsole, "Cargo"); + + for(i = 0; i < MIN(player->ncommodities,3); i++) { + j -= gl_smallFont.h + 3; + gl_print(&gl_smallFont, + gui.misc.x + 13, j, + NULL, "%d %s", player->commodities[i].quantity, + player->commodities[i].commodity->name); + } + } + + j -= gl_smallFont.h + 5; + gl_print(&gl_smallFont, + gui.misc.x + 8, j, &cConsole, "Free:"); + + i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo); + gl_print(&gl_smallFont, + gui.misc.x + gui.misc.w - 8 - i, j, + NULL, "%d", player->cargo_free); + // Messages. x = gui.msg.x; y = gui.msg.y + (double)(gl_defFont.h * msg_max)*1.2;