diff --git a/dat/missions/cargo.lua b/dat/missions/cargo.lua index 183a69a..0cc9ccd 100644 --- a/dat/missions/cargo.lua +++ b/dat/missions/cargo.lua @@ -1,7 +1,15 @@ -- Create the mission. function create() -- Target destination. - planet = space.getPlanet(misn.factions()) + local i = 0 + repeat + planet = space.getPlanet(misn.factions()) + i = i + 1 + until planet ~= space.landName() or i > 10 + -- Protect agains inf loop. + if i > 10 then + misn.finish() + end -- Missions generic. misn_type = "Rush" @@ -18,11 +26,20 @@ function create() end function accept() - player.addCargo(carg_type, carg_mass) - tk.msg("Mission Accepted", - string.format("The workers load the %d tons of %s onto your ship.", - carg_mass, carg_type)) - hook.land("land") + if player.freeCargo() < carg_mass then + tk.msg("Ship is full", + string.format("Your ship is too full, You need to make room for \ + %d more tons if you want to be able to accept the mission.", + carg_mass-player.freeCargo())) + elseif misn.accept() then -- Able to accept the mission, hooks BREAK after accepting. + player.addCargo(carg_type, carg_mass) + tk.msg("Mission Accepted", + string.format("The workers load the %d tons of %s onto your ship.", + carg_mass, carg_type)) + hook.land("land"); -- Only hook after accepting. + else + tk.msg("Too many missions", "You have too many active missions.") + end end function land() diff --git a/src/misn_lua.c b/src/misn_lua.c index 1bc3ea6..7cbae32 100644 --- a/src/misn_lua.c +++ b/src/misn_lua.c @@ -27,12 +27,14 @@ static int misn_setTitle(lua_State* L); static int misn_setDesc(lua_State* L); static int misn_setReward(lua_State* L); static int misn_factions(lua_State* L); +static int misn_accept(lua_State* L); static int misn_finish(lua_State* L); static const luaL_Reg misn_methods[] = { { "setTitle", misn_setTitle }, { "setDesc", misn_setDesc }, { "setReward", misn_setReward }, { "factions", misn_factions }, + { "accept", misn_accept }, { "finish", misn_finish }, { 0, 0 } }; @@ -154,9 +156,38 @@ static int misn_setReward(lua_State* L) { } static int misn_factions(lua_State* L) { - (void) L; - // TODO: proper misn.factions() implementation. - return 0; + int i; + MissionData* dat; + + dat = cur_mission->data; + + lua_newtable(L); + for(i = 0; i < dat->avail.nfactions; i++) { + lua_pushnumber(L, i+1); // Index, starts with 1. + lua_pushnumber(L, dat->avail.factions[i]); // Value. + lua_rawset(L, -3); // Store the value in the table. + } + return 1; +} + +static int misn_accept(lua_State* L) { + int i, ret; + + ret = 0; + + // Find the last mission. + //for(i = 0; i < MISSION_MAX; i++) + //if(player_missions[i].data == NULL) break; + + // No missions left. + if(i >= MISSION_MAX) ret = 1; + else { + memcpy(&player_missions[i], cur_mission, sizeof(Mission)); + memset(cur_mission, 0, sizeof(Mission)); + cur_mission = &player_missions[i]; + } + lua_pushboolean(L, !ret); // We'll convert C style return to lua. + return 1; } static int misn_finish(lua_State* L) { @@ -169,9 +200,46 @@ static int misn_finish(lua_State* L) { } static int space_getPlanet(lua_State* L) { - // TODO: Proper getPlanet implementation. - lua_pushstring(L, "KonoSphere"); - return 1; + int i; + int *factions; + int nfactions; + char** planets; + int nplanets; + char* rndplanet; + + if(lua_gettop(L) == 0) { + // Get random planet. + } + else if(lua_istable(L, -1)) { + // Get planet of faction in table. + + // Load up the table. + lua_pushnil(L); + nfactions = (int) lua_gettop(L); + factions = malloc(sizeof(int) * nfactions); + i = 0; + while(lua_next(L, -2) != 0) { + factions[i++] = (int) lua_tonumber(L, -1); + lua_pop(L, 1); + } + + // Get the planets. + planets = space_getFactionPlanet(&nplanets, factions, nfactions); + free(factions); + + // Choose random planet. + if(nplanets == 0) { + // No suitable planets. + free(planets); + return 0;; + } + rndplanet = planets[RNG(0, nplanets)]; + free(planets); + + lua_pushstring(L, rndplanet); + return 1; + } + return 0; // Nothing good passed. } static int space_landName(lua_State* L) { diff --git a/src/mission.c b/src/mission.c index f731122..cc04c18 100644 --- a/src/mission.c +++ b/src/mission.c @@ -60,7 +60,8 @@ static int mission_init(Mission* mission, MissionData* misn) { ERR("Unable to create a new lua state."); return -1; } - + + luaopen_base(mission->L); // Can be useful. luaopen_string(mission->L); // string.format can be very useful. misn_loadLibs(mission->L); // Load our custom libraries. @@ -80,23 +81,8 @@ static int mission_init(Mission* mission, MissionData* misn) { return mission->id; } -// Accept mission, used basically for mission computers. void mission_accept(Mission* mission) { - int i; - - // Find last mission. - for(i = 0; i < MISSION_MAX; i++) - if(player_missions[i].data == NULL) break; - - // No missions left. - if(i >= MISSION_MAX) return; - - // Copy it over. - memcpy(&player_missions[i], mission, sizeof(Mission)); - memset(mission, 0, sizeof(Mission)); - - // Run the accept commandz. - misn_run(&player_missions[i], "accept"); + misn_run(mission, "accept"); } // Clean up a mission. diff --git a/src/mission.h b/src/mission.h index 92a1331..5083a78 100644 --- a/src/mission.h +++ b/src/mission.h @@ -53,7 +53,7 @@ typedef struct Mission_ { } Mission; #define MISSION_MAX 6 // No sense in the player having unlimited missions.. -extern Mission player_mission[MISSION_MAX]; +extern Mission player_missions[MISSION_MAX]; // For mission computer. Mission* missions_computer(int* n, int faction, char* planet, char* system); diff --git a/src/rng.h b/src/rng.h index 212e4eb..eea770a 100644 --- a/src/rng.h +++ b/src/rng.h @@ -1,6 +1,6 @@ #pragma once -#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * randfp())) +#define RNG(L,H) ((int)L + (int)((double)(H-L) * randfp())) // L <= RNG <= H #define RNGF() (randfp()) void rng_init(void); diff --git a/src/space.c b/src/space.c index f64b2ed..a281ee7 100644 --- a/src/space.c +++ b/src/space.c @@ -193,6 +193,38 @@ int space_hyperspace(Pilot* p) { return 0; } +// Return the name of all the planets that belong to factions. +char** space_getFactionPlanet(int* nplanets, int* factions, int nfactions) { + int i, j, k; + Planet* planet; + char** tmp; + int ntmp; + int mtmp; + + ntmp = 0; + mtmp = 25; + tmp = malloc(sizeof(char*) * mtmp); + + for(i = 0; i < systems_nstack; i++) + for(j = 0; j < systems_stack[i].nplanets; j++) { + planet = &systems_stack[i].planets[j]; + for(k = 0; k < nfactions; k++) + if((faction_isFaction(factions[k]) && + (planet->faction == factions[k])) || + (faction_isAlliance(factions[k]) && + faction_ofAlliance(planet->faction, factions[k]))) { + ntmp++; + if(ntmp > mtmp) { + mtmp += 25; + tmp = realloc(tmp, sizeof(char*) * mtmp); + } + tmp[ntmp-1] = planet->name; + } + } + (*nplanets) = ntmp; + return tmp; +} + // Basically used for spawning fleets. void space_update(const double dt) { unsigned int t; diff --git a/src/space.h b/src/space.h index 6d77eba..eb7c38b 100644 --- a/src/space.h +++ b/src/space.h @@ -108,5 +108,6 @@ void space_update(const double dt); // Misc. int space_canHyperspace(Pilot* p); int space_hyperspace(Pilot* p); +char** space_getFactionPlanet(int* nplanets, int* factions, int nfactions); extern char* stardate;