#include #include #include #include #include "lua.h" #include "lauxlib.h" #include "llua.h" #include "llua_space.h" #include "llua_pilot.h" #include "llua_faction.h" #include "lluadef.h" #include "hook.h" #include "mission.h" #include "log.h" #include "lephisto.h" #include "rng.h" #include "space.h" #include "toolkit.h" #include "land.h" #include "pilot.h" #include "player.h" #include "ltime.h" #include "xml.h" #include "music.h" #include "unidiff.h" #include "misn_lua.h" /* Similar to lua vars, but with less variety. */ #define MISN_VAR_NIL 0 #define MISN_VAR_NUM 1 #define MISN_VAR_BOOL 2 #define MISN_VAR_STR 3 typedef struct misn_var_ { char* name; char type; union { double num; char* str; int b; } d; } misn_var; /* Variable stack. */ static misn_var* var_stack = NULL; static int var_nstack = 0; static int var_mstack = 0; /* Current mission. */ static Mission* cur_mission = NULL; static int misn_delete = 0; /* If 1 delete current mission. */ /* Static. */ static int var_add(misn_var* var); static void var_free(misn_var* var); static unsigned int hook_generic(lua_State* L, char* stack); /* Extern. */ int misn_run(Mission* misn, char* func); int var_save(xmlTextWriterPtr writer); int var_load(xmlNodePtr parent); /* External. */ extern void mission_sysMark(void); /* -- Libraries. -- */ /* Mission. */ static int misn_setTitle(lua_State* L); static int misn_setDesc(lua_State* L); static int misn_setReward(lua_State* L); static int misn_setMarker(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 int misn_timerStart(lua_State* L); static int misn_timerStop(lua_State* L); static const luaL_reg misn_methods[] = { { "setTitle", misn_setTitle }, { "setDesc", misn_setDesc }, { "setReward", misn_setReward }, { "setMarker", misn_setMarker }, { "factions", misn_factions }, { "accept", misn_accept }, { "finish", misn_finish }, { "timerStart", misn_timerStart }, { "timerStop", misn_timerStop }, { 0, 0 } }; /* Var. */ static int var_peek(lua_State* L); static int var_pop(lua_State* L); static int var_push(lua_State* L); static const luaL_reg var_methods[] = { { "peek", var_peek }, { "pop", var_pop}, { "push", var_push}, {0, 0} }; /* Only conditional. */ static const luaL_reg var_cond_methods[] = { { "peek", var_peek }, {0, 0 } }; /* Player. */ static int player_getname(lua_State* L); static int player_shipname(lua_State* L); static int player_freeSpace(lua_State* L); static int player_addCargo(lua_State* L); static int player_rmCargo(lua_State* L); static int player_pay(lua_State* L); static int player_msg(lua_State* L); static int player_modFaction(lua_State* L); static int player_modFactionRaw(lua_State* L); static int player_getFaction(lua_State* L); static int player_getRating(lua_State* L); static int player_getPosition(lua_State* L); static int player_getPilot(lua_State* L); static const luaL_reg player_methods[] = { { "name", player_getname }, { "ship", player_shipname }, { "freeCargo", player_freeSpace }, { "addCargo", player_addCargo }, { "rmCargo", player_rmCargo }, { "pay", player_pay }, { "msg", player_msg }, { "modFaction", player_modFaction }, { "modFactionRaw", player_modFactionRaw }, { "getFaction", player_getFaction }, { "getRating", player_getRating }, { "pos", player_getPosition }, { "pilot", player_getPilot }, { 0, 0 } }; static const luaL_reg player_cond_methods[] = { { "name", player_getname }, { "ship", player_shipname }, { "getFaction", player_getFaction }, { "getRating", player_getRating }, { 0, 0 } }; /* Hooks. */ static int hook_land(lua_State* L); static int hook_takeoff(lua_State* L); static int hook_time(lua_State* L); static int hook_enter(lua_State* L); static int hook_pilot(lua_State* L); static const luaL_reg hook_methods[] = { { "land", hook_land }, { "takeoff", hook_takeoff }, { "time", hook_time }, { "enter", hook_enter }, { "pilot", hook_pilot }, { 0, 0 } }; /* Diffs. */ static int diff_applyL(lua_State* L); static int diff_removeL(lua_State* L); static int diff_isappliedL(lua_State* L); static const luaL_reg diff_methods[] = { { "apply", diff_applyL }, { "remove", diff_removeL }, { "isApplied", diff_isappliedL }, { 0, 0 } }; static const luaL_reg diff_cond_methods[] = { { "isApplied", diff_isappliedL }, { 0, 0 } }; /* Register all the libaries. */ int misn_loadLibs(lua_State* L) { lua_loadLephisto(L); lua_loadMisn(L); lua_loadVar(L, 0); lua_loadSpace(L, 0); lua_loadTime(L, 0); lua_loadPlayer(L, 0); lua_loadRnd(L); lua_loadTk(L); lua_loadHook(L); lua_loadPilot(L, 0); lua_loadMusic(L, 0); lua_loadDiff(L, 0); lua_loadFaction(L, 0); return 0; } int misn_loadCondLibs(lua_State* L) { lua_loadTime(L, 1); lua_loadSpace(L, 1); lua_loadVar(L, 1); lua_loadPlayer(L, 1); lua_loadDiff(L,1); return 0; } /* Individual libarary loading. */ int lua_loadMisn(lua_State* L) { luaL_register(L, "misn", misn_methods); return 0; } int lua_loadVar(lua_State* L, int readonly) { if(readonly == 0) luaL_register(L, "var", var_methods); else luaL_register(L, "var", var_cond_methods); return 0; } int lua_loadPlayer(lua_State* L, int readonly) { if(readonly == 0) luaL_register(L, "player", player_methods); else luaL_register(L, "player", player_cond_methods); return 0; } int lua_loadHook(lua_State* L) { luaL_register(L, "hook", hook_methods); return 0; } /** * @fn int lua_loadDiff(lua_State* L, int readonly) * * @brief Loads the diff Lua library. * @param L Lua State. * @param readonly Load read only functions. */ int lua_loadDiff(lua_State* L, int readonly) { if(readonly == 0) luaL_register(L, "diff", diff_methods); else luaL_register(L, "diff", diff_cond_methods); return 0; } /* * Run a mission function. * -1 on error, 1 on misn.finish() call and 0 normally. */ int misn_run(Mission* misn, char* func) { int i, ret; char* err; cur_mission = misn; misn_delete = 0; lua_getglobal(misn->L, func); if((ret = lua_pcall(misn->L, 0, 0, 0))) { /* Did an oops. */ err = (lua_isstring(misn->L, -1)) ? (char*) lua_tostring(misn->L, -1) : NULL; if(strcmp(err, "Mission Done")!=0) WARN("Mission '%s' -> '%s' : %s", cur_mission->data->name, func, (err) ? err : "Unknown Error"); else ret = 1; } /* Mission is finished. */ if(misn_delete) { mission_cleanup(cur_mission); for(i = 0; i < MISSION_MAX; i++) if(cur_mission == &player_missions[i]) { memmove(&player_missions[i], &player_missions[i+1], sizeof(Mission) * (MISSION_MAX-i-1)); break; } } cur_mission = NULL; return ret; } /* Save the mission variables. */ int var_save(xmlTextWriterPtr writer) { int i; xmlw_startElem(writer, "vars"); for(i = 0; i < var_nstack; i++) { xmlw_startElem(writer, "vars"); xmlw_attr(writer, "name", var_stack[i].name); switch(var_stack[i].type) { case MISN_VAR_NIL: xmlw_attr(writer, "type", "nil"); break; case MISN_VAR_NUM: xmlw_attr(writer, "type", "num"); xmlw_str(writer, "%d", var_stack[i].d.num); break; case MISN_VAR_BOOL: xmlw_attr(writer, "type", "bool"); xmlw_str(writer, "%d", var_stack[i].d.b); break; case MISN_VAR_STR: xmlw_attr(writer, "type", "str"); xmlw_str(writer, var_stack[i].d.str); break; } xmlw_endElem(writer); /* var. */ } xmlw_endElem(writer); /* vars. */ return 0; } /* Load the vars. */ int var_load(xmlNodePtr parent) { char* str; xmlNodePtr node, cur; misn_var var; var_cleanup(); node = parent->xmlChildrenNode; do { if(xml_isNode(node, "vars")) { cur = node->xmlChildrenNode; do { if(xml_isNode(cur, "var")) { xmlr_attr(cur, "name", var.name); xmlr_attr(cur, "type", str); if(strcmp(str, "nil")==0) var.type = MISN_VAR_NIL; else if(strcmp(str, "num")==0) { var.type = MISN_VAR_NUM; var.d.num = atoi(xml_get(cur)); } else if(strcmp(str, "bool")==0) { var.type = MISN_VAR_BOOL; var.d.b = atoi(xml_get(cur)); } else if(strcmp(str, "str")==0) { var.type = MISN_VAR_STR; var.d.str = atoi(xml_get(cur)); } else { /* Supeh error checking. */ WARN("Unknown var type '%s'", str); free(var.name); continue; } free(str); var_add(&var); } } while(xml_nextNode(cur)); } } while(xml_nextNode(node)); return 0; } /* Add a var to the stack, strings will be SHARED, don't free!!! */ static int var_add(misn_var* new_var) { int i; if(var_nstack+1 > var_mstack) { /* More memory. */ var_mstack += 64; /* Overkill much?? */ var_stack = realloc(var_stack, var_mstack * sizeof(misn_var)); } /* Check if already exists. */ for(i = 0; i < var_nstack; i++) if(strcmp(new_var->name, var_stack[i].name)==0) { var_free(&var_stack[i]); memcpy(&var_stack[i], new_var, sizeof(misn_var)); return 0; } memcpy(&var_stack[var_nstack], new_var, sizeof(misn_var)); var_nstack++; return 0; } /* -- Mission. -- */ static int misn_setTitle(lua_State* L) { LLUA_MIN_ARGS(1); if(lua_isstring(L, 1)) { if(cur_mission->title) /* Cleanup the old title. */ free(cur_mission->title); cur_mission->title = strdup((char*)lua_tostring(L, 1)); } return 0; } static int misn_setDesc(lua_State* L) { LLUA_MIN_ARGS(1); if(lua_isstring(L, 1)) { if(cur_mission->desc) /* Cleanup the old description. */ free(cur_mission->desc); cur_mission->desc = strdup((char*)lua_tostring(L, 1)); } return 0; } static int misn_setReward(lua_State* L) { LLUA_MIN_ARGS(1); if(lua_isstring(L, 1)) { if(cur_mission->reward != NULL) /* Cleanup old reward. */ /* Cleanup the old reward. */ free(cur_mission->reward); cur_mission->reward = strdup((char*)lua_tostring(L, 1)); } else LLUA_INVALID_PARAMETER(); return 0; } static int misn_setMarker(lua_State* L) { LuaSystem* sys; /* No parameter clears the marker. */ if(lua_gettop(L)==0) { if(cur_mission->sys_marker != NULL) free(cur_mission->sys_marker); mission_sysMark(); /* Clear the marker. */ } /* Passing in a Star System. */ if(lua_issystem(L, 1)) { sys = lua_tosystem(L, 1); cur_mission->sys_marker = strdup(sys->s->name); mission_sysMark(); /* Mark the system. */ } else LLUA_INVALID_PARAMETER(); return 0; } static int misn_factions(lua_State* L) { int i; MissionData* dat; LuaFaction f; dat = cur_mission->data; /* We'll push all the factions in table form. */ lua_newtable(L); for(i = 0; i < dat->avail.nfactions; i++) { lua_pushnumber(L, i+1); /* Index, starts with 1. */ f.f = dat->avail.factions[i]; lua_pushfaction(L, f); /* 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) { int b; if(lua_isboolean(L, 1)) b = lua_toboolean(L, 1); else { lua_pushstring(L, "Mission Done"); lua_error(L); /* THERE IS NO RETURN! */ return 0; } misn_delete = 1; if(b && mis_isFlag(cur_mission->data, MISSION_UNIQUE)) player_missionFinished(mission_getID(cur_mission->data->name)); lua_pushstring(L, "Mission Done"); lua_error(L); /* Should not return.. */ return 0; } /** * @fn static int misn_timerStart(lua_State* L) * * @brief number timerStart( string func, number delay ) * * Start a timer. * @param func Function to run when timer is up. * @param delay Milliseconds to wait for timer. * @return The timer being used. */ static int misn_timerStart(lua_State* L) { LLUA_MIN_ARGS(2); int i; char* func; double delay; /* Parse arguments. */ if(lua_isstring(L,1)) func = (char*)lua_tostring(L,1); else LLUA_INVALID_PARAMETER(); if(lua_isnumber(L,2)) delay = lua_tonumber(L,2); else LLUA_INVALID_PARAMETER(); /* Add timer. */ for(i = 0; i < MISSION_TIMER_MAX; i++) { if(cur_mission->timer[i] == 0.) { cur_mission->timer[i] = delay / 1000.; cur_mission->tfunc[i] = strdup(func); break; } } /* No timer found. */ if(i >= MISSION_TIMER_MAX) { return 0; } /* Return the timer id. */ lua_pushnumber(L, i); return 1; } /** * @fn static int misn_timerStop(lua_State* L) * * @brief timerStop(number t) * * Stop a timer previously started with timerStart(). * @param t Timer to stop. */ static int misn_timerStop(lua_State* L) { LLUA_MIN_ARGS(1); int t; /* Parse arguments. */ if(lua_isnumber(L,1)) t = (int)lua_tonumber(L,1); else LLUA_INVALID_PARAMETER(); /* Stop the timer. */ if(cur_mission->timer[t] != 0.) { cur_mission->timer[t] = 0.; if(cur_mission->tfunc[t] != NULL) { free(cur_mission->tfunc[t]); cur_mission->tfunc[t] = NULL; } } return 0; } /* -- Var. -- */ /* Check if a variable exists. */ int var_checkflag(char* str) { int i; for(i = 0; i < var_nstack; i++) if(strcmp(var_stack[i].name, str)==0) return 1; return 0; } static int var_peek(lua_State* L) { LLUA_MIN_ARGS(1); int i; char* str; if(lua_isstring(L, 1)) str = (char*) lua_tostring(L, 1); else { LLUA_DEBUG("Trying to peek a var with non-string name"); return 0; } for(i = 0; i < var_nstack; i++) if(strcmp(str, var_stack[i].name)==0) { switch(var_stack[i].type) { case MISN_VAR_NIL: lua_pushnil(L); break; case MISN_VAR_NUM: lua_pushnumber(L, var_stack[i].d.num); break; case MISN_VAR_BOOL: lua_pushboolean(L, var_stack[i].d.b); break; case MISN_VAR_STR: lua_pushstring(L, var_stack[i].d.str); break; } return 1; } lua_pushnil(L); return 1; } static int var_pop(lua_State* L) { LLUA_MIN_ARGS(1); int i; char* str; if(lua_isstring(L, 1)) str = (char*) lua_tostring(L, 1); else { LLUA_DEBUG("Trying to pop a var with non-string name"); return 0; } for(i = 0; i < var_nstack; i++) if(strcmp(str, var_stack[i].name)==0) { var_free(&var_stack[i]); memmove(&var_stack[i], &var_stack[i+1], sizeof(misn_var)*(var_nstack-i-1)); var_stack--; return 0; } LLUA_DEBUG("Var '%s' not found in stack", str); return 0; } static int var_push(lua_State* L) { LLUA_MIN_ARGS(2); char* str; misn_var var; if(lua_isstring(L, 1)) str = (char*) lua_tostring(L, 1); else { LLUA_DEBUG("Trying to push a var with non-string name"); return 0; } var.name = strdup(str); /* Store appropriate data. */ if(lua_isnil(L, 2)) var.type = MISN_VAR_NIL; else if(lua_isnumber(L, 2)) { var.type = MISN_VAR_NUM; var.d.num = (double)lua_tonumber(L, 2); } else if(lua_isboolean(L, 2)) { var.type = MISN_VAR_BOOL; var.d.b = lua_toboolean(L, 2); } else if(lua_isstring(L, 2)) { var.type = MISN_VAR_STR; var.d.str = strdup((char*)lua_tostring(L, 2)); } else { LLUA_DEBUG("Trying to push a var of invalid data type to stack"); return 0; } var_add(&var); return 0; } static void var_free(misn_var* var) { switch(var->type) { case MISN_VAR_STR: if(var->d.str != NULL) { free(var->d.str); var->d.str = NULL; } break; case MISN_VAR_NIL: case MISN_VAR_NUM: case MISN_VAR_BOOL: break; } if(var->name != NULL) { free(var->name); var->name = NULL; } } void var_cleanup(void) { int i; for(i = 0; i < var_nstack; i++) var_free(&var_stack[i]); if(var_stack != NULL) free(var_stack); var_stack = NULL; var_nstack = 0; var_mstack = 0; } /* -- Player. -- */ static int player_getname(lua_State* L) { lua_pushstring(L, player_name); return 1; } static int player_shipname(lua_State* L) { lua_pushstring(L, player->name); return 1; } static int player_freeSpace(lua_State* L) { lua_pushnumber(L, pilot_cargoFree(player)); return 1; } static int player_addCargo(lua_State* L) { Commodity* cargo; int quantity, ret; LLUA_MIN_ARGS(2); if(lua_isstring(L, 2)) cargo = commodity_get((char*) lua_tostring(L, 1)); else LLUA_INVALID_PARAMETER(); if(lua_isnumber(L, 2)) quantity = (int)lua_tonumber(L, 2); else LLUA_INVALID_PARAMETER(); ret = pilot_addMissionCargo(player, cargo, quantity); mission_linkCargo(cur_mission, ret); lua_pushnumber(L, ret); return 1; } static int player_rmCargo(lua_State* L) { int ret; unsigned int id; LLUA_MIN_ARGS(1); if(lua_isnumber(L, 1)) id = (unsigned int) lua_tonumber(L, 1); else LLUA_INVALID_PARAMETER(); ret = pilot_rmMissionCargo(player, id); mission_unlinkCargo(cur_mission, id); lua_pushboolean(L, !ret); return 1; } static int player_pay(lua_State* L) { int money; LLUA_MIN_ARGS(1); if(lua_isnumber(L, 1)) money = (int) lua_tonumber(L, 1); else LLUA_INVALID_PARAMETER(); player->credits += money; return 0; } static int player_msg(lua_State* L) { LLUA_MIN_ARGS(1); char* str; if(lua_isstring(L, -1)) str = (char*) lua_tostring(L, -1); else LLUA_INVALID_PARAMETER(); player_message(str); return 0; } static int player_modFaction(lua_State* L) { LLUA_MIN_ARGS(2); int f, mod; if(lua_isstring(L, 1)) f = faction_get(lua_tostring(L, 1)); else LLUA_INVALID_PARAMETER(); if(lua_isnumber(L, 2)) mod = (int)lua_tonumber(L, 2); else LLUA_INVALID_PARAMETER(); faction_modPlayer(f, mod); return 0; } static int player_modFactionRaw(lua_State* L) { LLUA_MIN_ARGS(2); int f, mod; if(lua_isstring(L, 1)) f = faction_get(lua_tostring(L,1)); else LLUA_INVALID_PARAMETER(); if(lua_isnumber(L,2)) mod = (int) lua_tonumber(L,2); else LLUA_INVALID_PARAMETER(); faction_modPlayerRaw(f, mod); return 0; } static int player_getFaction(lua_State* L) { LLUA_MIN_ARGS(1); int f; if(lua_isstring(L, 1)) f = faction_get(lua_tostring(L, 1)); else LLUA_INVALID_PARAMETER(); lua_pushnumber(L, faction_getPlayer(f)); return 1; } static int player_getRating(lua_State* L) { lua_pushnumber(L, player_crating); lua_pushstring(L, player_rating()); return 2; } /* -- HOOK -- */ static unsigned int hook_generic(lua_State* L, char* stack) { int i; char* func; LLUA_MIN_ARGS(1); /* Last parameter must be function to hook. */ if(lua_isstring(L, -1)) func = (char*)lua_tostring(L, -1); else LLUA_INVALID_PARAMETER(); /* Make sure mission is a player mission. */ for(i = 0; i < MISSION_MAX; i++) if(player_missions[i].id == cur_mission->id) break; if(i >= MISSION_MAX) { WARN("Mission not in stack trying to hook"); return 0; } return hook_add(cur_mission->id, func, stack); } static int hook_land(lua_State* L) { hook_generic(L, "land"); return 0; } static int hook_takeoff(lua_State* L) { hook_generic(L, "takeoff"); return 0; } static int hook_time(lua_State* L) { hook_generic(L, "time"); return 0; } static int hook_enter(lua_State* L) { hook_generic(L, "enter"); return 0; } /** * @fn static int player_getPosition(lua_State* L) * * @brief Vec2 getPos(nil) * * Get the players position. * @return The position of the player. */ static int player_getPosition(lua_State* L) { LuaVector v; vectcpy(&v.vec, &player->solid->pos); lua_pushvector(L, v); return 1; } /** * @fn static int player_getPilot(lua_State* L) * * @brief Pilot getPilot(nil) * * Get the players associated pilot. * @return The players pilot. */ static int player_getPilot(lua_State* L) { LuaPilot lp; lp.pilot = PLAYER_ID; lua_pushpilot(L, lp); return 1; } /** * @fn static int hook_pilot(lua_State* L) * @ingroup HOOK * * @brief number pilot(Pilot pilot, string type, string func) * * Hooks the function to a specific pilot. * * You can hook to different actions. At the moment hook system only supports: * -- "death" : Triggered when pilot dies. * -- "board" : Triggered when pilot is boarded. * -- "disable" : Triggered when pilot is disabled. * -- "jump" : Triggered when pilot jumps to hyperspace. * * @param pilot Pilot identifier to hook. * @param typer One of the supported hook types. * @param func Function to run when hook is triggered. * @return Hook identifier. */ static int hook_pilot(lua_State* L) { LLUA_MIN_ARGS(2); unsigned int h; LuaPilot* p; int type; char* hook_type; /* First parameter - pilot to hook. */ if(lua_ispilot(L, 1)) p = lua_topilot(L, 1); else LLUA_INVALID_PARAMETER(); /* Second parameer - Hook name. */ if(lua_isstring(L, 2)) hook_type = (char*) lua_tostring(L, 2); else LLUA_INVALID_PARAMETER(); /* Check to see if hook_type is valid. */ if(strcmp(hook_type, "death")==0) type = PILOT_HOOK_DEATH; else if(strcmp(hook_type, "board")==0) type = PILOT_HOOK_BOARD; else if(strcmp(hook_type, "disable")==0) type = PILOT_HOOK_DISABLE; else if(strcmp(hook_type, "jump")==0) type = PILOT_HOOK_JUMP; else { /* Hook type not valid. */ LLUA_DEBUG("Invalid pilot hook type: '%s'", hook_type); return 0; } /* Actually add the hook. */ h = hook_generic(L, hook_type); pilot_addHook(pilot_get(p->pilot), type, h); return 0; } /** * @defgroup DIFF Universe Diff Lua Bindings. * * @brief Lua bindings to apply/remove Universe Diffs. * * Functions should be called like: * * @code * diff.function(parameters) * @endcode * * @{ */ /** * @fn static int diff_applyL(lua_State* L) * * @brief apply(string name) * * Applies a diff by name. * @param name Name of the diff to apply. */ static int diff_applyL(lua_State* L) { char* name; if(lua_isstring(L, 1)) name = (char*)lua_tostring(L, 1); else LLUA_INVALID_PARAMETER(); diff_apply(name); return 0; } /** * @fn static int diff_removeL(lua_State* L) * * @brief remove(string name) * * Removes a diff by name. * @param name Name of the diff to remove. */ static int diff_removeL(lua_State* L) { char* name; if(lua_isstring(L, 1)) name = (char*)lua_tostring(L, 1); else LLUA_INVALID_PARAMETER(); diff_remove(name); return 0; } /** * @fn static int diff_isappliedL(lua_State* L) * * @brief bool isApplied(string name) * * Check to see if a diff is currently applied. * @param name Name of the diff to check. * @return true if it is applied, false if it isn't. */ static int diff_isappliedL(lua_State* L) { char* name; if(lua_isstring(L, 1)) name = (char*)lua_tostring(L, 1); else LLUA_INVALID_PARAMETER(); lua_pushboolean(L, diff_isApplied(name)); return 1; } /** * @} */