static void _get_vec_attrib(lua_State *L, const char *key, vector3d &output, const vector3d default_output) { LUA_DEBUG_START(L); lua_pushstring(L, key); lua_gettable(L, -2); if (lua_isnil(L, -1)) { output = default_output; } else { output = *LuaVector::CheckFromLua(L, -1); } lua_pop(L, 1); LUA_DEBUG_END(L, 0); }
static void _get_int_attrib(lua_State *L, const char *key, int &output, const int default_output) { LUA_DEBUG_START(L); lua_pushstring(L, key); lua_gettable(L, -2); if (lua_isnil(L, -1)) { output = default_output; } else { output = lua_tointeger(L,-1); } lua_pop(L, 1); LUA_DEBUG_END(L, 0); }
void LuaShipDef::Register() { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); lua_newtable(l); for (std::map<ShipType::Id,ShipType>::const_iterator i = ShipType::types.begin(); i != ShipType::types.end(); ++i) { const ShipType &st = (*i).second; lua_newtable(l); pi_lua_settable(l, "id", (*i).first.c_str()); pi_lua_settable(l, "name", st.name.c_str()); pi_lua_settable(l, "modelName", st.modelName.c_str()); pi_lua_settable(l, "tag", EnumStrings::GetString("ShipTypeTag", st.tag)); pi_lua_settable(l, "angularThrust", st.angThrust); pi_lua_settable(l, "capacity", st.capacity); pi_lua_settable(l, "hullMass", st.hullMass); pi_lua_settable(l, "basePrice", double(st.baseprice)*0.01); pi_lua_settable(l, "minCrew", st.minCrew); pi_lua_settable(l, "maxCrew", st.maxCrew); pi_lua_settable(l, "defaultHyperdrive", EnumStrings::GetString("EquipType", st.hyperdrive)); lua_newtable(l); for (int t = ShipType::THRUSTER_REVERSE; t < ShipType::THRUSTER_MAX; t++) pi_lua_settable(l, EnumStrings::GetString("ShipTypeThruster", t), st.linThrust[t]); pi_lua_readonly_table_proxy(l, -1); lua_setfield(l, -3, "linearThrust"); lua_pop(l, 1); lua_newtable(l); for (int slot = Equip::SLOT_CARGO; slot < Equip::SLOT_MAX; slot++) pi_lua_settable(l, EnumStrings::GetString("EquipSlot", slot), st.equipSlotCapacity[slot]); pi_lua_readonly_table_proxy(l, -1); lua_setfield(l, -3, "equipSlotCapacity"); lua_pop(l, 1); pi_lua_readonly_table_proxy(l, -1); lua_setfield(l, -3, (*i).first.c_str()); lua_pop(l, 1); } pi_lua_readonly_table_proxy(l, -1); lua_setglobal(l, "ShipDef"); lua_pop(l, 1); LUA_DEBUG_END(l, 0); }
void Player::SetShipType(const ShipType::Id &shipId) { Ship::SetShipType(shipId); lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); LuaObject<Player>::PushToLua(this); lua_pushcclosure(l, onEquipChangeListener, 1); LuaRef lr(Lua::manager->GetLuaState(), -1); ScopedTable(m_equipSet).CallMethod("AddListener", lr); lua_pop(l, 1); LUA_DEBUG_END(l, 0); }
/* * Method: SetFace * * Set the properties used to generate the face * * > form:SetFace({ * > female = female, * > armour = armour, * > seed = seed, * > name = name, * > title = title, * > }) * * Parameters: * * female - if true, the face will be female. If false, the face will be * male. If not specified, a gender will be chosen at random. * * armour - if true, the face will wear armour, otherwise the face will have * clothes and accessories. * * seed - the seed for the random number generator. if not specified, the * station seed will be used. if 0, a random seed will be generated * * name - name of the person. If not specified, a random one will be generated. * * title - the person's job or other suitable title. If not specified, nothing * will be shown. * * Example: * * > form:SetFace({ * > female = true, * > armour = false, * > seed = 1234, * > name = "Steve", * > title = "Station manager", * > }) * * Availability: * * alpha 10 * * Status: * * experimental */ static int l_luachatform_set_face(lua_State *l) { LuaChatForm *form = LuaObject<LuaChatForm>::CheckFromLua(1); luaL_checktype(l, 2, LUA_TTABLE); LUA_DEBUG_START(l); Uint32 flags = 0; Uint32 seed = 0; std::string name = ""; std::string title = ""; lua_getfield(l, 2, "female"); if (lua_isnil(l, -1)) flags = FaceVideoLink::GENDER_RAND; else if (lua_toboolean(l, -1)) flags = FaceVideoLink::GENDER_FEMALE; else flags = FaceVideoLink::GENDER_MALE; lua_pop(l, 1); lua_getfield(l, 2, "armour"); if (lua_toboolean(l, -1)) flags |= FaceVideoLink::ARMOUR; lua_pop(l, 1); lua_getfield(l, 2, "seed"); if (!lua_isnil(l, -1)) seed = luaL_checkinteger(l, -1); lua_pop(l, 1); lua_getfield(l, 2, "name"); if (!lua_isnil(l, -1)) name = luaL_checkstring(l, -1); lua_pop(l, 1); lua_getfield(l, 2, "title"); if (!lua_isnil(l, -1)) title = luaL_checkstring(l, -1); lua_pop(l, 1); LUA_DEBUG_END(l, 0); form->SetFaceFlags(flags); form->SetFaceSeed(seed); form->SetCharacterName(name); form->SetCharacterTitle(title); return 0; }
static bool GetNameGenFunc(lua_State *l, const char *func) { LUA_DEBUG_START(l); lua_getglobal(l, "NameGen"); if (lua_isnil(l, -1)) { lua_pop(l, 1); LUA_DEBUG_END(l, 0); return false; } lua_getfield(l, -1, func); if (lua_isnil(l, -1)) { lua_pop(l, 2); LUA_DEBUG_END(l, 0); return false; } lua_remove(l, -2); LUA_DEBUG_END(l, 1); return true; }
void LuaChatForm::OnClose() { StationAdvertForm::OnClose(); lua_State *l = Lua::manager->GetLuaState(); int ref = GetAdvert()->ref; LUA_DEBUG_START(l); if (m_commodityTradeWidget) { lua_getfield(l, LUA_REGISTRYINDEX, "PiAdverts"); assert(lua_istable(l, -1)); lua_pushinteger(l, ref); lua_gettable(l, -2); assert(!lua_isnil(l, -1)); lua_pushstring(l, "tradeWidgetFunctions"); lua_pushnil(l); lua_settable(l, -3); lua_pop(l, 2); } if (!AdTaken()) return; lua_getfield(l, LUA_REGISTRYINDEX, "PiAdverts"); assert(lua_istable(l, -1)); lua_pushinteger(l, ref); lua_gettable(l, -2); assert(!lua_isnil(l, -1)); lua_getfield(l, -1, "onDelete"); if (!lua_isnil(l, -1)) { lua_pushinteger(l, ref); pi_lua_protected_call(l, 1, 0); } else lua_pop(l, 1); lua_pop(l, 1); lua_pushinteger(l, ref); lua_pushnil(l); lua_settable(l, -3); lua_pop(l, 1); LUA_DEBUG_END(l, 0); }
// Create the table and leave a copy on the stack for further use static void init_global_table(lua_State *l) { LUA_DEBUG_START(l); lua_newtable(l); lua_newtable(l); lua_pushliteral(l, "__index"); lua_getglobal(l, "_G"); lua_rawset(l, -3); lua_setmetatable(l, -2); lua_pushvalue(l, -1); lua_setfield(l, LUA_REGISTRYINDEX, "ConsoleGlobal"); LUA_DEBUG_END(l, 1); }
void Queue(const char *event, const ArgsBase &args) { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); if (!_get_method_onto_stack(l, "Queue")) return; int top = lua_gettop(l); lua_pushstring(l, event); args.PrepareStack(); pi_lua_protected_call(l, lua_gettop(l) - top, 0); LUA_DEBUG_END(l, 0); }
/* * Function: GetDictionary * * Retrieve a Lua table for the current language. * * > dict = Lang.GetDictionary() * > print(dict['WE_HAVE_NO_BUSINESS_WITH_YOU']) * * Return: * * dict - A Lua table mapping language token to translated string. * * Availability: * * alpha 15 * * Status: * * stable */ static int l_lang_get_dictionary(lua_State *l) { LUA_DEBUG_START(l); lua_getfield(l, LUA_REGISTRYINDEX, "LangCoreDictionary"); if (lua_isnil(l, -1)) { lua_pop(l, 1); _build_dictionary_table(l); pi_lua_table_ro(l); lua_pushvalue(l, -1); lua_setfield(l, LUA_REGISTRYINDEX, "LangCoreDictionary"); } LUA_DEBUG_END(l, 1); return 1; }
/* * Method: AddAdvert * * Add an advertisement to the station's bulletin board * * > ref = station:AddAdvert(description, chatfunc, deletefunc) * * Parameters: * * description - text to display in the bulletin board * * chatfunc - function to call when the ad is activated. The function is * passed three parameters: a <ChatForm> object for the ad * conversation display, the ad reference returned by <AddAdvert> * when the ad was created, and an integer value corresponding to * the action that caused the activation. When the ad is initially * selected from the bulletin board, this value is 0. Additional * actions (and thus values) are defined by the script via * <ChatForm.AddAction>. * * deletefunc - optional. function to call when the ad is removed from the * bulletin board. This happens when <RemoveAdvert> is called, * when the ad is cleaned up after * <ChatForm.RemoveAdvertOnClose> is called, and when the * <SpaceStation> itself is destroyed (eg the player leaves the * system). * * Return: * * ref - an integer value for referring to the ad in the future. This value * will be passed to the ad's chat function and should be passed to * <RemoveAdvert> to remove the ad from the bulletin board. * * Example: * * > local ref = station:AddAdvert( * > "FAST SHIP to deliver a package to the Epsilon Eridani system.", * > function (ref, opt) ... end, * > function (ref) ... end * > ) * * Availability: * * alpha 10 * * Status: * * stable */ static int l_spacestation_add_advert(lua_State *l) { LUA_DEBUG_START(l); SpaceStation *s = LuaSpaceStation::GetFromLua(1); std::string description = luaL_checkstring(l, 2); luaL_checktype(l, 3, LUA_TFUNCTION); // any type of function bool have_delete = false; if (lua_gettop(l) >= 4) { luaL_checktype(l, 4, LUA_TFUNCTION); // any type of function have_delete = true; } int ref = s->AddBBAdvert(description, _create_chat_form); lua_getfield(l, LUA_REGISTRYINDEX, "PiAdverts"); if (lua_isnil(l, -1)) { lua_pop(l, 1); lua_newtable(l); lua_pushvalue(l, -1); lua_setfield(l, LUA_REGISTRYINDEX, "PiAdverts"); } lua_pushinteger(l, ref); lua_newtable(l); lua_pushstring(l, "onChat"); lua_pushvalue(l, 3); lua_settable(l, -3); if (have_delete) { lua_pushstring(l, "onDelete"); lua_pushvalue(l, 4); lua_settable(l, -3); } lua_settable(l, -3); lua_pop(l, 1); LUA_DEBUG_END(l,0); _register_for_station_delete(s); lua_pushinteger(l, ref); return 1; }
static void _json_to_lua(lua_State *l, const Json &data) { LUA_DEBUG_START(l); switch (data.type()) { case Json::nullValue: lua_pushnil(l); break; case Json::intValue: case Json::uintValue: case Json::realValue: lua_pushnumber(l, data.asDouble()); break; case Json::stringValue: { const std::string &str(data.asString()); lua_pushlstring(l, str.c_str(), str.size()); break; } case Json::booleanValue: lua_pushboolean(l, data.asBool()); break; case Json::arrayValue: { lua_newtable(l); for (int i = 0; i < int(data.size()); i++) { lua_pushinteger(l, i+1); _json_to_lua(l, data[i]); lua_rawset(l, -3); } break; } case Json::objectValue: { lua_newtable(l); for (Json::const_iterator i = data.begin(); i != data.end(); ++i) { const std::string &key(i.key().asString()); lua_pushlstring(l, key.c_str(), key.size()); _json_to_lua(l, *i); lua_rawset(l, -3); } break; } } LUA_DEBUG_END(l, 1); }
static void register_class(lua_State *L, const char *tname, luaL_Reg *meta) { LUA_DEBUG_START(L); luaL_newmetatable(L, tname); luaL_setfuncs(L, meta, 0); // map the metatable to its own __index lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); // publish the metatable lua_setglobal(L, tname); LUA_DEBUG_END(L, 0); }
/* * Function: SpawnShipParked * * Create a ship and place it in one of the given <SpaceStation's> parking spots. * * > ship = Space.SpawnShipParked(type, station) * * For orbital stations the parking spots are some distance from the door, out * of the path of ships entering and leaving the station. For group stations * the parking spots are directly above the station, usually some distance * away. * * Parameters: * * type - the name of the ship * * station - the <SpaceStation> to place the near * * Return: * * ship - a <Ship> object for the new ship, or nil if there was no space * inside the station * Availability: * * alpha 10 * * Status: * * experimental */ static int l_space_spawn_ship_parked(lua_State *l) { if (!Pi::game) luaL_error(l, "Game is not started"); LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); if (! ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); SpaceStation *station = LuaObject<SpaceStation>::CheckFromLua(2); int slot; if (!station->AllocateStaticSlot(slot)) return 0; Ship *ship = new Ship(type); assert(ship); double parkDist = station->GetStationType()->parkingDistance; parkDist -= ship->GetPhysRadius(); // park inside parking radius double parkOffset = 0.5 * station->GetStationType()->parkingGapSize; parkOffset += ship->GetPhysRadius(); // but outside the docking gap double xpos = (slot == 0 || slot == 3) ? -parkOffset : parkOffset; double zpos = (slot == 0 || slot == 1) ? -parkOffset : parkOffset; vector3d parkPos = vector3d(xpos, parkDist, zpos); parkPos = station->GetPosition() + station->GetOrient() * parkPos; // orbital stations have Y as axis of rotation matrix3x3d rot = matrix3x3d::RotateX(M_PI/2) * station->GetOrient(); ship->SetFrame(station->GetFrame()); ship->SetVelocity(vector3d(0.0)); ship->SetPosition(parkPos); ship->SetOrient(rot); Pi::game->GetSpace()->AddBody(ship); ship->AIHoldPosition(); LuaObject<Ship>::PushToLua(ship); LUA_DEBUG_END(l, 1); return 1; }
Player::Player(ShipType::Id shipId): Ship(shipId) { SetController(new PlayerShipController()); InitCockpit(); lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); LuaObject<Player>::PushToLua(this); lua_pushcclosure(l, onEquipChangeListener, 1); LuaRef lr(Lua::manager->GetLuaState(), -1); ScopedTable(m_equipSet).CallMethod("AddListener", lr); lua_pop(l, 1); LUA_DEBUG_END(l, 0); }
void LuaConsole::Register() { lua_State *l = Pi::luaManager->GetLuaState(); LUA_DEBUG_START(l); static const luaL_reg methods[] = { { "AddLine", l_console_addline }, { 0, 0 } }; luaL_register(l, "Console", methods); lua_pop(l, 1); LUA_DEBUG_END(l, 0); }
void LuaVector::Register(lua_State *L) { LUA_DEBUG_START(L); luaL_newlib(L, l_vector_lib); lua_setglobal(L, LuaVector::LibName); luaL_newmetatable(L, LuaVector::TypeName); luaL_setfuncs(L, l_vector_meta, 0); // hide the metatable to thwart crazy exploits lua_pushboolean(L, 0); lua_setfield(L, -2, "__metatable"); lua_pop(L, 1); LUA_DEBUG_END(L, 0); }
static int l_vector_unit(lua_State *L) { LUA_DEBUG_START(L); if (lua_isnumber(L, 1)) { double x = luaL_checknumber(L, 1); double y = luaL_checknumber(L, 2); double z = luaL_checknumber(L, 3); const vector3d v = vector3d(x, y, z); LuaVector::PushToLua(L, v.NormalizedSafe()); } else { const vector3d *v = LuaVector::CheckFromLua(L, 1); LuaVector::PushToLua(L, v->NormalizedSafe()); } LUA_DEBUG_END(L, 1); return 1; }
static int _get_stage_durations(lua_State *L, const char *key, int &outNumStages, double **outDurationArray) { LUA_DEBUG_START(L); LuaTable stages = LuaTable(L, -1).Sub(key); if (stages.GetLua() == 0) { luaL_error(L, "Not a proper table (%s)", key); } if (stages.Size() < 1) return luaL_error(L, "Station must have at least 1 stage in %s", key); outNumStages = stages.Size(); *outDurationArray = new double[stages.Size()]; std::copy(stages.Begin<double>(), stages.End<double>(), *outDurationArray); lua_pop(L, 1); // Popping t LUA_DEBUG_END(L, 0); return 0; }
/* * Method: Explore * * Set the star system to be explored by the Player. * * > system:Explore(time) * * Parameters: * * time - optional, the game time at which the system was explored. * Defaults to current game time. * * Availability: * * October 2014 * * Status: * * experimental */ static int l_starsystem_explore(lua_State *l) { LUA_DEBUG_START(l); StarSystem *s = LuaObject<StarSystem>::CheckFromLua(1); double time; if (lua_isnumber(l, 2)) time = luaL_checknumber(l, 2); else time = Pi::game->GetTime(); s->ExploreSystem(time); LUA_DEBUG_END(l,0); return 0; }
void LuaConsole::RegisterAutoexec() { lua_State *L = Lua::manager->GetLuaState(); LUA_DEBUG_START(L); if (!pi_lua_import(L, "Event")) { Output("console.lua:\nProblem when registering the autoexec script.\n"); return; } lua_getfield(L, -1, "Register"); // Register, Event lua_pushstring(L, "onGameStart"); // "onGameStart", Register, Event lua_pushlightuserdata(L, this); // console, "onGameStart", Register, Event lua_pushcclosure(L, console_autoexec, 1); // autoexec, "onGameStart", Register, Event lua_call(L, 2, 0); // Event lua_pop(L, 1); LUA_DEBUG_END(L, 0); }
/* * Function: GetBodies * * Get all the <Body> objects that match the specified filter * * bodies = Space.GetBodies(filter) * * Parameters: * * filter - an option function. If specificed the function will be called * once for each body with the <Body> object as the only parameter. * If the filter function returns true then the <Body> will be * included in the array returned by <GetBodies>, otherwise it will * be omitted. If no filter function is specified then all bodies * are returned. * * Return: * * bodies - an array containing zero or more <Body> objects that matched the * filter * * Example: * * > -- get all the ground-based stations * > local stations = Space.GetBodies(function (body) * > return body.type == "STARPORT_SURFACE" * > end) * * Availability: * * alpha 10 * * Status: * * stable */ static int l_space_get_bodies(lua_State *l) { if (!Pi::game) luaL_error(l, "Game is not started"); LUA_DEBUG_START(l); bool filter = false; if (lua_gettop(l) >= 1) { luaL_checktype(l, 1, LUA_TFUNCTION); // any type of function filter = true; } lua_newtable(l); for (Space::BodyIterator i = Pi::game->GetSpace()->BodiesBegin(); i != Pi::game->GetSpace()->BodiesEnd(); ++i) { Body *b = *i; if (filter) { lua_pushvalue(l, 1); LuaBody::PushToLua(b); if (int ret = lua_pcall(l, 1, 1, 0)) { const char *errmsg( "Unknown error" ); if (ret == LUA_ERRRUN) errmsg = lua_tostring(l, -1); else if (ret == LUA_ERRMEM) errmsg = "memory allocation failure"; else if (ret == LUA_ERRERR) errmsg = "error in error handler function"; luaL_error(l, "Error in filter function: %s", errmsg); } if (!lua_toboolean(l, -1)) { lua_pop(l, 1); continue; } lua_pop(l, 1); } lua_pushinteger(l, lua_rawlen(l, -1)+1); LuaBody::PushToLua(b); lua_rawset(l, -3); } LUA_DEBUG_END(l, 1); return 1; }
/* * Function: SpawnShipNear * * Create a ship and place it in space near the given <Body>. * * > ship = Space.SpawnShip(type, body, min, max, hyperspace) * * Parameters: * * type - the name of the ship * * body - the <Body> near which the ship should be spawned * * min - minimum distance from the body to place the ship, in Km * * max - maximum distance to place the ship * * hyperspace - optional table containing hyperspace entry information. If * this is provided the ship will not spawn directly. Instead, * a hyperspace cloud will be created that the ship will exit * from. The table contains two elements, a <SystemPath> for * the system the ship is travelling from, and the due * date/time that the ship should emerge from the cloud. * * Return: * * ship - a <Ship> object for the new ship * * Example: * * > -- spawn a ship 10km from the player * > local ship = Ship.SpawnNear("viper_police_craft", Game.player, 10, 10) * * Availability: * * alpha 10 * * Status: * * experimental */ static int l_space_spawn_ship_near(lua_State *l) { if (!Pi::game) luaL_error(l, "Game is not started"); LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); if (! ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); Body *nearbody = LuaObject<Body>::CheckFromLua(2); float min_dist = luaL_checknumber(l, 3); float max_dist = luaL_checknumber(l, 4); SystemPath *path = 0; double due = -1; _unpack_hyperspace_args(l, 5, path, due); Ship *ship = new Ship(type); assert(ship); Body *thing = _maybe_wrap_ship_with_cloud(ship, path, due); // XXX protect against spawning inside the body Frame * newframe = nearbody->GetFrame(); const vector3d newPosition = (MathUtil::RandomPointOnSphere(min_dist, max_dist)* 1000.0) + nearbody->GetPosition(); // If the frame is rotating and the chosen position is too far, use non-rotating parent. // Otherwise the ship will be given a massive initial velocity when it's bumped out of the // rotating frame in the next update if (newframe->IsRotFrame() && newframe->GetRadius() < newPosition.Length()) { assert(newframe->GetParent()); newframe = newframe->GetParent(); } thing->SetFrame(newframe);; thing->SetPosition(newPosition); thing->SetVelocity(vector3d(0,0,0)); Pi::game->GetSpace()->AddBody(thing); LuaObject<Ship>::PushToLua(ship); LUA_DEBUG_END(l, 1); return 1; }
void LuaEngine::Register() { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); static const luaL_Reg l_methods[] = { { "Quit", l_engine_quit }, { "GetVideoModeList", l_engine_get_video_mode_list }, { "GetVideoResolution", l_engine_get_video_resolution }, { "SetVideoResolution", l_engine_set_video_resolution }, { "GetFullscreen", l_engine_get_fullscreen }, { "SetFullscreen", l_engine_set_fullscreen }, { "GetVSyncEnabled", l_engine_get_vsync_enabled }, { "SetVSyncEnabled", l_engine_set_vsync_enabled }, { "GetTextureCompressionEnabled", l_engine_get_texture_compression_enabled }, { "SetTextureCompressionEnabled", l_engine_set_texture_compression_enabled }, { "GetMultisampling", l_engine_get_multisampling }, { "SetMultisampling", l_engine_set_multisampling }, //{ "GetKeyBindings", l_engine_get_key_bindings }, //{ "SetKeyBinding", l_engine_set_key_binding }, //{ "GetMouseYInverted", l_engine_get_mouse_y_inverted }, //{ "SetMouseYInverted", l_engine_set_mouse_y_inverted }, //{ "GetJoystickEnabled", l_engine_get_joystick_enabled }, //{ "SetJoystickEnabled", l_engine_set_joystick_enabled }, { 0, 0 } }; static const luaL_Reg l_attrs[] = { { "rand", l_engine_attr_rand }, { "ticks", l_engine_attr_ticks }, { "ui", l_engine_attr_ui }, { "version", l_engine_attr_version }, { 0, 0 } }; lua_getfield(l, LUA_REGISTRYINDEX, "CoreImports"); LuaObjectBase::CreateObject(l_methods, l_attrs, 0); lua_setfield(l, -2, "Engine"); lua_pop(l, 1); LUA_DEBUG_END(l, 0); }
Color4ub Color4ub::FromLuaTable(lua_State *l, int idx) { const int table = lua_absindex(l, idx); assert(lua_istable(l, table)); LUA_DEBUG_START(l); float r, g, b, a; _get_number(l, table, "r", r); _get_number(l, table, "g", g); _get_number(l, table, "b", b); if (!_get_number(l, table, "a", a)) a = 1.0f; LUA_DEBUG_END(l, 0); return Color4ub(r*255, g*255, b*255, a*255); }
/* Method: SetShipType * * Replaces the ship with a new ship of the specified type. * * > ship:SetShipType(newtype) * * Parameters: * * newtype - the name of the ship * * Example: * * > ship:SetShipType('sirius_interdictor') * * Availability: * * alpha 15 * * Status: * * experimental */ static int l_ship_set_type(lua_State *l) { LUA_DEBUG_START(l); Ship *s = LuaObject<Ship>::CheckFromLua(1); const char *type = luaL_checkstring(l, 2); if (! ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); s->SetShipType(type); s->UpdateEquipStats(); LUA_DEBUG_END(l, 0); return 0; }
Color4f Color4f::FromLuaTable(lua_State *l, int idx) { const int table = lua_absindex(l, idx); assert(lua_istable(l, table)); LUA_DEBUG_START(l); float r, g, b, a; _get_number(l, table, "r", r); _get_number(l, table, "g", g); _get_number(l, table, "b", b); _get_number(l, table, "a", a); LUA_DEBUG_END(l, 0); return Color4f(r, g, b, a); }
void LuaSerializer::Serialize(Serializer::Writer &wr) { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); lua_newtable(l); int savetable = lua_gettop(l); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks"); if (lua_isnil(l, -1)) { lua_pop(l, 1); lua_newtable(l); lua_pushvalue(l, -1); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks"); } lua_pushnil(l); while (lua_next(l, -2) != 0) { lua_pushinteger(l, 1); lua_gettable(l, -2); pi_lua_protected_call(l, 0, 1); lua_pushvalue(l, -3); lua_insert(l, -2); lua_settable(l, savetable); lua_pop(l, 1); } lua_pop(l, 1); lua_newtable(l); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); std::string pickled; pickle(l, savetable, pickled); wr.String(pickled); lua_pop(l, 1); lua_pushnil(l); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); LUA_DEBUG_END(l, 0); }
void LuaSerializer::Unserialize(Serializer::Reader &rd) { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); lua_newtable(l); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); std::string pickled = rd.String(); const char *start = pickled.c_str(); const char *end = unpickle(l, start); if (size_t(end - start) != pickled.length()) throw SavedGameCorruptException(); if (!lua_istable(l, -1)) throw SavedGameCorruptException(); int savetable = lua_gettop(l); lua_pushnil(l); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks"); if (lua_isnil(l, -1)) { lua_pop(l, 1); lua_newtable(l); lua_pushvalue(l, -1); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks"); } lua_pushnil(l); while (lua_next(l, -2) != 0) { lua_pushvalue(l, -2); lua_pushinteger(l, 2); lua_gettable(l, -3); lua_getfield(l, savetable, lua_tostring(l, -2)); if (lua_isnil(l, -1)) { lua_pop(l, 1); lua_newtable(l); } pi_lua_protected_call(l, 1, 0); lua_pop(l, 2); } lua_pop(l, 2); LUA_DEBUG_END(l, 0); }
static void _table_to_mission(lua_State *l, Mission &m, bool create) { LUA_DEBUG_START(l); // XXX sucky. should report errors that tell you which field is broken lua_getfield(l, -1, "due"); if (create || !lua_isnil(l, -1)) m.due = luaL_checknumber(l, -1); lua_pop(l, 1); lua_getfield(l, -1, "reward"); if (create || !lua_isnil(l, -1)) m.reward = Sint64(luaL_checknumber(l, -1) * 100.0); lua_pop(l, 1); lua_getfield(l, -1, "type"); if (create || !lua_isnil(l, -1)) m.type = luaL_checkstring(l, -1); lua_pop(l, 1); lua_getfield(l, -1, "client"); if (create || !lua_isnil(l, -1)) m.client = luaL_checkstring(l, -1); lua_pop(l, 1); lua_getfield(l, -1, "location"); if (create || !lua_isnil(l, -1)) { SystemPath *sbody = LuaSystemPath::GetFromLua(-1); m.location = *sbody; } lua_pop(l, 1); lua_getfield(l, -1, "status"); if (lua_isnil(l, -1)) { if (create) m.status = Mission::ACTIVE; } else m.status = static_cast<Mission::MissionState>(LuaConstants::GetConstant(l, "MissionStatus", luaL_checkstring(l, -1))); lua_pop(l, 2); LUA_DEBUG_END(l, -1); }