// XXX this whole thing should be done by Lua void SpaceStation::DoLawAndOrder(const double timeStep) { Sint64 fine, crimeBitset; Polit::GetCrime(&crimeBitset, &fine); if (Pi::player->GetFlightState() != Ship::DOCKED && m_numPoliceDocked && (fine > 1000) && (GetPositionRelTo(Pi::player).Length() < 100000.0)) { int port = GetFreeDockingPort(); // at 60 Hz updates (ie, 1x time acceleration), // this spawns a police ship with probability ~0.83% each frame // This makes it unlikely (but not impossible) that police will spawn on top of each other // the expected number of game-time seconds between spawns: 120 (2*60 Hz) // variance is quite high though if (port != -1 && 2.0*Pi::rng.Double() < timeStep) { m_numPoliceDocked--; // Make police ship intent on killing the player Ship *ship = new Ship(ShipType::POLICE); ship->AIKill(Pi::player); ship->SetFrame(GetFrame()); ship->SetDockedWith(this, port); Pi::game->GetSpace()->AddBody(ship); ship->SetLabel(Lang::POLICE_SHIP_REGISTRATION); ship->m_equipment.Set(Equip::SLOT_LASER, 0, Equip::PULSECANNON_DUAL_1MW); ship->m_equipment.Add(Equip::LASER_COOLING_BOOSTER); ship->m_equipment.Add(Equip::ATMOSPHERIC_SHIELDING); ship->UpdateStats(); } } }
void SpaceStation::DoLawAndOrder() { Sint64 fine, crimeBitset; Polit::GetCrime(&crimeBitset, &fine); bool isDocked = static_cast<Ship*>(Pi::player)->GetDockedWith() ? true : false; if (Pi::player->GetFlightState() != Ship::DOCKED && m_numPoliceDocked && (fine > 1000) && (GetPositionRelTo(static_cast<Body*>(Pi::player)).Length() < 100000.0)) { int port = GetFreeDockingPort(); if (port != -1) { m_numPoliceDocked--; // Make police ship intent on killing the player Ship *ship = new Ship(ShipType::LADYBIRD); ship->AIKill(Pi::player); ship->SetFrame(GetFrame()); ship->SetDockedWith(this, port); Space::AddBody(ship); { // blue and white thang ShipFlavour f; f.type = ShipType::LADYBIRD; strncpy(f.regid, "POLICE", 16); f.price = ship->GetFlavour()->price; LmrMaterial m; m.diffuse[0] = 0.0f; m.diffuse[1] = 0.0f; m.diffuse[2] = 1.0f; m.diffuse[3] = 1.0f; m.specular[0] = 0.0f; m.specular[1] = 0.0f; m.specular[2] = 1.0f; m.specular[3] = 1.0f; m.emissive[0] = 0.0f; m.emissive[1] = 0.0f; m.emissive[2] = 0.0f; m.emissive[3] = 0.0f; m.shininess = 50.0f; f.primaryColor = m; m.shininess = 0.0f; m.diffuse[0] = 1.0f; m.diffuse[1] = 1.0f; m.diffuse[2] = 1.0f; m.diffuse[3] = 1.0f; f.secondaryColor = m; ship->ResetFlavour(&f); } ship->m_equipment.Set(Equip::SLOT_LASER, 0, Equip::PULSECANNON_DUAL_1MW); ship->m_equipment.Add(Equip::SHIELD_GENERATOR); ship->m_equipment.Add(Equip::LASER_COOLING_BOOSTER); ship->m_equipment.Add(Equip::ATMOSPHERIC_SHIELDING); ship->UpdateMass(); } } }
void Body::UpdateFrame() { if (!(m_flags & FLAG_CAN_MOVE_FRAME)) return; // falling out of frames if (m_frame->GetRadius() < GetPosition().Length()) { Frame *newFrame = GetFrame()->GetParent(); if (newFrame) { // don't fall out of root frame Output("%s leaves frame %s\n", GetLabel().c_str(), GetFrame()->GetLabel().c_str()); SwitchToFrame(newFrame); return; } } // entering into frames for (Frame* kid : m_frame->GetChildren()) { vector3d pos = GetPositionRelTo(kid); if (pos.Length() >= kid->GetRadius()) continue; SwitchToFrame(kid); Output("%s enters frame %s\n", GetLabel().c_str(), kid->GetLabel().c_str()); break; } }
void Body::UpdateFrame() { if (!(m_flags & FLAG_CAN_MOVE_FRAME)) return; // falling out of frames if (m_frame->GetRadius() < GetPosition().Length()) { Frame *newFrame = GetFrame()->GetParent(); if (newFrame) { // don't fall out of root frame printf("%s leaves frame %s\n", GetLabel().c_str(), GetFrame()->GetLabel().c_str()); SwitchToFrame(newFrame); return; } } // entering into frames for (Frame::ChildIterator it = m_frame->BeginChildren(); it != m_frame->EndChildren(); ++it) { vector3d pos = GetPositionRelTo(*it); if (pos.Length() >= (*it)->GetRadius()) continue; SwitchToFrame(*it); printf("%s enters frame %s\n", GetLabel().c_str(), (*it)->GetLabel().c_str()); break; } }
vector3d Body::GetPositionRelTo(const Body *relTo) const { return GetPositionRelTo(relTo->GetFrame()) - relTo->GetPosition(); }
void Ship::UpdateAlertState() { // no alerts if no radar int radar_cap = 0; Properties().Get("radar_cap", radar_cap); if (radar_cap <= 0) { // clear existing alert state if there was one if (GetAlertState() != ALERT_NONE) { SetAlertState(ALERT_NONE); LuaEvent::Queue("onShipAlertChanged", this, EnumStrings::GetString("ShipAlertStatus", ALERT_NONE)); } return; } bool ship_is_near = false, ship_is_firing = false; if (m_lastAlertUpdate + 1.0 <= Pi::game->GetTime()) { // time to update the list again, once per second should suffice m_lastAlertUpdate = Pi::game->GetTime(); // refresh the list m_nearbyBodies.clear(); static const double ALERT_DISTANCE = 100000.0; // 100km Pi::game->GetSpace()->GetBodiesMaybeNear(this, ALERT_DISTANCE, m_nearbyBodies); // handle the results for (auto i : m_nearbyBodies) { if ((i) == this) continue; if (!(i)->IsType(Object::SHIP) || (i)->IsType(Object::MISSILE)) continue; const Ship *ship = static_cast<const Ship*>(i); if (ship->GetShipType()->tag == ShipType::TAG_STATIC_SHIP) continue; if (ship->GetFlightState() == LANDED || ship->GetFlightState() == DOCKED) continue; if (GetPositionRelTo(ship).LengthSqr() < ALERT_DISTANCE*ALERT_DISTANCE) { ship_is_near = true; Uint32 gunstate = 0; for (int j = 0; j < ShipType::GUNMOUNT_MAX; j++) gunstate |= ship->m_gun[j].state; if (gunstate) { ship_is_firing = true; break; } } } // store m_shipNear = ship_is_near; m_shipFiring = ship_is_firing; } else { ship_is_near = m_shipNear; ship_is_firing = m_shipFiring; } bool changed = false; switch (m_alertState) { case ALERT_NONE: if (ship_is_near) { SetAlertState(ALERT_SHIP_NEARBY); changed = true; } if (ship_is_firing) { m_lastFiringAlert = Pi::game->GetTime(); SetAlertState(ALERT_SHIP_FIRING); changed = true; } break; case ALERT_SHIP_NEARBY: if (!ship_is_near) { SetAlertState(ALERT_NONE); changed = true; } else if (ship_is_firing) { m_lastFiringAlert = Pi::game->GetTime(); SetAlertState(ALERT_SHIP_FIRING); changed = true; } break; case ALERT_SHIP_FIRING: if (!ship_is_near) { SetAlertState(ALERT_NONE); changed = true; } else if (ship_is_firing) { m_lastFiringAlert = Pi::game->GetTime(); } else if (m_lastFiringAlert + 60.0 <= Pi::game->GetTime()) { SetAlertState(ALERT_SHIP_NEARBY); changed = true; } break; } if (changed) LuaEvent::Queue("onShipAlertChanged", this, EnumStrings::GetString("ShipAlertStatus", GetAlertState())); }
void Ship::UpdateAlertState() { // no alerts if no scanner if (m_equipment.Get(Equip::SLOT_SCANNER) == Equip::NONE) { // clear existing alert state if there was one if (GetAlertState() != ALERT_NONE) { SetAlertState(ALERT_NONE); Pi::luaOnShipAlertChanged->Queue(this, LuaConstants::GetConstantString(Pi::luaManager->GetLuaState(), "ShipAlertStatus", ALERT_NONE)); } return; } bool ship_is_near = false, ship_is_firing = false; for (Space::bodiesIter_t i = Space::bodies.begin(); i != Space::bodies.end(); i++) { if ((*i) == this) continue; if (!(*i)->IsType(Object::SHIP) || (*i)->IsType(Object::MISSILE)) continue; Ship *ship = static_cast<Ship*>(*i); if (ship->GetFlightState() == LANDED || ship->GetFlightState() == DOCKED) continue; if (GetPositionRelTo(ship).LengthSqr() < 100000.0*100000.0) { ship_is_near = true; Uint32 gunstate = 0; for (int j = 0; j < ShipType::GUNMOUNT_MAX; j++) gunstate |= ship->m_gunState[j]; if (gunstate) { ship_is_firing = true; break; } } } bool changed = false; switch (m_alertState) { case ALERT_NONE: if (ship_is_near) { SetAlertState(ALERT_SHIP_NEARBY); changed = true; } if (ship_is_firing) { m_lastFiringAlert = Pi::GetGameTime(); SetAlertState(ALERT_SHIP_FIRING); changed = true; } break; case ALERT_SHIP_NEARBY: if (!ship_is_near) { SetAlertState(ALERT_NONE); changed = true; } else if (ship_is_firing) { m_lastFiringAlert = Pi::GetGameTime(); SetAlertState(ALERT_SHIP_FIRING); changed = true; } break; case ALERT_SHIP_FIRING: if (!ship_is_near) { SetAlertState(ALERT_NONE); changed = true; } else if (ship_is_firing) { m_lastFiringAlert = Pi::GetGameTime(); } else if (m_lastFiringAlert + 60.0 <= Pi::GetGameTime()) { SetAlertState(ALERT_SHIP_NEARBY); changed = true; } break; } if (changed) Pi::luaOnShipAlertChanged->Queue(this, LuaConstants::GetConstantString(Pi::luaManager->GetLuaState(), "ShipAlertStatus", GetAlertState())); }
void Ship::UpdateAlertState() { // no alerts if no scanner if (m_equipment.Get(Equip::SLOT_SCANNER) == Equip::NONE) { // clear existing alert state if there was one if (GetAlertState() != ALERT_NONE) { SetAlertState(ALERT_NONE); LuaEvent::Queue("onShipAlertChanged", this, EnumStrings::GetString("ShipAlertStatus", ALERT_NONE)); } return; } static const double ALERT_DISTANCE = 100000.0; // 100km Space::BodyNearList nearby; Pi::game->GetSpace()->GetBodiesMaybeNear(this, ALERT_DISTANCE, nearby); bool ship_is_near = false, ship_is_firing = false; for (Space::BodyNearIterator i = nearby.begin(); i != nearby.end(); ++i) { if ((*i) == this) continue; if (!(*i)->IsType(Object::SHIP) || (*i)->IsType(Object::MISSILE)) continue; const Ship *ship = static_cast<const Ship*>(*i); if (ship->GetShipType().tag == ShipType::TAG_STATIC_SHIP) continue; if (ship->GetFlightState() == LANDED || ship->GetFlightState() == DOCKED) continue; if (GetPositionRelTo(ship).LengthSqr() < ALERT_DISTANCE*ALERT_DISTANCE) { ship_is_near = true; Uint32 gunstate = 0; for (int j = 0; j < ShipType::GUNMOUNT_MAX; j++) gunstate |= ship->m_gunState[j]; if (gunstate) { ship_is_firing = true; break; } } } bool changed = false; switch (m_alertState) { case ALERT_NONE: if (ship_is_near) { SetAlertState(ALERT_SHIP_NEARBY); changed = true; } if (ship_is_firing) { m_lastFiringAlert = Pi::game->GetTime(); SetAlertState(ALERT_SHIP_FIRING); changed = true; } break; case ALERT_SHIP_NEARBY: if (!ship_is_near) { SetAlertState(ALERT_NONE); changed = true; } else if (ship_is_firing) { m_lastFiringAlert = Pi::game->GetTime(); SetAlertState(ALERT_SHIP_FIRING); changed = true; } break; case ALERT_SHIP_FIRING: if (!ship_is_near) { SetAlertState(ALERT_NONE); changed = true; } else if (ship_is_firing) { m_lastFiringAlert = Pi::game->GetTime(); } else if (m_lastFiringAlert + 60.0 <= Pi::game->GetTime()) { SetAlertState(ALERT_SHIP_NEARBY); changed = true; } break; } if (changed) LuaEvent::Queue("onShipAlertChanged", this, EnumStrings::GetString("ShipAlertStatus", GetAlertState())); }