diff --git a/scripts/ai/include/attack_generic.lua b/scripts/ai/include/attack_generic.lua index 1635e11..81873e8 100644 --- a/scripts/ai/include/attack_generic.lua +++ b/scripts/ai/include/attack_generic.lua @@ -31,6 +31,13 @@ end --]] function atk_g() target = ai.target() + + -- Check if is bribed by target. + if ai.isbribed(target) then + ai.poptask() + return + end + ai.hostile(target) -- Mark as hostile. -- Make sure pilot exists. diff --git a/src/ai.c b/src/ai.c index e62cd37..1311356 100644 --- a/src/ai.c +++ b/src/ai.c @@ -130,6 +130,7 @@ static int ai_getpos(lua_State* L); /* getpos(number) */ static int ai_minbrakedist(lua_State* L); /* Number minbrakedist() */ static int ai_cargofree(lua_State* L); /* Number cargofree(). */ static int ai_shipclass(lua_State* L); /* string shipclass(). */ +static int ai_isbribed(lua_State* L); /* bool isbribed(number). */ /* Boolean expressions. */ static int ai_exists(lua_State* L); /* boolean exists */ static int ai_ismaxvel(lua_State* L); /* Boolean ismaxvel() */ @@ -203,6 +204,7 @@ static const luaL_Reg ai_methods[] = { { "minbrakedist", ai_minbrakedist }, { "cargofree", ai_cargofree }, { "shipclass", ai_shipclass }, + { "isbribed", ai_isbribed }, /* Movement. */ { "nearestplanet", ai_getnearestplanet }, { "rndplanet", ai_getrndplanet }, @@ -862,11 +864,24 @@ static int ai_cargofree(lua_State* L) { return 1; } +/* Get the pilots ship class. */ static int ai_shipclass(lua_State* L) { lua_pushstring(L, ship_class(cur_pilot->ship)); return 1; } +/* Check to see if target has bribed pilot. */ +static int ai_isbribed(lua_State* L) { + unsigned int target; + + if(lua_isnumber(L, 1)) + target = (unsigned int) lua_tonumber(L, 1); + else LLUA_INVALID_PARAMETER(); + + lua_pushboolean(L, (target == PLAYER_ID) && pilot_isFlag(cur_pilot, PILOT_BRIBED)); + return 1; +} + static int ai_exists(lua_State* L) { Pilot* p; int i; diff --git a/src/comm.c b/src/comm.c index 1197f6d..0c03217 100644 --- a/src/comm.c +++ b/src/comm.c @@ -7,7 +7,9 @@ #include "lephisto.h" #include "log.h" #include "toolkit.h" +#include "dialogue.h" #include "pilot.h" +#include "rng.h" #include "comm.h" #define BUTTON_WIDTH 80 /**< Button width. */ @@ -15,6 +17,8 @@ static Pilot* comm_pilot = NULL; /**< Pilot currently talking to. */ +static void comm_bribe(unsigned int wid, char* str); + /** * @brief Open the communication dialogue with a pilot. * @param pilot Pilot to communicate with. @@ -76,9 +80,10 @@ int comm_open(unsigned int pilot) { window_addButton(wid, -20, 20 + BUTTON_HEIGHT + 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnGreet", "Greet", NULL); - if(faction_getPlayer(comm_pilot->faction) < 0) + if((faction_getPlayer(comm_pilot->faction) < 0) || + pilot_isFlag(comm_pilot, PILOT_HOSTILE)) window_addButton(wid, -20, 20 + 2*BUTTON_HEIGHT + 40, - BUTTON_WIDTH, BUTTON_HEIGHT, "btnBribe", "Bribe", NULL); + BUTTON_WIDTH, BUTTON_HEIGHT, "btnBribe", "Bribe", comm_bribe); else window_addButton(wid, -20, 20 + 2*BUTTON_HEIGHT + 40, BUTTON_WIDTH, BUTTON_HEIGHT, "btnRequest", "Request...", NULL); @@ -86,3 +91,30 @@ int comm_open(unsigned int pilot) { return 0; } +/** + * @brief Try to bribe the pilot. + * @param wid ID of window calling the function. + * @param str Unused. + */ +static void comm_bribe(unsigned int wid, char* str) { + (void)str; + int answer; + int price; + + price = (int) sqrt(comm_pilot->solid->mass) * (300.*RNGF() + 850.); + + answer = dialogue_YesNo("Bribe Pilot", "\"I'm gonna need at least %d credits \ + to not leave you as a hunk of floating debris.\"\n\npay %d Credits?", price, price); + + if(player->credits < price) { + dialogue_msg("Bribe Pilot", "You don't have enough credits for the bribary."); + } else { + player->credits -= price; + dialogue_msg("Bribe Pilot", "\"Pleasure to do business with you.\""); + pilot_setFlag(comm_pilot, PILOT_BRIBED); + /* Reopen window. */ + window_destroy(wid); + comm_open(comm_pilot->id); + } +} + diff --git a/src/mission.h b/src/mission.h index 60c9ea3..85b5694 100644 --- a/src/mission.h +++ b/src/mission.h @@ -11,9 +11,9 @@ #define MIS_AVAIL_COMMODITY 6 /**< Mission is available at commodity exchange. */ /* Flags. */ -#define mis_isFlag(m,f) ((m)->flags & (f)) -#define mis_setFlag(m,f) ((m)->flags |= (f)) -#define mis_rmFlag(m,f) ((m)->flags ^= (f)) +#define mis_isFlag(m,f) ((m)->flags & (f)) +#define mis_setFlag(m,f) ((m)->flags |= (f)) +#define mis_rmFlag(m,f) ((m)->flags &= ~(f)) #define MISSION_UNIQUE 1 /* Unique missions can't be repeated. */ diff --git a/src/pilot.c b/src/pilot.c index f4806ab..4ddb2c5 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -132,7 +132,11 @@ unsigned int pilot_getNearestEnemy(const Pilot* p) { int i; double d, td; - for(tp = 0, d = 0., i = 0; i < pilot_nstack; i++) + for(tp = 0, d = 0., i = 0; i < pilot_nstack; i++) { + /* Must not be bribed. */ + if((pilot_stack[i]->id == PLAYER_ID) && pilot_isFlag(p, PILOT_BRIBED)) + continue; + if(areEnemies(p->faction, pilot_stack[i]->faction) || ((pilot_stack[i]->id == PLAYER_ID) && (pilot_isFlag(p, PILOT_HOSTILE)))) { td = vect_dist(&pilot_stack[i]->solid->pos, &p->solid->pos); @@ -141,6 +145,7 @@ unsigned int pilot_getNearestEnemy(const Pilot* p) { tp = pilot_stack[i]->id; } } + } return tp; }