/** * @brief Checks to see if a faction has presence in a system. * * This checks to see if the faction has a possibility of having any ships at all * be randomly generated in the system. * * @usage if sys:hasPresence( "Empire" ) then -- Checks to see if Empire has ships in the system * @usage if sys:hasPresence( faction.get("Pirate") ) then -- Checks to see if the Pirate has ships in the system * * @luaparam s System to check to see if has presence of a certain faction. * @luaparam f Faction or name of faction to check to see if has presence in the system. * @luareturn true If faction has presence in the system, false otherwise. * @luafunc hasPresence( s, f ) */ static int systemL_hasPresence( lua_State *L ) { LuaFaction *lf; StarSystem *s; int fct; int i, found; s = luaL_validsystem(L,1); /* Get the second parameter. */ if (lua_isstring(L,2)) { fct = faction_get( lua_tostring(L,2) ); } else if (lua_isfaction(L,2)) { lf = lua_tofaction(L,2); fct = lf->f; } else NLUA_INVALID_PARAMETER(L); /* Try to find a fleet of the faction. */ found = 0; for (i=0; i<s->npresence; i++) { if (s->presence[i].faction == fct) { found = 1; break; } } lua_pushboolean(L, found); return 1; }
/** * @brief Sets the pilot's faction. * * @usage p:setFaction( "Empire" ) * @usage p:setFaction( faction.get( "Dvaered" ) ) * * @luaparam p Pilot to change faction of. * @luaparam faction Faction to set by name or faction. * @luafunc setFaction( faction ) */ static int pilotL_setFaction( lua_State *L ) { Pilot *p; LuaPilot *lp; LuaFaction *f; int fid; const char *faction; /* Parse parameters. */ lp = luaL_checkpilot(L,1); if (lua_isstring(L,2)) { faction = lua_tostring(L,2); fid = faction_get(faction); } else if (lua_isfaction(L,2)) { f = lua_tofaction(L,2); fid = f->f; } else NLUA_INVALID_PARAMETER(); /* Get pilot/faction. */ p = pilot_get(lp->pilot); if (p==NULL) { NLUA_ERROR(L,"Pilot is invalid."); return 0; } /* Set the new faction. */ p->faction = fid; return 0; }
/** * @brief Gets the pilots available in the system by a certain criteria. * * @usage p = pilot.get() -- Gets all the pilots * @usage p = pilot.get( { faction.get("Empire") } ) -- Only gets empire pilots. * * @luaparam f If f is a table of factions, it will only get pilots matching those factions. Otherwise it gets all the pilots. * @luareturn A table containing the pilots. * @luafunc get( f ) */ 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 { /* Now put all the matching pilots in a table. */ lua_newtable(L); k = 1; for (i=0; i<pilot_nstack; i++) { if (!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. */ } } } return 1; }
/** * @brief Gets the presence in the system. * * Possible parameters are besides a faction:<br/> * - "all": Gets the sum of all the presences.<br /> * - "friendly": Gets the sum of all the friendly presences.<br /> * - "hostile": Gets the sum of all the hostile presences.<br /> * - "neutral": Gets the sum of all the neutral presences.<br /> * * @usage p = sys:presence( f ) -- Gets the presence of a faction f * @usage p = sys:presence( "all" ) -- Gets the sum of all the presences * @usage if sys:presence("friendly") > sys:presence("hostile") then -- Checks to see if the system is dominantly friendly * * @luaparam s System to get presence level of. * @luareturn The presence level in sys (absolute value). * @luafunc presence( s ) */ static int systemL_presence( lua_State *L ) { StarSystem *sys; LuaFaction *lf; int *fct; int nfct; double presence; int i; const char *cmd; /* Get parameters. */ sys = luaL_validsystem(L, 1); /* Get the second parameter. */ if (lua_isstring(L, 2)) { /* A string command has been given. */ cmd = lua_tostring(L, 2); nfct = 0; /* Check the command string and get the appropriate faction group.*/ if(strcmp(cmd, "all") == 0) fct = faction_getGroup(&nfct, 0); else if(strcmp(cmd, "friendly") == 0) fct = faction_getGroup(&nfct, 1); else if(strcmp(cmd, "hostile") == 0) fct = faction_getGroup(&nfct, 3); else if(strcmp(cmd, "neutral") == 0) fct = faction_getGroup(&nfct, 2); else /* Invalid command string. */ NLUA_INVALID_PARAMETER(L); } else if (lua_isfaction(L, 2)) { /* A faction id was given. */ lf = lua_tofaction(L, 2); nfct = 1; fct = malloc(sizeof(int) * nfct); fct[0] = lf->f; } else NLUA_INVALID_PARAMETER(L); /* Add up the presence values. */ presence = 0; for(i=0; i<nfct; i++) presence += system_getPresence( sys, fct[i] ); /* Clean up after ourselves. */ free(fct); /* Push it back to Lua. */ lua_pushnumber(L, presence); return 1; }
/** * @brief Gets faction (or faction name) at index, raising an error if type isn't a valid faction. * * @param L Lua state to get faction from. * @param ind Index position to find the faction. * @return Faction found at the index in the state. */ int luaL_validfaction( lua_State *L, int ind ) { int id; if (lua_isfaction(L,ind)) id = lua_tofaction(L,ind)->f; else if (lua_isstring(L,ind)) id = faction_get( lua_tostring(L, ind) ); else { luaL_typerror(L, ind, FACTION_METATABLE); return 0; } if (id == -1) NLUA_ERROR(L,"Faction '%s' not found in stack.", lua_tostring(L,ind) ); return id; }
/** * @brief Gets a planet. * * Possible values of param: * - nil : Gets the current landed planet or nil if there is none. * - bool : Gets a random planet. * - faction : Gets random planet belonging to faction matching the number. * - string : Gets the planet by name. * - table : Gets random planet belonging to any of the factions in the * table. * * @usage p,s = planet.get( "Anecu" ) -- Gets planet by name * @usage p,s = planet.get( faction.get( "Empire" ) ) -- Gets random Empire planet * @usage p,s = planet.get(true) -- Gets completely random planet * @usage p,s = planet.get( { faction.get("Empire"), faction.get("Dvaered") } ) -- Random planet belonging to Empire or Dvaered * @luaparam param See description. * @luareturn Returns the planet and the system it belongs to. * @luafunc get( param ) */ static int planetL_get( lua_State *L ) { int i; int *factions; int nfactions; char **planets; int nplanets; const char *rndplanet; LuaPlanet planet; LuaSystem sys; LuaFaction *f; rndplanet = NULL; nplanets = 0; /* Get the landed planet */ if (lua_gettop(L) == 0) { if (land_planet != NULL) { planet.p = land_planet; lua_pushplanet(L,planet); sys.s = system_get( planet_getSystem(land_planet->name) ); lua_pushsystem(L,sys); return 2; } NLUA_ERROR(L,"Attempting to get landed planet when player not landed."); return 0; /* Not landed. */ } /* If boolean return random. */ else if (lua_isboolean(L,1)) { planet.p = planet_get( space_getRndPlanet() ); lua_pushplanet(L,planet); sys.s = system_get( planet_getSystem(land_planet->name) ); lua_pushsystem(L,sys); return 2; } /* Get a planet by faction */ else if (lua_isfaction(L,1)) { f = lua_tofaction(L,1); planets = space_getFactionPlanet( &nplanets, &f->f, 1 ); } /* Get a planet by name */ else if (lua_isstring(L,1)) { rndplanet = lua_tostring(L,1); } /* Get a planet from faction list */ else 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); } /* get the planets */ planets = space_getFactionPlanet( &nplanets, factions, nfactions ); free(factions); } else NLUA_INVALID_PARAMETER(); /* Bad Parameter */ /* No suitable planet found */ if ((rndplanet == NULL) && (nplanets == 0)) { free(planets); return 0; } /* Pick random planet */ else if (rndplanet == NULL) { rndplanet = planets[RNG(0,nplanets-1)]; free(planets); } /* Push the planet */ planet.p = planet_get(rndplanet); /* The real planet */ lua_pushplanet(L,planet); sys.s = system_get( planet_getSystem(rndplanet) ); lua_pushsystem(L,sys); return 2; }
static int planetL_getBackend( lua_State *L, int landable ) { int i; int *factions; int nfactions; char **planets; int nplanets; const char *rndplanet; LuaSystem luasys; LuaFaction f; Planet *pnt; StarSystem *sys; char *sysname; rndplanet = NULL; planets = NULL; nplanets = 0; /* If boolean return random. */ if (lua_isboolean(L,1)) { pnt = planet_get( space_getRndPlanet(landable, 0, NULL) ); lua_pushplanet(L,planet_index( pnt )); luasys = system_index( system_get( planet_getSystem(pnt->name) ) ); lua_pushsystem(L,luasys); return 2; } /* Get a planet by faction */ else if (lua_isfaction(L,1)) { f = lua_tofaction(L,1); planets = space_getFactionPlanet( &nplanets, &f, 1, landable ); } /* Get a planet by name */ else if (lua_isstring(L,1)) { rndplanet = lua_tostring(L,1); if (landable) { pnt = planet_get( rndplanet ); if (pnt == NULL) { NLUA_ERROR(L, _("Planet '%s' not found in stack"), rndplanet); return 0; } /* Check if can land. */ planet_updateLand( pnt ); if (!pnt->can_land) return 0; } } /* Get a planet from faction list */ else 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) { if (lua_isfaction(L, -1)) factions[i++] = lua_tofaction(L, -1); lua_pop(L,1); } /* get the planets */ planets = space_getFactionPlanet( &nplanets, factions, nfactions, landable ); free(factions); } else NLUA_INVALID_PARAMETER(L); /* Bad Parameter */ /* No suitable planet found */ if ((rndplanet == NULL) && ((planets == NULL) || nplanets == 0)) return 0; /* Pick random planet */ else if (rndplanet == NULL) { planets = (char**) arrayShuffle( (void**)planets, nplanets ); for (i=0; i<nplanets; i++) { if (landable) { /* Check landing. */ pnt = planet_get( planets[i] ); if (pnt == NULL) continue; planet_updateLand( pnt ); if (!pnt->can_land) continue; } rndplanet = planets[i]; break; } free(planets); } /* Push the planet */ pnt = planet_get(rndplanet); /* The real planet */ if (pnt == NULL) { NLUA_ERROR(L, _("Planet '%s' not found in stack"), rndplanet); return 0; } sysname = planet_getSystem(rndplanet); if (sysname == NULL) { NLUA_ERROR(L, _("Planet '%s' is not placed in a system"), rndplanet); return 0; } sys = system_get( sysname ); if (sys == NULL) { NLUA_ERROR(L, _("Planet '%s' can't find system '%s'"), rndplanet, sysname); return 0; } lua_pushplanet(L,planet_index( pnt )); luasys = system_index( sys ); lua_pushsystem(L,luasys); return 2; }
/** * @brief Persists the node on the top of the stack and pops it. * * @param L Lua state with node to persist on top of the stack. * @param writer XML Writer to use. * @param Are we parsing a node in a table? Avoids checking for extra __save. * @return 0 on success. */ static int nxml_persistDataNode( lua_State *L, xmlTextWriterPtr writer, int intable ) { int ret, b; LuaPlanet *p; LuaSystem *s; LuaFaction *f; LuaShip *sh; LuaTime *lt; Planet *pnt; StarSystem *ss; char buf[PATH_MAX]; const char *name, *str; int keynum; /* Default values. */ ret = 0; /* key, value */ /* Handle different types of keys. */ switch (lua_type(L, -2)) { case LUA_TSTRING: /* Can just tostring directly. */ name = lua_tostring(L,-2); /* Isn't a number key. */ keynum = 0; break; case LUA_TNUMBER: /* Can't tostring directly. */ lua_pushvalue(L,-2); name = lua_tostring(L,-1); lua_pop(L,1); /* Is a number key. */ keynum = 1; break; /* We only handle string or number keys, so ignore the rest. */ default: lua_pop(L,1); /* key */ return 0; } /* key, value */ /* Now handle the value. */ switch (lua_type(L, -1)) { /* Recursive for tables. */ case LUA_TTABLE: /* Check if should save -- only if not in table.. */ if (!intable) { lua_getfield(L, -1, "__save"); b = lua_toboolean(L,-1); lua_pop(L,1); if (!b) /* No need to save. */ break; } /* Start the table. */ xmlw_startElem(writer,"data"); xmlw_attr(writer,"type","table"); xmlw_attr(writer,"name","%s",name); if (keynum) xmlw_attr(writer,"keynum","1"); lua_pushnil(L); /* key, value, nil */ /* key, value, nil */ while (lua_next(L, -2) != 0) { /* key, value, key, value */ ret = nxml_persistDataNode( L, writer, 1 ); /* key, value, key */ } /* key, value */ xmlw_endElem(writer); /* "table" */ break; /* Normal number. */ case LUA_TNUMBER: nxml_saveData( writer, "number", name, lua_tostring(L,-1), keynum ); /* key, value */ break; /* Boolean is either 1 or 0. */ case LUA_TBOOLEAN: /* lua_tostring doesn't work on booleans. */ if (lua_toboolean(L,-1)) buf[0] = '1'; else buf[0] = '0'; buf[1] = '\0'; nxml_saveData( writer, "bool", name, buf, keynum ); /* key, value */ break; /* String is saved normally. */ case LUA_TSTRING: nxml_saveData( writer, "string", name, lua_tostring(L,-1), keynum ); /* key, value */ break; /* User data must be handled here. */ case LUA_TUSERDATA: if (lua_isplanet(L,-1)) { p = lua_toplanet(L,-1); pnt = planet_getIndex( p->id ); if (pnt != NULL) nxml_saveData( writer, "planet", name, pnt->name, keynum ); else WARN("Failed to save invalid planet."); /* key, value */ break; } else if (lua_issystem(L,-1)) { s = lua_tosystem(L,-1); ss = system_getIndex( s->id ); if (ss != NULL) nxml_saveData( writer, "system", name, ss->name, keynum ); else WARN("Failed to save invalid system."); /* key, value */ break; } else if (lua_isfaction(L,-1)) { f = lua_tofaction(L,-1); str = faction_name( f->f ); if (str == NULL) break; nxml_saveData( writer, "faction", name, str, keynum ); /* key, value */ break; } else if (lua_isship(L,-1)) { sh = lua_toship(L,-1); str = sh->ship->name; if (str == NULL) break; nxml_saveData( writer, "ship", name, str, keynum ); /* key, value */ break; } else if (lua_istime(L,-1)) { lt = lua_totime(L,-1); snprintf( buf, sizeof(buf), "%"PRId64, lt->t ); nxml_saveData( writer, "time", name, buf, keynum ); break; } /* Rest gets ignored, like functions, etc... */ default: /* key, value */ break; } lua_pop(L,1); /* key */ return ret; }