[Add] Added faction metatable to Lua API.

This commit is contained in:
Allanis 2013-12-16 23:43:31 +00:00
parent 751bbbefe8
commit 571b801a49
5 changed files with 402 additions and 10 deletions

358
src/llua_faction.c Normal file
View File

@ -0,0 +1,358 @@
/**
* @file llua_faction.c
*
* @breif Handle the Lua faction bindings.
*
* These bindings control the faction.
*/
#include "lauxlib.h"
#include "log.h"
#include "lephisto.h"
#include "llua.h"
#include "lluadef.h"
#include "faction.h"
#include "llua_faction.h"
static int factionL_createmetatable(lua_State* L, int readonly);
/* Faction metatable methods. */
static int factionL_eq(lua_State* L);
static int factionL_name(lua_State* L);
static int factionL_longname(lua_State* L);
static int factionL_areenemies(lua_State* L);
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 const luaL_reg faction_methods[] = {
{ "__eq", factionL_eq },
{ "name", factionL_name },
{ "longname", factionL_longname },
{ "areEnemeies", factionL_areenemies },
{ "areAllies", factionL_areallies },
{ "modPlayer", factionL_modplayer },
{ "modPlayerRaw", factionL_modplayerraw },
{ "playerStanding", factionL_playerstanding },
{ 0, 0 }
}; /**< Faction metatable methods. */
static const luaL_reg faction_methods_cond[] = {
{ "__eq", factionL_eq },
{ "name", factionL_name },
{ "longname", factionL_longname },
{ "areEnemeies", factionL_areenemies },
{ "areAllies", factionL_areallies },
{ "playerStanding", factionL_playerstanding },
{ 0, 0 }
};
/* Global faction functions. */
static int factionL_get(lua_State* L);
static const luaL_reg factionL_methods[] = {
{ "get", faction_get },
{ 0, 0 }
};
/**
* @fn int lua_loadFaction(lua_State* L, int readonly)
*
* @brief Load the faction library.
* @param L State to load faction library into.
* @return 0 on success.
*/
int lua_loadFaction(lua_State* L, int readonly) {
/* Register the faction functions. */
luaL_register(L, "faction", factionL_methods);
/* Register the metatables. */
factionL_createmetatable(L, readonly);
return 0;
}
/**
* @fn static int factionL_createmetatable(lua_State* L, int readonly)
*
* @brief Register the faction metatable.
* @param L Lua state to register metatable into.
* @param readonly Whether table should be readonly.
* @return 0 on success.
*/
static int factionL_createmetatable(lua_State* L, int readonly) {
/* Create metatable. */
luaL_newmetatable(L, FACTION_METATABLE);
/* Create the access table. */
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
/* Register the values. */
luaL_register(L, NULL, (readonly) ? faction_methods_cond : faction_methods);
return 0; /* No error. */
}
/**
* @defgroup FACTION Faction Lua bindings.
*
* @brief Lua bindings to deal with factions.
*
* Use with:
* @code
* faction.func(params)
* @endcode
*
* @{
*/
/**
* @fn static int factionL_get(lua_State* L)
*
* @brief faction get(string name)
*
* Get the faction based on its name.
* @param name Name of the faction to get.
* @return The faction matching name.
*/
static int factionL_get(lua_State* L) {
LuaFaction f;
char* name;
if(lua_isstring(L, 1)) name = (char*) lua_tostring(L, 1);
else LLUA_INVALID_PARAMETER();
f.f = faction_get(name);
lua_pushfaction(L, f);
return 1;
}
/**
* @}
*/
/**
* @defgroup META_FACTION Faction Metatable.
*
* @brief The faction metatable is a way to represent a faction in Lua.
*
* It allows all sorts of operators making it much more natural to use.
*
* To call members of the metatable always use:
*
* @code
* faction:function(param)
* @endcode
*
* @{
*/
/**
* @fn LuaFaction* lua_tofaction(lua_State* L, int ind)
*
* @brief Get faction at index.
* @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.
*/
LuaFaction* lua_tofaction(lua_State* L, int ind) {
if(lua_isuserdata(L, ind)) {
return (LuaFaction*) lua_touserdata(L, ind);
}
luaL_typerror(L, ind, FACTION_METATABLE);
return NULL;
}
/**
* @fn LuaFaction* lua_pushfaction(lua_State* L, LuaFaction faction)
*
* @brief Pushes a faction on the stack.
* @param L lua state to push faction into.
* @param faction Faction to push.
* @return Newly pushed faction.
*/
LuaFaction* lua_pushfaction(lua_State* L, LuaFaction faction) {
LuaFaction* f;
f = (LuaFaction*) lua_newuserdata(L, sizeof(LuaFaction));
*f = faction;
luaL_getmetatable(L, FACTION_METATABLE);
lua_setmetatable(L, -2);
return f;
}
/**
* @fn int lua_isfaction(lua_State* L, int ind)
*
* @brief Check to see if ind is a faction.
* @param L Lua state to check.
* @param ind Index position to check.
* @return 1 if ind is a faction.
*/
int lua_isfaction(lua_State* L, int ind) {
int ret;
if(lua_getmetatable(L, ind)==0)
return 0;
lua_getfield(L, LUA_REGISTRYINDEX, FACTION_METATABLE);
ret = 0;
if(lua_rawequal(L, -1, -2)) /* Does it have the correct mt? */
ret = 1;
lua_pop(L, 2); /* Remove both metatables. */
return ret;
}
/**
* @fn static int factionL_eq(lua_State* L)
*
* @brief bool __eq(faction comp)
*
* __eq (equality) metamethod for factions.
*
* You can use the '=' operator within Lua to compare factions with this.
* @param comp faction to compare against.
* @return true if both factions are the same.
*/
static int factionL_eq(lua_State* L) {
LuaFaction* a, *b;
a = lua_tofaction(L, 1);
b = lua_tofaction(L, 2);
lua_pushboolean(L, a->f == b->f);
return 1;
}
/**
* @fn static int factionL_name(lua_State* L)
*
* @brief string name(nil)
*
* Get the faction's name.
* @return The name of the faction.
*/
static int factionL_name(lua_State* L) {
LuaFaction* f;
f = lua_tofaction(L, 1);
lua_pushstring(L, faction_name(f->f));
return 1;
}
/**
* @fn static int factionL_longname(lua_State* L)
*
* @brief string longname(nil)
*
* Get the factions long name.
* @return The long name of the faction.
*/
static int factionL_longname(lua_State* L) {
LuaFaction* f;
f = lua_tofaction(L, 1);
lua_pushstring(L, faction_longname(f->f));
return 1;
}
/**
* @fn static int factionL_areenemeies(lua_State* L)
*
* @brief bool areenemies(faction f)
*
* Check to see if f is an enemy.
* @param f Faction to check if is an enemy.
* @return true if they are enemeies, false if they aren't.
*/
static int factionL_areenemies(lua_State* L) {
LuaFaction* f, *ff;
f = lua_tofaction(L, 1);
if(lua_isfaction(L, 2)) ff = lua_tofaction(L, 2);
else LLUA_INVALID_PARAMETER();
lua_pushboolean(L, areEnemies(f->f, ff->f));
return 1;
}
/**
* @fn static int factionL_areallies(lua_State* L)
*
* @brief bool areEnemies(faction f)
*
* Check to see if f is an enemy.
* @param f Faction to check if is an enemy.
* @return true if they are enemies, false if they aren't.
*/
static int factionL_areallies(lua_State* L) {
LuaFaction* f, *ff;
f = lua_tofaction(L, 1);
if(lua_isfaction(L, 2)) ff = lua_tofaction(L, 2);
else LLUA_INVALID_PARAMETER();
lua_pushboolean(L, areAllies(f->f, ff->f));
return 1;
}
/**
* @fn static int factionL_modplayer(lua_State* L)
*
* @brief modPlayer(number mod)
*
* Modifies the players standing with the faction.
* @param mod The modifier to modify faction by.
*/
static int factionL_modplayer(lua_State* L) {
LuaFaction* f;
int n;
f = lua_tofaction(L, 1);
if(lua_isnumber(L, 2)) n = lua_tonumber(L, 2);
else LLUA_INVALID_PARAMETER();
faction_modPlayer(f->f, n);
return 0;
}
/**
* @fn static int factionL_modplayerraw(lua_State* L)
*
* @brief modPlayerRaw(number mod)
*
* Modifies the players standing with the faction.
*
* Does not affect other faction standings.
* @param mod The modifier to modify faction by.
*/
static int factionL_modplayerraw(lua_State* L) {
LuaFaction* f;
int n;
f = lua_tofaction(L, 1);
if(lua_isnumber(L, 2)) n = lua_tonumber(L, 2);
else LLUA_INVALID_PARAMETER();
faction_modPlayerRaw(f->f, n);
return 0;
}
/**
* @fn static int factionL_playerstanding(lua_State* L)
*
* @brief number, string playerStanding(nil)
*
* Get the players standing with the faction.
* @return The value of the standing and the human readable string.
*/
static int factionL_playerstanding(lua_State* L) {
LuaFaction* f;
int n;
f = lua_tofaction(L, 1);
n = faction_getPlayer(f->f);
lua_pushnumber(L, n);
lua_pushstring(L, faction_getStanding(n));
return 1;
}
/**
* @}
*/

