Game::Game(const SystemPath &path, double time) : m_time(time), m_state(STATE_NORMAL), m_wantHyperspace(false), m_timeAccel(TIMEACCEL_1X), m_requestedTimeAccel(TIMEACCEL_1X), m_forceTimeAccel(false) { Pi::FlushCaches(); m_space.reset(new Space(this, path)); SpaceStation *station = static_cast<SpaceStation*>(m_space->FindBodyForPath(&path)); assert(station); m_player.reset(new Player("kanara")); m_space->AddBody(m_player.get()); m_player->SetFrame(station->GetFrame()); m_player->SetDockedWith(station, 0); Polit::Init(); CreateViews(); }
/* * Function: SpawnShipDocked * * Create a ship and place it inside the given <SpaceStation>. * * > ship = Space.SpawnShipDocked(type, station) * * Parameters: * * type - the name of the ship * * station - the <SpaceStation> to place the ship inside * * Return: * * ship - a <Ship> object for the new ship, or nil if there was no space * inside the station * * Availability: * * alpha 10 * * Status: * * stable */ static int l_space_spawn_ship_docked(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 = LuaSpaceStation::CheckFromLua(2); int port = station->GetFreeDockingPort(); if (port < 0) return 0; Ship *ship = new Ship(type); assert(ship); ship->SetFrame(station->GetFrame()); Pi::game->GetSpace()->AddBody(ship); ship->SetDockedWith(station, port); LuaShip::PushToLua(ship); LUA_DEBUG_END(l, 1); return 1; }
/* * 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; }
Game::Game(const SystemPath &path) : m_time(0), m_state(STATE_NORMAL), m_wantHyperspace(false), m_timeAccel(TIMEACCEL_1X), m_requestedTimeAccel(TIMEACCEL_1X), m_forceTimeAccel(false) { m_space.Reset(new Space(this, path)); SpaceStation *station = static_cast<SpaceStation*>(m_space->FindBodyForPath(&path)); assert(station); CreatePlayer(); m_space->AddBody(m_player.Get()); m_player->Enable(); m_player->SetFrame(station->GetFrame()); m_player->SetDockedWith(station, 0); CreateViews(); }
void Pi::Start() { WorldView *view = new WorldView(); Gui::Fixed *splash = new Gui::Fixed(Gui::Screen::GetWidth(), Gui::Screen::GetHeight()); Gui::Screen::AddBaseWidget(splash, 0, 0); splash->SetTransparency(true); const float w = Gui::Screen::GetWidth() / 2; const float h = Gui::Screen::GetHeight() / 2; const int OPTS = 5; Gui::ToggleButton *opts[OPTS]; opts[0] = new Gui::ToggleButton(); opts[0]->SetShortcut(SDLK_1, KMOD_NONE); opts[1] = new Gui::ToggleButton(); opts[1]->SetShortcut(SDLK_2, KMOD_NONE); opts[2] = new Gui::ToggleButton(); opts[2]->SetShortcut(SDLK_3, KMOD_NONE); opts[3] = new Gui::ToggleButton(); opts[3]->SetShortcut(SDLK_4, KMOD_NONE); opts[4] = new Gui::ToggleButton(); opts[4]->SetShortcut(SDLK_5, KMOD_NONE); splash->Add(opts[0], w, h-64); splash->Add(new Gui::Label("New game starting on Earth"), w+32, h-64); splash->Add(opts[1], w, h-32); splash->Add(new Gui::Label("New game starting on Epsilon Eridani"), w+32, h-32); splash->Add(opts[2], w, h); splash->Add(new Gui::Label("New game starting on debug point"), w+32, h); splash->Add(opts[3], w, h+32); splash->Add(new Gui::Label("Load a saved game"), w+32, h+32); splash->Add(opts[4], w, h+64); splash->Add(new Gui::Label("Quit"), w+32, h+64); splash->ShowAll(); int choice = 0; Uint32 last_time = SDL_GetTicks(); float _time = 0; do { Pi::HandleEvents(); Render::PrepareFrame(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float fracH = 1.0 / Pi::GetScrAspect(); glFrustum(-1, 1, -fracH, fracH, 1.0f, 10000.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_ShowCursor(1); SDL_WM_GrabInput(SDL_GRAB_OFF); draw_intro(view, _time); Render::PostProcess(); Gui::Draw(); Render::SwapBuffers(); Pi::frameTime = 0.001*(SDL_GetTicks() - last_time); _time += Pi::frameTime; last_time = SDL_GetTicks(); // poll ui instead of using callbacks :-J for (int i=0; i<OPTS; i++) if (opts[i]->GetPressed()) choice = i+1; } while (!choice); splash->HideAll(); Gui::Screen::RemoveBaseWidget(splash); delete splash; delete view; InitGame(); if (choice == 1) { /* Earth start point */ SBodyPath path(0,0,0); Space::DoHyperspaceTo(&path); //Frame *pframe = *(++(++(Space::rootFrame->m_children.begin()))); //player->SetFrame(pframe); // XXX there isn't a sensible way to find stations for a planet. SpaceStation *station = 0; for (Space::bodiesIter_t i = Space::bodies.begin(); i!=Space::bodies.end(); i++) { if ((*i)->IsType(Object::SPACESTATION)) { station = (SpaceStation*)*i; break; } } assert(station); player->SetPosition(vector3d(0,0,0)); player->SetFrame(station->GetFrame()); player->SetDockedWith(station, 0); MainLoop(); } else if (choice == 2) { /* Epsilon Eridani start point */ SBodyPath path(1,0,2); Space::DoHyperspaceTo(&path); // XXX there isn't a sensible way to find stations for a planet. SpaceStation *station = 0; for (Space::bodiesIter_t i = Space::bodies.begin(); i!=Space::bodies.end(); i++) { if ((*i)->IsType(Object::SPACESTATION)) { station = (SpaceStation*)*i; if (!station->IsGroundStation()) break; } } assert(station); player->SetPosition(vector3d(0,0,0)); player->SetFrame(station->GetFrame()); player->SetDockedWith(station, 0); MainLoop(); } else if (choice == 3) { /* debug start point */ SBodyPath path(1,0,2); path.sbodyId = 6; Space::DoHyperspaceTo(&path); player->SetPosition(vector3d(2*EARTH_RADIUS,0,0)); player->SetVelocity(vector3d(0,0,0)); player->m_equipment.Add(Equip::HYPERCLOUD_ANALYZER); Ship *enemy = new Ship(ShipType::EAGLE_LRF); enemy->SetFrame(player->GetFrame()); enemy->SetPosition(player->GetPosition()+vector3d(0,0,-9000.0)); enemy->SetVelocity(vector3d(0,0,0)); enemy->m_equipment.Add(Equip::PULSECANNON_1MW); enemy->AIKill(player); Space::AddBody(enemy); player->SetCombatTarget(enemy); const ShipType *shipdef; double mass, acc1, acc2, acc3; printf("Player ship mass = %.0fkg, Enemy ship mass = %.0fkg\n", player->GetMass(), enemy->GetMass()); shipdef = &player->GetShipType(); mass = player->GetMass(); acc1 = shipdef->linThrust[ShipType::THRUSTER_FORWARD] / (9.81*mass); acc2 = shipdef->linThrust[ShipType::THRUSTER_REVERSE] / (9.81*mass); acc3 = shipdef->linThrust[ShipType::THRUSTER_UP] / (9.81*mass); printf("Player ship thrust = %.1fg, %.1fg, %.1fg\n", acc1, acc2, acc3); shipdef = &enemy->GetShipType(); mass = enemy->GetMass(); acc1 = shipdef->linThrust[ShipType::THRUSTER_FORWARD] / (9.81*mass); acc2 = shipdef->linThrust[ShipType::THRUSTER_REVERSE] / (9.81*mass); acc3 = shipdef->linThrust[ShipType::THRUSTER_UP] / (9.81*mass); printf("Enemy ship thrust = %.1fg, %.1fg, %.1fg\n", acc1, acc2, acc3); /* Frame *stationFrame = new Frame(pframe, "Station frame..."); stationFrame->SetRadius(5000); stationFrame->m_sbody = 0; stationFrame->SetPosition(vector3d(0,0,zpos)); stationFrame->SetAngVelocity(vector3d(0,0,0.5)); for (int i=0; i<4; i++) { Ship *body = new Ship(ShipType::LADYBIRD); char buf[64]; snprintf(buf,sizeof(buf),"X%c-0%02d", 'A'+i, i); body->SetLabel(buf); body->SetFrame(stationFrame); body->SetPosition(vector3d(200*(i+1), 0, 2000)); Space::AddBody(body); } SpaceStation *station = new SpaceStation(SpaceStation::JJHOOP); station->SetLabel("Poemi-chan's Folly"); station->SetFrame(stationFrame); station->SetPosition(vector3d(0,0,0)); Space::AddBody(station); SpaceStation *station2 = new SpaceStation(SpaceStation::GROUND_FLAVOURED); station2->SetLabel("Conor's End"); station2->SetFrame(*pframe->m_children.begin()); // rotating frame of planet station2->OrientOnSurface(EARTH_RADIUS, M_PI/4, M_PI/4); Space::AddBody(station2); */ // player->SetDockedWith(station2, 0); MainLoop(); } else if (choice == 4) { if (Pi::player) { Pi::player->MarkDead(); Space::bodies.remove(Pi::player); delete Pi::player; Pi::player = 0; } Pi::gameMenuView->OpenLoadDialog(); do { Gui::MainLoopIteration(); } while (Pi::currentView != Pi::worldView); if (Pi::isGameStarted) MainLoop(); } else { Pi::Quit(); } UninitGame(); }
/* * 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 = LuaSpaceStation::CheckFromLua(2); int slot; if (!station->AllocateStaticSlot(slot)) return 0; Ship *ship = new Ship(type); assert(ship); vector3d pos, vel; matrix4x4d rot = matrix4x4d::Identity(); if (station->GetSystemBody()->type == SystemBody::TYPE_STARPORT_SURFACE) { vel = vector3d(0.0); // XXX on tiny planets eg asteroids force this to be larger so the // are out of the docking path pos = station->GetPosition() * 1.1; station->GetRotMatrix(rot); vector3d axis1, axis2; axis1 = pos.Cross(vector3d(0.0,1.0,0.0)); axis2 = pos.Cross(axis1); double ang = atan((140 + ship->GetLmrCollMesh()->GetBoundingRadius()) / pos.Length()); if (slot<2) ang = -ang; vector3d axis = (slot == 0 || slot == 3) ? axis1 : axis2; pos.ArbRotate(axis, ang); } else { double dist = 100 + ship->GetLmrCollMesh()->GetBoundingRadius(); double xpos = (slot == 0 || slot == 3) ? -dist : dist; double zpos = (slot == 0 || slot == 1) ? -dist : dist; pos = vector3d(xpos,5000,zpos); vel = vector3d(0.0); rot.RotateX(M_PI/2); } ship->SetFrame(station->GetFrame()); ship->SetVelocity(vel); ship->SetPosition(pos); ship->SetRotMatrix(rot); Pi::game->GetSpace()->AddBody(ship); ship->AIHoldPosition(); LuaShip::PushToLua(ship); LUA_DEBUG_END(l, 1); return 1; }