void Chaser::Update() { bool before = IsOnScreen(); if ( _timer ) _timer--; if ( _timer <= 0 ) { _timer = TIME * ( _move + 1 ); _move = !_move; if ( _move ) { Ship* p = GetNearestPlayer(); _dir = p->GetPosition() - GetPosition(); _dir.Normalise(); _dir *= SPEED; } } if ( _move ) { Move( _dir ); if ( !before && IsOnScreen() ) { _move = false; } } else { Rotate( M_PT_ONE ); } }
/* * Method: GetPosition * * Get the ships position * * > ship:GetPosition() * * Availability: * * April 2016 * * Status: * * experimental */ static int l_ship_get_position(lua_State *l) { Ship *s = LuaObject<Ship>::CheckFromLua(1); vector3d v = s->GetPosition(); lua_newtable(l); pi_lua_settable(l, "x", v.x); pi_lua_settable(l, "y", v.y); pi_lua_settable(l, "z", v.z); return 1; }
bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel) { if ((flags & 0x10) && (b->IsType(Object::SHIP))) { Ship *s = static_cast<Ship*>(b); int port = -1; for (int i=0; i<MAX_DOCKING_PORTS; i++) { if (m_shipDocking[i].ship == s) { port = i; break; } } if (port == -1) return false; // no permission if (!m_type->dockOneAtATimePlease) { if (port != int(flags & 0xf)) return false; // wrong port } if (m_shipDocking[port].stage != 1) return false; // already docking? SpaceStationType::positionOrient_t dport; // why stage 2? Because stage 1 is permission to dock // granted, stage 2 is start of docking animation. PiVerify(m_type->GetDockAnimPositionOrient(port, 2, 0.0, vector3d(0.0), dport, s)); // must be oriented sensibly and have wheels down if (IsGroundStation()) { vector3d dockingNormal = GetOrient()*dport.yaxis; const double dot = s->GetOrient().VectorY().Dot(dockingNormal); if ((dot < 0.99) || (s->GetWheelState() < 1.0)) return false; // <0.99 harsh? if (s->GetVelocity().Length() > MAX_LANDING_SPEED) return false; } // if there is more docking port anim to do, don't set docked yet if (m_type->numDockingStages >= 2) { shipDocking_t &sd = m_shipDocking[port]; sd.ship = s; sd.stage = 2; sd.stagePos = 0; sd.fromPos = (s->GetPosition() - GetPosition()) * GetOrient(); // station space sd.fromRot = Quaterniond::FromMatrix3x3(GetOrient().Transpose() * s->GetOrient()); if (m_type->dockOneAtATimePlease) m_dockingLock = true; s->SetFlightState(Ship::DOCKING); s->SetVelocity(vector3d(0.0)); s->SetAngVelocity(vector3d(0.0)); s->ClearThrusterState(); } else { s->SetDockedWith(this, port); // bounces back to SS::SetDocked() LuaEvent::Queue("onShipDocked", s, this); } return false; } else { return true; } }
bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel) { if ((flags & 0x10) && (b->IsType(Object::SHIP))) { Ship *s = static_cast<Ship*>(b); matrix4x4d rot; GetRotMatrix(rot); bool canDock = true; int port = -1; for (int i=0; i<MAX_DOCKING_PORTS; i++) { if (m_shipDocking[i].ship == s) { port = i; break; } } if (m_type->dockOneAtATimePlease) { for (int i=0; i<m_type->numDockingPorts; i++) { if (m_shipDocking[i].ship && m_shipDocking[i].stage != 1 && (m_shipDocking[i].stage != m_type->numDockingStages+1)) { canDock = false; break; } } } else { // for non-dockOneAtATimePlease, the ship is expected // to hit the right docking trigger surface for that port if (m_shipDocking[flags&0xf].ship != s) canDock = false; } if (port == -1) canDock = false; // hitting docking area of a station if (canDock) { SpaceStationType::positionOrient_t dport; // why stage 2? Because stage 1 is permission to dock // granted, stage 2 is start of docking animation. PiVerify(m_type->GetDockAnimPositionOrient(port, 2, 0.0f, vector3d(0.0), dport, s)); double speed = s->GetVelocity().Length(); // must be oriented sensibly and have wheels down if (IsGroundStation()) { matrix4x4d shiprot; s->GetRotMatrix(shiprot); matrix4x4d invShipRot = shiprot.InverseOf(); vector3d dockingNormal = rot*dport.yaxis; // check player is sortof sensibly oriented for landing const double dot = vector3d(invShipRot[1], invShipRot[5], invShipRot[9]).Dot(dockingNormal); if ((dot < 0.99) || (s->GetWheelState() < 1.0)) return false; } if ((speed < MAX_LANDING_SPEED) && (!s->GetDockedWith()) && (m_shipDocking[port].stage == 1)) { // if there is more docking port anim to do, // don't set docked yet if (m_type->numDockingStages >= 2) { shipDocking_t &sd = m_shipDocking[port]; sd.ship = s; sd.stage = 2; sd.stagePos = 0; sd.fromPos = rot.InverseOf() * (s->GetPosition() - GetPosition()); matrix4x4d temp; s->GetRotMatrix(temp); sd.fromRot = Quaterniond::FromMatrix4x4(temp); s->Disable(); s->ClearThrusterState(); s->SetFlightState(Ship::DOCKING); } else { s->SetDockedWith(this, port); LuaEvent::Queue("onShipDocked", s, this); } } } return false; } else { return true; } }
void PlayerController::ProcessControls() { if(Game->GetCurrentMode() == GM_PLAY) { Ship *ship = (Ship *)SM->GetSceneByName("Main")->GetEntityByName("Player")->GetMeshByName("Player Ship"); Plane *lengine = (Plane *)SM->GetSceneByName("Main")->GetEntityByName("Player")->GetMeshByName("LEngine"); Plane *rengine = (Plane *)SM->GetSceneByName("Main")->GetEntityByName("Player")->GetMeshByName("REngine"); float magnitude = sqrtf(pow(GetMouseX()-ship->GetPosition().x,2)+pow(GetMouseY()-ship->GetPosition().y,2)); glm::vec3 dir = glm::vec3((GetMouseX()-ship->GetPosition().x),(GetMouseY()-ship->GetPosition().y),0)/magnitude; float rotSpeed=10.0f; float maxspeed = 12.0f; float acceleration = 0.5f; glm::vec3 vel = ship->GetThrottle(); float accelerating = lengine->GetScale().x; if(keys[SDLK_RIGHT]) // If the right arrow key is pressed { ship->Rotate(glm::vec3(0.0f,0.0f,+rotSpeed)); // Rotate the ship clockwise } if(keys[SDLK_LEFT]) // If the right arrow key is pressed { ship->Rotate(glm::vec3(0.0f,0.0f,-rotSpeed)); // Rotate the ship clockwise } if(keys['w']) { if(magnitude > -maxspeed) // If the throttle is less than max { vel += 0.5f*dir*acceleration; } else { vel -= maxspeed; } if(accelerating < 1.0f) accelerating += .05f; else accelerating = 1.0f; } else { if(accelerating > 0) accelerating -= .05f; else accelerating = 0.0f; } if(vel.x > 0 && vel.x < 0.1f) // If the throttle is close to zero { vel.x=0; // Go ahead and set it to zero (no need to waste fuel) } if(vel.y > 0 && vel.y < 0.1f) // If the throttle is close to zero { vel.y=0; // Go ahead and set it to zero (no need to waste fuel) } if(vel.x < 0 && vel.x > -0.1f) // If the throttle is close to zero { vel.x=0; // Go ahead and set it to zero (no need to waste fuel) } if(vel.y < 0 && vel.y > -0.1f) // If the throttle is close to zero { vel.y=0; // Go ahead and set it to zero (no need to waste fuel) } glm::vec3 pos = ship->GetPosition(); if(pos.x > WM->GetWindowWidth()+16.0f) { pos.x = -16.0f; ship->SetPosition(pos); } else if(pos.x < -16.0f) { pos.x = WM->GetWindowWidth()+16.0f; ship->SetPosition(pos); } if(pos.y > WM->GetWindowHeight()+16.0f) { pos.y = -16.0f; ship->SetPosition(pos); } else if(pos.y < -16.0f) { pos.y = WM->GetWindowHeight()+16.0f; ship->SetPosition(pos); } ship->SetThrottle(vel); ship->Translate(vel); pos = ship->GetPosition(); glm::vec3 rot = glm::vec3(0,0,-(atan2(mouse_x-pos.x,mouse_y-pos.y)+3.14159)*180/3.14159); ship->SetRotation(rot); if(!lengine || !rengine) return; lengine->SetOrigin(-50,0); lengine->SetPosition(pos); lengine->SetRotation(rot); float lscalemod = rand()%10/100.0f-0.05f; float rscalemod = rand()%10/100.0f-0.05f; glm::vec3 lscale = glm::vec3(accelerating+lscalemod,accelerating+lscalemod,accelerating+lscalemod); glm::vec3 rscale = glm::vec3(accelerating+rscalemod,accelerating+rscalemod,accelerating+rscalemod); lengine->SetScale(lscale); rengine->SetScale(rscale); rengine->SetPosition(pos); rengine->SetRotation(rot); } }
/* * Method: GetPosition * * Get the ships velocity * * > ship:GetPosition() * * Availability: * * April 2016 * * Status: * * experimental */ static int l_ship_get_position(lua_State *l) { Ship *s = LuaObject<Ship>::CheckFromLua(1); LuaVector::PushToLua(l, s->GetPosition()); return 1; }