17
src/llua_faction.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#define FACTION_METATABLE "Faction"
/* Lua wrappers. */
typedef struct LuaFaction_s {
int f;
} LuaFaction;
/* Load the space library. */
int lua_loadFaction(lua_State* L, int readonly);
/* Faction operations. */
LuaFaction* lua_tofaction(lua_State* L, int ind);
LuaFaction* lua_pushfaction(lua_State* L, LuaFaction faction);
int lua_isfaction(lua_State* L, int ind);

View File

@ -8,8 +8,10 @@
#include "lauxlib.h"
#include "lephisto.h"
#include "llua_space.h"
#include "llua.h"
#include "lluadef.h"
#include "llua_space.h"
#include "llua_faction.h"
#include "rng.h"
#include "pilot.h"
#include "player.h"
@ -518,19 +520,25 @@ static int pilotL_setFaction(lua_State* L) {
LLUA_MIN_ARGS(2);
Pilot* p;
LuaPilot* lp;
LuaFaction* f;
int fid;
char* faction;
/* Parse parameters. */
lp = lua_topilot(L, 1);
if(lua_isstring(L, 2))
if(lua_isstring(L, 2)) {
faction = (char*)lua_tostring(L,2);
fid = faction_get(faction);
}
else if(lua_isfaction(L, 2)) {
f = lua_tofaction(L, 2);
fid = f->f;
}
else LLUA_INVALID_PARAMETER();
/* Get pilot/faction. */
p = pilot_get(lp->pilot);
if(p == NULL) return 0;
fid = faction_get(faction);
/* Set the new faction. */
p->faction = fid;

View File

@ -4,7 +4,9 @@
#include "lephisto.h"
#include "rng.h"
#include "land.h"
#include "llua.h"
#include "lluadef.h"
#include "llua_faction.h"
#include "map.h"
#include "llua_space.h"
@ -203,6 +205,7 @@ static int planetL_get(lua_State* L) {
char* rndplanet;
LuaPlanet planet;
LuaSystem sys;
LuaFaction* f;
rndplanet = NULL;
nplanets = 0;
@ -220,9 +223,9 @@ static int planetL_get(lua_State* L) {
}
/* Get a planet by faction */
else if(lua_isnumber(L, 1)) {
i = lua_tonumber(L, 1);
planets = space_getFactionPlanet(&nplanets, &i, 1);
else if(lua_isfaction(L, 1)) {
f = lua_tofaction(L, 1);
planets = space_getFactionPlanet(&nplanets, &f->f, 1);
}
/* Get a planet by name. */
@ -237,9 +240,9 @@ static int planetL_get(lua_State* 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);
f = lua_tofaction(L, -1);
factions[i++] = f->f;
lua_pop(L,1);
}
@ -292,8 +295,10 @@ static int planetL_name(lua_State* L) {
/* Get the planets faction. */
static int planetL_faction(lua_State* L) {
LuaPlanet* p;
LuaFaction f;
p = lua_toplanet(L, 1);
lua_pushstring(L, faction_name(p->p->faction));
f.f = p->p->faction;
lua_pushfaction(L, f);
return 1;
}

View File

@ -9,6 +9,7 @@
#include "llua.h"
#include "llua_space.h"
#include "llua_pilot.h"
#include "llua_faction.h"
#include "lluadef.h"
#include "hook.h"
#include "mission.h"
@ -187,6 +188,7 @@ int misn_loadLibs(lua_State* L) {
lua_loadPilot(L, 0);
lua_loadMusic(L, 0);
lua_loadDiff(L, 0);
lua_loadFaction(L, 0);
return 0;
}
@ -443,6 +445,7 @@ static int misn_setMarker(lua_State* L) {
static int misn_factions(lua_State* L) {
int i;
MissionData* dat;
LuaFaction f;
dat = cur_mission->data;
@ -450,7 +453,8 @@ static int misn_factions(lua_State* L) {
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. */
f.f = dat->avail.factions[i];
lua_pushfaction(L, f); /* Value. */
lua_rawset(L, -3); /* Store the value in the table. */
}
return 1;