/** * @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; double 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; double 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; } /** * @} */