diff --git a/dat/missions/dvaered/dv_patrol.lua b/dat/missions/dvaered/dv_patrol.lua index 20a9944..3cc4477 100644 --- a/dat/missions/dvaered/dv_patrol.lua +++ b/dat/missions/dvaered/dv_patrol.lua @@ -1,5 +1,9 @@ --[[ -- Handles random Dvaered Patrol missions. +-- +-- Stage 1: Travelling. +-- Stage 2: Must clear enemies. +-- Stage 3: Continue travelling. --]] lang = lephisto.lang() @@ -20,6 +24,9 @@ else -- Default English. msg_msg = {} msg_title[1] = "Mission Success" msg_msg[1] = "You are greeted by a Dvaered official and recieve your payment of %d credits for your contribution in keeping Dvaered systems clean." + msg_msg[2] = "DV: Engage hostiles." + msg_msg[3] = "MISSION FAILED: Fled from the heat of battle." + msg_msg[5] = "DV: Patrol finished, return to base." end -- Create the mission. @@ -87,18 +94,58 @@ function jump() if sys == systems[visited+1] then visited = visited + 1 - -- Finished visiting systems. - if visited >= #systems then - misn_stage = 2 - misn.setDesc(string.format(misn_desc[3], base:name(), base_sys:name())) - misn.setMarker(base_sys) - - -- Need to visit more systems. - else - misn.setDesc(string.format(misn_desc[2], systems[visited+1]:name())) - misn.setMarker(systems[visited+1]) - end + -- Get the next goal. + setNextGoal() end + elseif misn_stage == 3 then + player.msg(msg_msg[3]) + misn.finish(false) + end +end + +-- Set the next goal. +function setNextGoal() + -- Check to see if there are enemies. + f = faction.get("Dvaered") + enemies = pilot.get(f:enemies()) + hostiles = #enemies + if hostiles > 0 then + misn_stage = 3 + + -- Set hooks. + for k,v in ipairs(enemies) do + hook.pilot(v, "disable", "death") + hook.pilot(v, "jump", "death") + end + + -- Update description and send messages. + player.msg(msg_msg[2]) + misn.setDesc(string.format(misn_desc[4], sys:name())) + + -- No hostiles, continue route. + else + -- Finished visiting systems. + if visited >= #systems then + misn_stage = 2 + player.msg(msg_msg[5]) + misn.setDesc(string.format(misn_desc[3], base:name(), base_sys:name())) + misn.setMarker(base_sys) + + -- Need to visit more systems. + else + player.msg(msg_msg[4]) + misn.setDesc(string.format(misn_desc[2], systems[visited+1]:name())) + misn.setMarker(systems[visited+1]) + end + end +end + +-- Pilot death hook. +function death() + hostiles = hostiles - 1 + if hostiles <= 0 then + misn_stage = 1 + setNextGoal() end end diff --git a/src/faction.c b/src/faction.c index 1545f8c..0049887 100644 --- a/src/faction.c +++ b/src/faction.c @@ -129,6 +129,36 @@ glTexture* faction_logoSmall(int f) { return faction_stack[f].logo_small; } +/** + * @brief Get the list of enemies of a faction. + * @param f faction to get enemies of. + * @param[out] Number of enemies. + * @return The enemies of the faction. + */ +int* faction_getEnemies(int f, int* n) { + if((f < 0) || (f >= faction_nstack)) { + WARN("Faction id '%d' is invalid.", f); + return NULL; + } + *n = faction_stack[f].nenemies; + return faction_stack[f].enemies; +} + +/** + * @brief Get the list of allies of a faction. + * @param f Faction to get allies of. + * @param[out] Number of allies. + * @return The allies of the faction. + */ +int* faction_getAllies(int f, int* n) { + if((f < 0) || (f >= faction_nstack)) { + WARN("Faction id '%d' is invalid.", f); + return NULL; + } + *n = faction_stack[f].nallies; + return faction_stack[f].allies; +} + /** * @fn static void faction_sanitizePlayer(Faction* faction) * diff --git a/src/faction.h b/src/faction.h index be50deb..60aa885 100644 --- a/src/faction.h +++ b/src/faction.h @@ -9,6 +9,8 @@ int faction_get(const char* name); char* faction_name(int f); char* faction_longname(int f); glTexture* faction_logoSmall(int f); +int* faction_getEnemies(int f, int* n); +int* faction_getAllies(int f, int* n); /* Player stuff. */ void faction_modPlayer(int f, double mod); diff --git a/src/llua_faction.c b/src/llua_faction.c index 9688f11..4c22532 100644 --- a/src/llua_faction.c +++ b/src/llua_faction.c @@ -26,6 +26,8 @@ static int factionL_areallies(lua_State* L); static int factionL_modplayer(lua_State* L); static int factionL_modplayerraw(lua_State* L); static int factionL_playerstanding(lua_State* L); +static int factionL_enemies(lua_State* L); +static int factionL_allies(lua_State* L); static const luaL_reg faction_methods[] = { { "__eq", factionL_eq }, { "__tostring", factionL_name }, @@ -36,6 +38,8 @@ static const luaL_reg faction_methods[] = { { "modPlayer", factionL_modplayer }, { "modPlayerRaw", factionL_modplayerraw }, { "playerStanding", factionL_playerstanding }, + { "enemies", factionL_enemies }, + { "allies", factionL_allies }, { 0, 0 } }; /**< Faction metatable methods. */ @@ -47,6 +51,8 @@ static const luaL_reg faction_methods_cond[] = { { "areEnemeies", factionL_areenemies }, { "areAllies", factionL_areallies }, { "playerStanding", factionL_playerstanding }, + { "enemies", factionL_enemies }, + { "allies", factionL_allies }, { 0, 0 } }; /**< Factions read only metatable methods. */ @@ -321,6 +327,56 @@ static int factionL_playerstanding(lua_State* L) { return 1; } +/** + * @brief Get the enemies of the faction. + * @return A table containing the enemies of the faction. + * @luafunc enemies() + */ +static int factionL_enemies(lua_State* L) { + int i, n; + int* factions; + LuaFaction*f, fe; + + f = lua_tofaction(L, 1); + + /* Push the enemies in a table. */ + lua_newtable(L); + factions = faction_getEnemies(f->f, &n); + for(i = 0; i < n; i++) { + lua_pushnumber(L, i+1); /* Key. */ + fe.f = factions[i]; + lua_pushfaction(L, fe); /* value */ + lua_rawset(L, -3); + } + + return 1; +} + +/** + * @brief Get the alies of the faction. + * @return A table containing the allies of the faction. + * @luafunc allies() + */ +static int factionL_allies(lua_State* L) { + int i, n; + int* factions; + LuaFaction* f, fa; + + f = lua_tofaction(L, 1); + + /* Push the enemeies in a table. */ + lua_newtable(L); + factions = faction_getAllies(f->f, &n); + for(i = 0; i < n; i++) { + lua_pushnumber(L, i+1); /* Key. */ + fa.f = factions[i]; + lua_pushfaction(L, fa); /* value. */ + lua_rawset(L, -3); + } + + return 1; +} + /** * @} */ diff --git a/src/llua_pilot.c b/src/llua_pilot.c index 0b56337..a44ffc6 100644 --- a/src/llua_pilot.c +++ b/src/llua_pilot.c @@ -17,18 +17,23 @@ #include "player.h" #include "llua_pilot.h" +/* From pilot.c */ +extern Pilot** pilot_stack; +extern int pilot_nstack; + static int pilotL_createmetatable(lua_State* L); /* Pilots. */ static int pilot_getPlayer(lua_State* L); static int pilot_addFleet(lua_State* L); static int pilot_clear(lua_State* L); static int pilot_toggleSpawn(lua_State* L); +static int pilot_getPilots(lua_State* L); static const luaL_reg pilot_methods[] = { { "player", pilot_getPlayer }, { "add", pilot_addFleet }, { "clear", pilot_clear }, { "toggleSpawn", pilot_toggleSpawn }, - { "clear", pilot_toggleSpawn }, + { "get", pilot_getPilots }, { 0, 0 } }; /**< Pilot lua methods. */ @@ -340,6 +345,54 @@ static int pilot_toggleSpawn(lua_State* L) { return 1; } +/** + * @ingroup PILOT + */ +static int pilot_getPilots(lua_State* L) { + int i, j, k; + int* factions; + int nfactions; + LuaFaction* f; + LuaPilot p; + + /* Check for belonging to faction. */ + if(lua_istable(L, 1)) { + /* get table length and preallocate. */ + nfactions = (int)lua_objlen(L, 1); + factions = malloc(sizeof(int) * nfactions); + /* Load up the table. */ + lua_pushnil(L); + i = 0; + while(lua_next(L, -2) != 0) { + f = lua_tofaction(L, -1); + factions[i++] = f->f; + lua_pop(L, 1); + } + + /* Now put all the matching pilots in a table. */ + lua_newtable(L); + k = 1; + for(i = 0; i < pilot_nstack; i++) { + for(j = 0; j < nfactions; j++) { + if((pilot_stack[i]->faction == factions[j]) && + !pilot_isDisabled(pilot_stack[i])) { + lua_pushnumber(L, k++); /* key. */ + p.pilot = pilot_stack[i]->id; + lua_pushpilot(L, p); /* Value. */ + lua_rawset(L, -3); /* table[key] = value */ + break; /* Continue to next pilot. */ + } + } + } + + /* Clean up. */ + free(factions); + } else + LLUA_INVALID_PARAMETER(); + + return 1; +} + /** * @brief Check to see if pilot and p are the same. * @luaparam p Pilot to compare against.