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); }
static bool GetNameGenFunc(lua_State *l, const char *func) { LUA_DEBUG_START(l); if (!pi_lua_import(l, "NameGen")) 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 Ship::InitEquipSet() { lua_State * l = Lua::manager->GetLuaState(); PropertyMap & p = Properties(); LUA_DEBUG_START(l); pi_lua_import(l, "EquipSet"); LuaTable es_class(l, -1); LuaTable slots = LuaTable(l).LoadMap(GetShipType()->slots.begin(), GetShipType()->slots.end()); m_equipSet = es_class.Call<LuaRef>("New", slots); p.Set("equipSet", ScopedTable(m_equipSet)); UpdateEquipStats(); { ScopedTable es(m_equipSet); int usedCargo = es.CallMethod<int>("OccupiedSpace", "cargo"); int totalCargo = std::min(m_stats.free_capacity + usedCargo, es.CallMethod<int>("SlotSize", "cargo")); p.Set("usedCargo", usedCargo); p.Set("totalCargo", totalCargo); } lua_pop(l, 2); LUA_DEBUG_END(l, 0); }
static bool _get_method_onto_stack(lua_State *l, const char *method) { LUA_DEBUG_START(l); int top = lua_gettop(l); if (!pi_lua_import(l, "Event")) return false; lua_getfield(l, -1, method); if (!lua_isfunction(l, -1)) { lua_pop(l, 2); LUA_DEBUG_END(l, 0); return false; } lua_insert(l, top+1); lua_settop(l, top+1); LUA_DEBUG_END(l, 1); return true; }
void Pi::HandleEvents() { PROFILE_SCOPED() SDL_Event event; // XXX for most keypresses SDL will generate KEYUP/KEYDOWN and TEXTINPUT // events. keybindings run off KEYUP/KEYDOWN. the console is opened/closed // via keybinding. the console TextInput widget uses TEXTINPUT events. thus // after switching the console, the stray TEXTINPUT event causes the // console key (backtick) to appear in the text entry field. we hack around // this by setting this flag if the console was switched. if its set, we // swallow the TEXTINPUT event this hack must remain until we have a // unified input system bool skipTextInput = false; Pi::mouseMotion[0] = Pi::mouseMotion[1] = 0; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { if (Pi::game) Pi::EndGame(); Pi::Quit(); } if (skipTextInput && event.type == SDL_TEXTINPUT) { skipTextInput = false; continue; } if (ui->DispatchSDLEvent(event)) continue; bool consoleActive = Pi::IsConsoleActive(); if (!consoleActive) KeyBindings::DispatchSDLEvent(&event); else KeyBindings::toggleLuaConsole.CheckSDLEventAndDispatch(&event); if (consoleActive != Pi::IsConsoleActive()) { skipTextInput = true; continue; } if (Pi::IsConsoleActive()) continue; Gui::HandleSDLEvent(&event); switch (event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) { if (Pi::game) { // only accessible once game started if (currentView != 0) { if (currentView != Pi::game->GetSettingsView()) { Pi::game->SetTimeAccel(Game::TIMEACCEL_PAUSED); SetView(Pi::game->GetSettingsView()); } else { Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X); SetView(Pi::player->IsDead() ? static_cast<View*>(Pi::game->GetDeathView()) : static_cast<View*>(Pi::game->GetWorldView())); } } } break; } // special keys. LCTRL+turd if ((KeyState(SDLK_LCTRL) || (KeyState(SDLK_RCTRL)))) { switch (event.key.keysym.sym) { case SDLK_q: // Quit if (Pi::game) Pi::EndGame(); Pi::Quit(); break; case SDLK_PRINTSCREEN: // print case SDLK_KP_MULTIPLY: // screen { char buf[256]; const time_t t = time(0); struct tm *_tm = localtime(&t); strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.png", _tm); Graphics::ScreendumpState sd; Pi::renderer->Screendump(sd); write_screenshot(sd, buf); break; } #if WITH_DEVKEYS case SDLK_i: // Toggle Debug info Pi::showDebugInfo = !Pi::showDebugInfo; break; #ifdef PIONEER_PROFILER case SDLK_p: // alert it that we want to profile if (KeyState(SDLK_LSHIFT) || KeyState(SDLK_RSHIFT)) Pi::doProfileOne = true; else { Pi::doProfileSlow = !Pi::doProfileSlow; Output("slow frame profiling %s\n", Pi::doProfileSlow ? "enabled" : "disabled"); } break; #endif case SDLK_F12: { if(Pi::game) { vector3d dir = -Pi::player->GetOrient().VectorZ(); /* add test object */ if (KeyState(SDLK_RSHIFT)) { Missile *missile = new Missile(ShipType::MISSILE_GUIDED, Pi::player); missile->SetOrient(Pi::player->GetOrient()); missile->SetFrame(Pi::player->GetFrame()); missile->SetPosition(Pi::player->GetPosition()+50.0*dir); missile->SetVelocity(Pi::player->GetVelocity()); game->GetSpace()->AddBody(missile); missile->AIKamikaze(Pi::player->GetCombatTarget()); } else if (KeyState(SDLK_LSHIFT)) { SpaceStation *s = static_cast<SpaceStation*>(Pi::player->GetNavTarget()); if (s) { Ship *ship = new Ship(ShipType::POLICE); int port = s->GetFreeDockingPort(ship); if (port != -1) { Output("Putting ship into station\n"); // Make police ship intent on killing the player ship->AIKill(Pi::player); ship->SetFrame(Pi::player->GetFrame()); ship->SetDockedWith(s, port); game->GetSpace()->AddBody(ship); } else { delete ship; Output("No docking ports free dude\n"); } } else { Output("Select a space station...\n"); } } else { Ship *ship = new Ship(ShipType::POLICE); if( KeyState(SDLK_LCTRL) ) ship->AIFlyTo(Pi::player); // a less lethal option else ship->AIKill(Pi::player); // a really lethal option! lua_State *l = Lua::manager->GetLuaState(); pi_lua_import(l, "Equipment"); LuaTable equip(l, -1); LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("laser").Sub("pulsecannon_dual_1mw")); LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("misc").Sub("laser_cooling_booster")); LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("misc").Sub("atmospheric_shielding")); lua_pop(l, 5); ship->SetFrame(Pi::player->GetFrame()); ship->SetPosition(Pi::player->GetPosition()+100.0*dir); ship->SetVelocity(Pi::player->GetVelocity()); ship->UpdateEquipStats(); game->GetSpace()->AddBody(ship); } } break; } #endif /* DEVKEYS */ #if WITH_OBJECTVIEWER case SDLK_F10: Pi::SetView(Pi::game->GetObjectViewerView()); break; #endif case SDLK_F11: // XXX only works on X11 //SDL_WM_ToggleFullScreen(Pi::scrSurface); #if WITH_DEVKEYS renderer->ReloadShaders(); #endif break; case SDLK_F9: // Quicksave { if(Pi::game) { if (Pi::game->IsHyperspace()) Pi::game->log->Add(Lang::CANT_SAVE_IN_HYPERSPACE); else { const std::string name = "_quicksave"; const std::string path = FileSystem::JoinPath(GetSaveDir(), name); try { Game::SaveGame(name, Pi::game); Pi::game->log->Add(Lang::GAME_SAVED_TO + path); } catch (CouldNotOpenFileException) { Pi::game->log->Add(stringf(Lang::COULD_NOT_OPEN_FILENAME, formatarg("path", path))); } catch (CouldNotWriteToFileException) { Pi::game->log->Add(Lang::GAME_SAVE_CANNOT_WRITE); } } } break; } default: break; // This does nothing but it stops the compiler warnings } } Pi::keyState[event.key.keysym.sym] = true; Pi::keyModState = event.key.keysym.mod; Pi::onKeyPress.emit(&event.key.keysym); break; case SDL_KEYUP: Pi::keyState[event.key.keysym.sym] = false; Pi::keyModState = event.key.keysym.mod; Pi::onKeyRelease.emit(&event.key.keysym); break; case SDL_MOUSEBUTTONDOWN: if (event.button.button < COUNTOF(Pi::mouseButton)) { Pi::mouseButton[event.button.button] = 1; Pi::onMouseButtonDown.emit(event.button.button, event.button.x, event.button.y); } break; case SDL_MOUSEBUTTONUP: if (event.button.button < COUNTOF(Pi::mouseButton)) { Pi::mouseButton[event.button.button] = 0; Pi::onMouseButtonUp.emit(event.button.button, event.button.x, event.button.y); } break; case SDL_MOUSEWHEEL: Pi::onMouseWheel.emit(event.wheel.y > 0); // true = up break; case SDL_MOUSEMOTION: Pi::mouseMotion[0] += event.motion.xrel; Pi::mouseMotion[1] += event.motion.yrel; // SDL_GetRelativeMouseState(&Pi::mouseMotion[0], &Pi::mouseMotion[1]); break; case SDL_JOYAXISMOTION: if (!joysticks[event.jaxis.which].joystick) break; if (event.jaxis.value == -32768) joysticks[event.jaxis.which].axes[event.jaxis.axis] = 1.f; else joysticks[event.jaxis.which].axes[event.jaxis.axis] = -event.jaxis.value / 32767.f; break; case SDL_JOYBUTTONUP: case SDL_JOYBUTTONDOWN: if (!joysticks[event.jaxis.which].joystick) break; joysticks[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0; break; case SDL_JOYHATMOTION: if (!joysticks[event.jaxis.which].joystick) break; joysticks[event.jhat.which].hats[event.jhat.hat] = event.jhat.value; break; } } }
void Ship::StaticUpdate(const float timeStep) { // do player sounds before dead check, so they also turn off if (IsType(Object::PLAYER)) DoThrusterSounds(); if (IsDead()) return; if (m_controller) m_controller->StaticUpdate(timeStep); if (GetHullTemperature() > 1.0) Explode(); UpdateAlertState(); /* FUEL SCOOPING!!!!!!!!! */ int capacity = 0; Properties().Get("fuel_scoop_cap", capacity); if (m_flightState == FLYING && capacity > 0) { Body *astro = GetFrame()->GetBody(); if (astro && astro->IsType(Object::PLANET)) { Planet *p = static_cast<Planet*>(astro); if (p->GetSystemBody()->IsScoopable()) { double dist = GetPosition().Length(); double pressure, density; p->GetAtmosphericState(dist, &pressure, &density); double speed = GetVelocity().Length(); vector3d vdir = GetVelocity().Normalized(); vector3d pdir = -GetOrient().VectorZ(); double dot = vdir.Dot(pdir); if ((m_stats.free_capacity) && (dot > 0.95) && (speed > 2000.0) && (density > 1.0)) { double rate = speed*density*0.00000333f*double(capacity); if (Pi::rng.Double() < rate) { lua_State *l = Lua::manager->GetLuaState(); pi_lua_import(l, "Equipment"); LuaTable hydrogen = LuaTable(l, -1).Sub("cargo").Sub("hydrogen"); LuaObject<Ship>::CallMethod(this, "AddEquip", hydrogen); UpdateEquipStats(); if (this->IsType(Object::PLAYER)) { Pi::game->log->Add(stringf(Lang::FUEL_SCOOP_ACTIVE_N_TONNES_H_COLLECTED, formatarg("quantity", LuaObject<Ship>::CallMethod<int>(this, "CountEquip", hydrogen)))); } lua_pop(l, 3); } } } } } // Cargo bay life support capacity = 0; Properties().Get("cargo_life_support_cap", capacity); if (!capacity) { // Hull is pressure-sealed, it just doesn't provide // temperature regulation and breathable atmosphere // kill stuff roughly every 5 seconds if ((!m_dockedWith) && (5.0*Pi::rng.Double() < timeStep)) { std::string t(Pi::rng.Int32(2) ? "live_animals" : "slaves"); lua_State *l = Lua::manager->GetLuaState(); pi_lua_import(l, "Equipment"); LuaTable cargo = LuaTable(l, -1).Sub("cargo"); if (LuaObject<Ship>::CallMethod<int>(this, "RemoveEquip", cargo.Sub(t))) { LuaObject<Ship>::CallMethod<int>(this, "AddEquip", cargo.Sub("fertilizer")); if (this->IsType(Object::PLAYER)) { Pi::game->log->Add(Lang::CARGO_BAY_LIFE_SUPPORT_LOST); } lua_pop(l, 4); } else lua_pop(l, 3); } } if (m_flightState == FLYING) m_launchLockTimeout -= timeStep; if (m_launchLockTimeout < 0) m_launchLockTimeout = 0; if (m_flightState == JUMPING || m_flightState == HYPERSPACE) m_launchLockTimeout = 0; // lasers for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) { m_gun[i].recharge -= timeStep; float rateCooling = 0.01f; float cooler = 1.0f; Properties().Get("laser_cooler_cap", cooler); rateCooling *= cooler; m_gun[i].temperature -= rateCooling*timeStep; if (m_gun[i].temperature < 0.0f) m_gun[i].temperature = 0; if (m_gun[i].recharge < 0.0f) m_gun[i].recharge = 0; if (!m_gun[i].state) continue; if (m_gun[i].recharge > 0.0f) continue; if (m_gun[i].temperature > 1.0) continue; FireWeapon(i); } if (m_ecmRecharge > 0.0f) { m_ecmRecharge = std::max(0.0f, m_ecmRecharge - timeStep); } if (m_shieldCooldown > 0.0f) { m_shieldCooldown = std::max(0.0f, m_shieldCooldown - timeStep); } if (m_stats.shield_mass_left < m_stats.shield_mass) { // 250 second recharge float recharge_rate = 0.004f; float booster = 1.0f; Properties().Get("shield_energy_booster_cap", booster); recharge_rate *= booster; m_stats.shield_mass_left = Clamp(m_stats.shield_mass_left + m_stats.shield_mass * recharge_rate * timeStep, 0.0f, m_stats.shield_mass); Properties().Set("shieldMassLeft", m_stats.shield_mass_left); } if (m_wheelTransition) { m_wheelState += m_wheelTransition*0.3f*timeStep; m_wheelState = Clamp(m_wheelState, 0.0f, 1.0f); if (is_equal_exact(m_wheelState, 0.0f) || is_equal_exact(m_wheelState, 1.0f)) m_wheelTransition = 0; } if (m_testLanded) TestLanded(); capacity = 0; Properties().Get("hull_autorepair_cap", capacity); if (capacity) { m_stats.hull_mass_left = std::min(m_stats.hull_mass_left + 0.1f*timeStep, float(m_type->hullMass)); Properties().Set("hullMassLeft", m_stats.hull_mass_left); Properties().Set("hullPercent", 100.0f * (m_stats.hull_mass_left / float(m_type->hullMass))); } // After calling StartHyperspaceTo this Ship must not spawn objects // holding references to it (eg missiles), as StartHyperspaceTo // removes the ship from Space::bodies and so the missile will not // have references to this cleared by NotifyRemoved() if (m_hyperspace.now) { m_hyperspace.now = false; EnterHyperspace(); } if (m_hyperspace.countdown > 0.0f) { // Check the Lua function bool abort = false; lua_State * l = m_hyperspace.checks.GetLua(); if (l) { m_hyperspace.checks.PushCopyToStack(); if (lua_isfunction(l, -1)) { lua_call(l, 0, 1); abort = !lua_toboolean(l, -1); lua_pop(l, 1); } } if (abort) { AbortHyperjump(); } else { m_hyperspace.countdown = m_hyperspace.countdown - timeStep; if (!abort && m_hyperspace.countdown <= 0.0f) { m_hyperspace.countdown = 0; m_hyperspace.now = true; SetFlightState(JUMPING); // We have to fire it here, because the event isn't actually fired until // after the whole physics update, which means the flight state on next // step would be HYPERSPACE, thus breaking quite a few things. LuaEvent::Queue("onLeaveSystem", this); } } } //Add smoke trails for missiles on thruster state static double s_timeAccum = 0.0; s_timeAccum += timeStep; if (m_type->tag == ShipType::TAG_MISSILE && !is_equal_exact(m_thrusters.LengthSqr(), 0.0) && (s_timeAccum > 4 || 0.1*Pi::rng.Double() < timeStep)) { s_timeAccum = 0.0; const vector3d pos = GetOrient() * vector3d(0, 0 , 5); const float speed = std::min(10.0*GetVelocity().Length()*std::max(1.0,fabs(m_thrusters.z)),100.0); SfxManager::AddThrustSmoke(this, speed, pos); } }
void Pi::HandleKeyDown(SDL_Keysym *key) { if (key->sym == SDLK_ESCAPE) { if (Pi::game) { // only accessible once game started HandleEscKey(); } return; } const bool CTRL = input.KeyState(SDLK_LCTRL) || input.KeyState(SDLK_RCTRL); // special keys. if (CTRL) { switch (key->sym) { case SDLK_q: // Quit Pi::RequestQuit(); break; case SDLK_PRINTSCREEN: // print case SDLK_KP_MULTIPLY: // screen { char buf[256]; const time_t t = time(0); struct tm *_tm = localtime(&t); strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.png", _tm); Graphics::ScreendumpState sd; Pi::renderer->Screendump(sd); write_screenshot(sd, buf); break; } case SDLK_SCROLLLOCK: // toggle video recording Pi::isRecordingVideo = !Pi::isRecordingVideo; if (Pi::isRecordingVideo) { char videoName[256]; const time_t t = time(0); struct tm *_tm = localtime(&t); strftime(videoName, sizeof(videoName), "pioneer-%Y%m%d-%H%M%S", _tm); const std::string dir = "videos"; FileSystem::userFiles.MakeDirectory(dir); const std::string fname = FileSystem::JoinPathBelow(FileSystem::userFiles.GetRoot() + "/" + dir, videoName); Output("Video Recording started to %s.\n", fname.c_str()); // start ffmpeg telling it to expect raw rgba 720p-60hz frames // -i - tells it to read frames from stdin // if given no frame rate (-r 60), it will just use vfr char cmd[256] = { 0 }; snprintf(cmd, sizeof(cmd), "ffmpeg -f rawvideo -pix_fmt rgba -s %dx%d -i - -threads 0 -preset fast -y -pix_fmt yuv420p -crf 21 -vf vflip %s.mp4", config->Int("ScrWidth"), config->Int("ScrHeight"), fname.c_str()); // open pipe to ffmpeg's stdin in binary write mode #if defined(_MSC_VER) || defined(__MINGW32__) Pi::ffmpegFile = _popen(cmd, "wb"); #else Pi::ffmpegFile = _popen(cmd, "w"); #endif } else { Output("Video Recording ended.\n"); if (Pi::ffmpegFile != nullptr) { _pclose(Pi::ffmpegFile); Pi::ffmpegFile = nullptr; } } break; #if WITH_DEVKEYS case SDLK_i: // Toggle Debug info Pi::showDebugInfo = !Pi::showDebugInfo; break; #ifdef PIONEER_PROFILER case SDLK_p: // alert it that we want to profile if (input.KeyState(SDLK_LSHIFT) || input.KeyState(SDLK_RSHIFT)) Pi::doProfileOne = true; else { Pi::doProfileSlow = !Pi::doProfileSlow; Output("slow frame profiling %s\n", Pi::doProfileSlow ? "enabled" : "disabled"); } break; #endif case SDLK_F12: { if (Pi::game) { vector3d dir = -Pi::player->GetOrient().VectorZ(); /* add test object */ if (input.KeyState(SDLK_RSHIFT)) { Missile *missile = new Missile(ShipType::MISSILE_GUIDED, Pi::player); missile->SetOrient(Pi::player->GetOrient()); missile->SetFrame(Pi::player->GetFrame()); missile->SetPosition(Pi::player->GetPosition() + 50.0 * dir); missile->SetVelocity(Pi::player->GetVelocity()); game->GetSpace()->AddBody(missile); missile->AIKamikaze(Pi::player->GetCombatTarget()); } else if (input.KeyState(SDLK_LSHIFT)) { SpaceStation *s = static_cast<SpaceStation *>(Pi::player->GetNavTarget()); if (s) { Ship *ship = new Ship(ShipType::POLICE); int port = s->GetFreeDockingPort(ship); if (port != -1) { Output("Putting ship into station\n"); // Make police ship intent on killing the player ship->AIKill(Pi::player); ship->SetFrame(Pi::player->GetFrame()); ship->SetDockedWith(s, port); game->GetSpace()->AddBody(ship); } else { delete ship; Output("No docking ports free dude\n"); } } else { Output("Select a space station...\n"); } } else { Ship *ship = new Ship(ShipType::POLICE); if (!input.KeyState(SDLK_LALT)) { //Left ALT = no AI if (!input.KeyState(SDLK_LCTRL)) ship->AIFlyTo(Pi::player); // a less lethal option else ship->AIKill(Pi::player); // a really lethal option! } lua_State *l = Lua::manager->GetLuaState(); pi_lua_import(l, "Equipment"); LuaTable equip(l, -1); LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("laser").Sub("pulsecannon_dual_1mw")); LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("misc").Sub("laser_cooling_booster")); LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("misc").Sub("atmospheric_shielding")); lua_pop(l, 5); ship->SetFrame(Pi::player->GetFrame()); ship->SetPosition(Pi::player->GetPosition() + 100.0 * dir); ship->SetVelocity(Pi::player->GetVelocity()); ship->UpdateEquipStats(); game->GetSpace()->AddBody(ship); } } break; } #endif /* DEVKEYS */ #if WITH_OBJECTVIEWER case SDLK_F10: Pi::SetView(Pi::game->GetObjectViewerView()); break; #endif case SDLK_F11: // XXX only works on X11 //SDL_WM_ToggleFullScreen(Pi::scrSurface); #if WITH_DEVKEYS renderer->ReloadShaders(); #endif break; case SDLK_F9: // Quicksave { if (Pi::game) { if (Pi::game->IsHyperspace()) Pi::game->log->Add(Lang::CANT_SAVE_IN_HYPERSPACE); else { const std::string name = "_quicksave"; const std::string path = FileSystem::JoinPath(GetSaveDir(), name); try { Game::SaveGame(name, Pi::game); Pi::game->log->Add(Lang::GAME_SAVED_TO + path); } catch (CouldNotOpenFileException) { Pi::game->log->Add(stringf(Lang::COULD_NOT_OPEN_FILENAME, formatarg("path", path))); } catch (CouldNotWriteToFileException) { Pi::game->log->Add(Lang::GAME_SAVE_CANNOT_WRITE); } } } break; } default: break; // This does nothing but it stops the compiler warnings } } }
static void LuaInit() { LuaObject<PropertiedObject>::RegisterClass(); LuaObject<Body>::RegisterClass(); LuaObject<Ship>::RegisterClass(); LuaObject<SpaceStation>::RegisterClass(); LuaObject<Planet>::RegisterClass(); LuaObject<Star>::RegisterClass(); LuaObject<Player>::RegisterClass(); LuaObject<Missile>::RegisterClass(); LuaObject<CargoBody>::RegisterClass(); LuaObject<ModelBody>::RegisterClass(); LuaObject<HyperspaceCloud>::RegisterClass(); LuaObject<StarSystem>::RegisterClass(); LuaObject<SystemPath>::RegisterClass(); LuaObject<SystemBody>::RegisterClass(); LuaObject<Random>::RegisterClass(); LuaObject<Faction>::RegisterClass(); Pi::luaSerializer = new LuaSerializer(); Pi::luaTimer = new LuaTimer(); LuaObject<LuaSerializer>::RegisterClass(); LuaObject<LuaTimer>::RegisterClass(); LuaConstants::Register(Lua::manager->GetLuaState()); LuaLang::Register(); LuaEngine::Register(); LuaInput::Register(); LuaFileSystem::Register(); LuaJson::Register(); #ifdef ENABLE_SERVER_AGENT LuaServerAgent::Register(); #endif LuaGame::Register(); LuaComms::Register(); LuaFormat::Register(); LuaSpace::Register(); LuaShipDef::Register(); LuaMusic::Register(); LuaDev::Register(); LuaConsole::Register(); LuaVector::Register(Lua::manager->GetLuaState()); LuaVector2::Register(Lua::manager->GetLuaState()); // XXX sigh UI::Lua::Init(); GameUI::Lua::Init(); SceneGraph::Lua::Init(); LuaObject<PiGui>::RegisterClass(); // XXX load everything. for now, just modules lua_State *l = Lua::manager->GetLuaState(); pi_lua_import(l, "libs/autoload.lua", true); pi_lua_import_recursive(l, "ui"); pi_lua_import(l, "pigui/pigui.lua", true); pi_lua_import(l, "pigui/game.lua", true); pi_lua_import(l, "pigui/init.lua", true); pi_lua_import(l, "pigui/mainmenu.lua", true); pi_lua_import_recursive(l, "pigui/modules"); pi_lua_import_recursive(l, "pigui/views"); pi_lua_import_recursive(l, "modules"); Pi::luaNameGen = new LuaNameGen(Lua::manager); }
void LuaShipDef::Register() { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); lua_newtable(l); for (auto iter : ShipType::types) { const ShipType &st = iter.second; lua_newtable(l); pi_lua_settable(l, "id", iter.first.c_str()); pi_lua_settable(l, "name", st.name.c_str()); pi_lua_settable(l, "shipClass", st.shipClass.c_str()); pi_lua_settable(l, "manufacturer", st.manufacturer.c_str()); pi_lua_settable(l, "modelName", st.modelName.c_str()); pi_lua_settable(l, "cockpitName", st.cockpitName.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, "fuelTankMass", st.fuelTankMass); pi_lua_settable(l, "basePrice", st.baseprice); pi_lua_settable(l, "minCrew", st.minCrew); pi_lua_settable(l, "maxCrew", st.maxCrew); pi_lua_settable(l, "hyperdriveClass", st.hyperdriveClass); pi_lua_settable(l, "effectiveExhaustVelocity", st.effectiveExhaustVelocity); pi_lua_settable(l, "thrusterFuelUse", st.GetFuelUseRate()); lua_newtable(l); for (int t = Thruster::THRUSTER_REVERSE; t < Thruster::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 (auto it = st.slots.cbegin(); it != st.slots.cend(); ++it) { pi_lua_settable(l, it->first.c_str(), it->second); } pi_lua_readonly_table_proxy(l, -1); luaL_getmetafield(l, -1, "__index"); if (!lua_getmetatable(l, -1)) { lua_newtable(l); } pi_lua_import(l, "EquipSet"); luaL_getsubtable(l, -1, "default"); lua_setfield(l, -3, "__index"); lua_pop(l, 1); lua_setmetatable(l, -2); lua_pop(l, 1); lua_setfield(l, -3, "equipSlotCapacity"); lua_pop(l, 1); lua_newtable(l); for (auto it = st.roles.cbegin(); it != st.roles.cend(); ++it) { pi_lua_settable(l, it->first.c_str(), it->second); } pi_lua_readonly_table_proxy(l, -1); lua_setfield(l, -3, "roles"); lua_pop(l, 1); pi_lua_readonly_table_proxy(l, -1); lua_setfield(l, -3, iter.first.c_str()); lua_pop(l, 1); } lua_getfield(l, LUA_REGISTRYINDEX, "CoreImports"); pi_lua_readonly_table_proxy(l, -2); lua_setfield(l, -2, "ShipDef"); lua_pop(l, 2); LUA_DEBUG_END(l, 0); }