[Add] You can now use lua as conditions for missions.
This commit is contained in:
parent
848a5e120d
commit
273607eda0
@ -32,7 +32,7 @@
|
||||
<mission name = "Empire Shipping">
|
||||
<lua>es_cargo</lua>
|
||||
<avail>
|
||||
<req>es_cargo</req>
|
||||
<cond>var.peek("es_cargo") == true</cond>
|
||||
<chance>350</chance>
|
||||
<location>Computer</location>
|
||||
<alliance>Empire United</alliance>
|
||||
|
@ -3,7 +3,7 @@ if lang == "es" then
|
||||
-- Not translated atm.
|
||||
else -- Default english.
|
||||
misn_title = "Collective Scout"
|
||||
misn_reward = ""
|
||||
misn_reward = "None"
|
||||
misn_desc = {}
|
||||
misn_desc[1] = "Find a scout near %s."
|
||||
misn_desc[2] = "Travel back to %s in %s."
|
||||
|
@ -94,6 +94,12 @@ static const luaL_reg var_methods[] = {
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
// Only conditional.
|
||||
static const luaL_reg var_cond_methods[] = {
|
||||
{ "peek", var_peek },
|
||||
{0, 0 }
|
||||
};
|
||||
|
||||
// Space.
|
||||
static int space_getPlanet(lua_State* L);
|
||||
static int space_getSystem(lua_State* L);
|
||||
@ -200,6 +206,12 @@ int misn_loadLibs(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int misn_loadCondLibs(lua_State* L) {
|
||||
luaL_register(L, "time", time_methods);
|
||||
luaL_register(L, "var", var_cond_methods);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Run a mission function.
|
||||
//
|
||||
// -1 on error, 1 on misn.finish() call and 0 normally.
|
||||
|
@ -8,4 +8,5 @@ void var_cleanup(void);
|
||||
|
||||
// Load the libraries for a lua state.
|
||||
int misn_loadLibs(lua_State* L);
|
||||
int misn_loadCondLibs(lua_State* L); // Safe read only stuff.
|
||||
|
||||
|
@ -38,9 +38,10 @@ extern int misn_run(Mission* misn, char* func);
|
||||
|
||||
// Static.
|
||||
static unsigned int mission_genID(void);
|
||||
static int mission_init(Mission* mission, MissionData* misn);
|
||||
static int mission_init(Mission* mission, MissionData* misn, int load);
|
||||
static void mission_freeData(MissionData* mission);
|
||||
static int mission_alreadyRunning(MissionData* misn);
|
||||
static int mission_meetCond(MissionData* misn);
|
||||
static int mission_meetReq(int mission, int faction, char* planet, char* system);
|
||||
static int mission_matchFaction(MissionData* misn, int faction);
|
||||
static int mission_location(char* loc);
|
||||
@ -80,15 +81,16 @@ MissionData* mission_get(int id) {
|
||||
}
|
||||
|
||||
// Initialize a mission.
|
||||
static int mission_init(Mission* mission, MissionData* misn) {
|
||||
static int mission_init(Mission* mission, MissionData* misn, int load) {
|
||||
char* buf;
|
||||
uint32_t bufsize;
|
||||
|
||||
if(misn != NULL) {
|
||||
// Don't set the data either.
|
||||
if(load != 0)
|
||||
mission->id = 0;
|
||||
else
|
||||
mission->id = mission_genID();
|
||||
|
||||
mission->data = misn;
|
||||
}
|
||||
|
||||
// Sane defaults.
|
||||
mission->title = NULL;
|
||||
@ -108,9 +110,6 @@ static int mission_init(Mission* mission, MissionData* misn) {
|
||||
luaopen_string(mission->L); // string.format can be very useful.
|
||||
misn_loadLibs(mission->L); // Load our custom libraries.
|
||||
|
||||
// Don't load it with data.
|
||||
if(misn != NULL) {
|
||||
// Load the file.
|
||||
buf = pack_readfile(DATA, misn->lua, &bufsize);
|
||||
if(luaL_dobuffer(mission->L, buf, bufsize, misn->lua) != 0) {
|
||||
ERR("Error loading mission file: %s", misn->lua);
|
||||
@ -118,10 +117,10 @@ static int mission_init(Mission* mission, MissionData* misn) {
|
||||
WARN("Most likely Lua file has improper syntax, please check");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
|
||||
// Run create function.
|
||||
if(load == 0) // Never run when loading.
|
||||
misn_run(mission, "create");
|
||||
|
||||
return mission->id;
|
||||
@ -145,6 +144,60 @@ static int mission_alreadyRunning(MissionData* misn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Is the lua condition for misn met?
|
||||
static lua_State* mission_cond_L = NULL;
|
||||
static int mission_meetCond(MissionData* misn) {
|
||||
int ret;
|
||||
char buf[256];
|
||||
|
||||
if(mission_cond_L == NULL) {
|
||||
// Must create the conditional environment.
|
||||
mission_cond_L = luaL_newstate();
|
||||
misn_loadCondLibs(mission_cond_L);
|
||||
}
|
||||
|
||||
snprintf(buf, 256, "return %s", misn->avail.cond);
|
||||
ret = luaL_loadstring(mission_cond_L, buf);
|
||||
|
||||
switch(ret) {
|
||||
case LUA_ERRSYNTAX:
|
||||
WARN("Missions '%s' Lua Conditional syntax error", misn->name);
|
||||
return 0;
|
||||
case LUA_ERRMEM:
|
||||
WARN("Mission '%s' Lua Conditional ran out of memory", misn->name);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = lua_pcall(mission_cond_L, 0, 1, 0);
|
||||
|
||||
switch(ret) {
|
||||
case LUA_ERRRUN:
|
||||
WARN("Mission '%s' Lua Conditional had a runtime error: %s",
|
||||
misn->name, lua_tostring(mission_cond_L, -1));
|
||||
return 0;
|
||||
case LUA_ERRMEM:
|
||||
WARN("Mission '%s' Lua Conditional ran out of memory", misn->name);
|
||||
return 0;
|
||||
case LUA_ERRERR:
|
||||
WARN("Mission '%s' Lua Conditional had an error while handling error function",
|
||||
misn->name);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(lua_isboolean(mission_cond_L, -1)) {
|
||||
if(lua_toboolean(mission_cond_L, -1))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
WARN("Mission '%s' Conditional Lua didn't return a boolean", misn->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Does the mission meet the minimum requirements?
|
||||
static int mission_meetReq(int mission, int faction, char* planet, char* system) {
|
||||
MissionData* misn;
|
||||
@ -162,8 +215,8 @@ static int mission_meetReq(int mission, int faction, char* planet, char* system)
|
||||
mission_alreadyRunning(misn)))
|
||||
return 0;
|
||||
|
||||
if((misn->avail.req != NULL) && // Mission doesn't meet the requirement.
|
||||
!var_checkflag(misn->avail.req))
|
||||
if((misn->avail.cond != NULL) && // Mission doesn't meet the requirement.
|
||||
!mission_meetCond(misn))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@ -185,7 +238,7 @@ void missions_bar(int faction, char* planet, char* system) {
|
||||
chance = (double)(misn->avail.chance % 100)/100.;
|
||||
|
||||
if(RNGF() < chance) {
|
||||
mission_init(&mission, misn);
|
||||
mission_init(&mission, misn, 0);
|
||||
mission_cleanup(&mission); // It better clean up for itself or we do it.
|
||||
}
|
||||
}
|
||||
@ -300,7 +353,7 @@ Mission* missions_computer(int* n, int faction, char* planet, char* system) {
|
||||
// Random chance of rep appearances.
|
||||
if(RNGF() < chance) {
|
||||
tmp = realloc(tmp, sizeof(Mission) * ++m);
|
||||
mission_init(&tmp[m-1], misn);
|
||||
mission_init(&tmp[m-1], misn, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,8 +426,8 @@ static MissionData* mission_parse(const xmlNodePtr parent) {
|
||||
tmp->avail.factions[tmp->avail.nfactions-1] =
|
||||
faction_get(xml_get(cur));
|
||||
}
|
||||
else if(xml_isNode(cur, "req"))
|
||||
tmp->avail.req = strdup(xml_get(cur));
|
||||
else if(xml_isNode(cur, "cond"))
|
||||
tmp->avail.cond = strdup(xml_get(cur));
|
||||
} while(xml_nextNode(cur));
|
||||
}
|
||||
} while(xml_nextNode(node));
|
||||
@ -438,6 +491,11 @@ void missions_free(void) {
|
||||
free(mission_stack);
|
||||
mission_stack = NULL;
|
||||
mission_nstack = 0;
|
||||
|
||||
if(mission_cond_L != NULL) {
|
||||
lua_close(mission_cond_L);
|
||||
mission_cond_L = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void missions_cleanup(void) {
|
||||
@ -590,7 +648,7 @@ static int missions_parseActive(xmlNodePtr parent) {
|
||||
|
||||
// Process the attributes to create the mission.
|
||||
xmlr_attr(node, "data", buf);
|
||||
mission_init(misn, mission_get(mission_getID(buf)));
|
||||
mission_init(misn, mission_get(mission_getID(buf)), 1);
|
||||
free(buf);
|
||||
|
||||
// This will orphan an identifier.
|
||||
|
@ -33,7 +33,7 @@ typedef struct MissionData_ {
|
||||
int* factions;
|
||||
int nfactions;
|
||||
|
||||
char* req; // Required variable.
|
||||
char* cond; // Conditional that must be met.
|
||||
} avail;
|
||||
|
||||
unsigned int flags; // Flags to store binary properties.
|
||||
|
Loading…
Reference in New Issue
Block a user