hyperspace cloud analyzer. arrival clouds are not created yet so you can't follow ships
git-svn-id: https://pioneer.svn.sourceforge.net/svnroot/pioneer/trunk@475 e632f14b-6550-0410-b89e-a82653faca30master
parent
0db47d2c3e
commit
347874217e
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -10,6 +10,7 @@
|
|||
#include "Player.h"
|
||||
#include "Projectile.h"
|
||||
#include "Missile.h"
|
||||
#include "HyperspaceCloud.h"
|
||||
|
||||
Body::Body()
|
||||
{
|
||||
|
@ -22,8 +23,6 @@ Body::Body()
|
|||
|
||||
Body::~Body()
|
||||
{
|
||||
// Do not call delete body. Call Space::KillBody(body).
|
||||
assert(m_dead);
|
||||
}
|
||||
|
||||
void Body::Save()
|
||||
|
@ -59,6 +58,7 @@ void Body::Serialize()
|
|||
case Object::MISSILE:
|
||||
case Object::CARGOBODY:
|
||||
case Object::PROJECTILE:
|
||||
case Object::HYPERSPACECLOUD:
|
||||
Save();
|
||||
break;
|
||||
default:
|
||||
|
@ -92,6 +92,8 @@ Body *Body::Unserialize()
|
|||
b = new Projectile(); break;
|
||||
case Object::CARGOBODY:
|
||||
b = new CargoBody(); break;
|
||||
case Object::HYPERSPACECLOUD:
|
||||
b = new HyperspaceCloud(); break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
virtual void SetFrame(Frame *f) { m_frame = f; }
|
||||
// return true if to do collision response and apply damage
|
||||
virtual bool OnCollision(Object *o, Uint32 flags, double relVel) { return false; }
|
||||
// Attacker may be null
|
||||
virtual bool OnDamage(Object *attacker, float kgDamage) { return false; }
|
||||
virtual void OnHaveKilled(Body *guyWeKilled) {}
|
||||
virtual void TimeStepUpdate(const float timeStep) {}
|
||||
|
@ -36,8 +37,9 @@ public:
|
|||
// StaticUpdate() is called. Good for special collision testing (Projectiles)
|
||||
// as you can't test for collisions if different objects are on different 'steps'
|
||||
virtual void StaticUpdate(const float timeStep) {}
|
||||
// Override to clear any pointers you hold to the dying body.
|
||||
virtual void NotifyDeath(const Body* const dyingBody) {}
|
||||
// Note: Does not mean killed, just deleted.
|
||||
// Override to clear any pointers you hold to the body
|
||||
virtual void NotifyDeleted(const Body* const deletedBody) {}
|
||||
vector3d GetVelocityRelativeTo(const Body *other) const;
|
||||
vector3d GetVelocityRelativeTo(const Frame *f) const;
|
||||
// for putting on planet surface, oriented +y up
|
||||
|
|
|
@ -162,6 +162,12 @@ const EquipType EquipType::types[Equip::TYPE_MAX] = {
|
|||
Equip::SLOT_RADARMAPPER, {},
|
||||
90000, 1, 1,
|
||||
0, 3
|
||||
},{
|
||||
"Hypercloud Analyzer",
|
||||
"Analyze hyperspace clouds to determine destination and time of arrival or departure.",
|
||||
Equip::SLOT_HYPERCLOUD, {},
|
||||
150000, 1, 1,
|
||||
0, 3
|
||||
},{
|
||||
"Interplanetary Drive",0,
|
||||
Equip::SLOT_ENGINE, {},
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
#define _EQUIPTYPE_H
|
||||
|
||||
namespace Equip {
|
||||
enum Slot { SLOT_CARGO, SLOT_ENGINE, SLOT_LASER, SLOT_MISSILE, SLOT_ECM, SLOT_SCANNER, SLOT_RADARMAPPER, SLOT_MAX };
|
||||
enum Slot { SLOT_CARGO, SLOT_ENGINE, SLOT_LASER, SLOT_MISSILE, SLOT_ECM, SLOT_SCANNER, SLOT_RADARMAPPER, SLOT_HYPERCLOUD, SLOT_MAX };
|
||||
enum Type { NONE, HYDROGEN, LIQUID_OXYGEN, METAL_ORE, CARBON_ORE, METAL_ALLOYS, PLASTICS, FRUIT_AND_VEG, ANIMAL_MEAT, LIQUOR, GRAIN, TEXTILES, FERTILIZER, WATER, MEDICINES, CONSUMER_GOODS, COMPUTERS, ROBOTS, PRECIOUS_METALS, INDUSTRIAL_MACHINERY, FARM_MACHINERY, MINING_MACHINERY, AIR_PROCESSORS, HAND_WEAPONS, BATTLE_WEAPONS, NERVE_GAS, NARCOTICS,
|
||||
|
||||
MISSILE_UNGUIDED, MISSILE_GUIDED, MISSILE_SMART, MISSILE_NAVAL, ECM_BASIC, SCANNER, ECM_ADVANCED, SHIELD_GENERATOR,
|
||||
RADAR_MAPPER,
|
||||
RADAR_MAPPER, HYPERCLOUD_ANALYZER,
|
||||
DRIVE_INTERPLANETARY, DRIVE_CLASS1, DRIVE_CLASS2, DRIVE_CLASS3, DRIVE_CLASS4, DRIVE_CLASS5, DRIVE_CLASS6, DRIVE_CLASS7,
|
||||
PULSECANNON_1MW, PULSECANNON_DUAL_1MW, PULSECANNON_2MW, PULSECANNON_4MW, PULSECANNON_10MW, PULSECANNON_20MW, TYPE_MAX,
|
||||
FIRST_COMMODITY=HYDROGEN, LAST_COMMODITY=NARCOTICS,
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
#include "libs.h"
|
||||
#include "HyperspaceCloud.h"
|
||||
#include "Pi.h"
|
||||
#include "Ship.h"
|
||||
#include "Serializer.h"
|
||||
#include "Shader.h"
|
||||
|
||||
HyperspaceCloud::HyperspaceCloud(Ship *s, double dueDate)
|
||||
{
|
||||
m_ship = s;
|
||||
m_pos = vector3d(0,0,0);
|
||||
m_birthdate = Pi::GetGameTime();
|
||||
m_due = dueDate;
|
||||
}
|
||||
|
||||
HyperspaceCloud::HyperspaceCloud()
|
||||
{
|
||||
m_ship = 0;
|
||||
m_pos = vector3d(0,0,0);
|
||||
}
|
||||
|
||||
HyperspaceCloud::~HyperspaceCloud()
|
||||
{
|
||||
if (m_ship) delete m_ship;
|
||||
}
|
||||
|
||||
vector3d HyperspaceCloud::GetPosition() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
void HyperspaceCloud::SetPosition(vector3d p)
|
||||
{
|
||||
m_pos = p;
|
||||
}
|
||||
|
||||
void HyperspaceCloud::Save()
|
||||
{
|
||||
using namespace Serializer::Write;
|
||||
Body::Save();
|
||||
wr_vector3d(m_pos);
|
||||
wr_double(m_birthdate);
|
||||
wr_double(m_due);
|
||||
m_ship->Serialize();
|
||||
}
|
||||
|
||||
void HyperspaceCloud::Load()
|
||||
{
|
||||
using namespace Serializer::Read;
|
||||
Body::Load();
|
||||
m_pos = rd_vector3d();
|
||||
m_birthdate = rd_double();
|
||||
m_due = rd_double();
|
||||
m_ship = (Ship*)Body::Unserialize();
|
||||
}
|
||||
|
||||
void HyperspaceCloud::PostLoadFixup()
|
||||
{
|
||||
m_ship->PostLoadFixup();
|
||||
}
|
||||
|
||||
void HyperspaceCloud::Render(const Frame *a_camFrame)
|
||||
{
|
||||
Shader::EnableVertexProgram(Shader::VPROG_SIMPLE);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
glPushMatrix();
|
||||
vector3d fpos = GetPositionRelTo(a_camFrame);
|
||||
glTranslatef((float)fpos.x, (float)fpos.y, (float)fpos.z);
|
||||
glColor4f(1.0,1.0,1.0,0.5);
|
||||
gluSphere(Pi::gluQuadric, 25.0, 20, 20);
|
||||
glColor4f(.5,.5,1.0,0.5);
|
||||
gluSphere(Pi::gluQuadric, 50.0, 20, 20);
|
||||
glColor4f(0,0,1.0,0.5);
|
||||
gluSphere(Pi::gluQuadric, 100.0, 20, 20);
|
||||
glPopMatrix();
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_LIGHTING);
|
||||
Shader::DisableVertexProgram();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef _HYPERSPACECLOUD_H
|
||||
#define _HYPERSPACECLOUD_H
|
||||
|
||||
#include "Body.h"
|
||||
|
||||
class Frame;
|
||||
class Ship;
|
||||
|
||||
class HyperspaceCloud: public Body {
|
||||
public:
|
||||
OBJDEF(HyperspaceCloud, Body, HYPERSPACECLOUD);
|
||||
HyperspaceCloud(Ship *, double dateDue);
|
||||
HyperspaceCloud();
|
||||
virtual ~HyperspaceCloud();
|
||||
virtual void SetPosition(vector3d p);
|
||||
virtual vector3d GetPosition() const;
|
||||
virtual double GetRadius() const { return 10.0; }
|
||||
virtual void Render(const Frame *camFrame);
|
||||
virtual void PostLoadFixup();
|
||||
Ship *GetShip() { return m_ship; }
|
||||
double GetDueDate() const { return m_due; }
|
||||
protected:
|
||||
virtual void Save();
|
||||
virtual void Load();
|
||||
private:
|
||||
Ship *m_ship;
|
||||
vector3d m_pos;
|
||||
double m_birthdate;
|
||||
double m_due;
|
||||
};
|
||||
|
||||
#endif /* _HYPERSPACECLOUD_H */
|
|
@ -13,7 +13,7 @@ include_HEADERS = Body.h Frame.h GenericSystemView.h glfreetype.h GuiButton.h Gu
|
|||
NameGenerator.h perlin.h GeoSphere.h GuiBox.h ShipFlavour.h GuiTextLayout.h Mission.h pirates.h Polit.h \
|
||||
CityOnPlanet.h Shader.h ShipCpanelMultiFuncDisplays.h Projectile.h Render.h Sound.h GuiRepeaterButton.h \
|
||||
CommodityTradeWidget.h GenericChatForm.h PoliceChatForm.h SysLoc.h PersistSystemData.h GalacticView.h \
|
||||
Galaxy.h GameMenuView.h GuiTextEntry.h Missile.h
|
||||
Galaxy.h GameMenuView.h GuiTextEntry.h Missile.h HyperspaceCloud.h
|
||||
|
||||
libgui_a_SOURCES = GuiButton.cpp Gui.cpp GuiFixed.cpp GuiScreen.cpp GuiLabel.cpp GuiToolTip.cpp GuiToggleButton.cpp GuiRadioButton.cpp \
|
||||
GuiRadioGroup.cpp GuiImageButton.cpp GuiImage.cpp GuiImageRadioButton.cpp GuiMultiStateImageButton.cpp GuiWidget.cpp \
|
||||
|
@ -28,7 +28,7 @@ pioneer_SOURCES = main.cpp glfreetype.cpp Body.cpp Space.cpp Ship.cpp Player.cpp
|
|||
EquipType.cpp CargoBody.cpp NameGenerator.cpp perlin.cpp GeoSphere.cpp Pi.cpp ShipFlavour.cpp \
|
||||
Mission.cpp pirates.cpp Polit.cpp CityOnPlanet.cpp Shader.cpp ShipCpanelMultiFuncDisplays.cpp \
|
||||
Projectile.cpp Render.cpp Sound.cpp CommodityTradeWidget.cpp GenericChatForm.cpp PoliceChatForm.cpp \
|
||||
SysLoc.cpp GalacticView.cpp Galaxy.cpp GameMenuView.cpp Missile.cpp
|
||||
SysLoc.cpp GalacticView.cpp Galaxy.cpp GameMenuView.cpp Missile.cpp HyperspaceCloud.cpp
|
||||
pioneer_LDADD = sbre/libsbre.a collider/libcollider.a missions/libmissions.a libgui.a
|
||||
|
||||
sbreviewer_SOURCES = SbreViewer.cpp glfreetype.cpp ModelCollMeshData.cpp
|
||||
|
|
|
@ -81,12 +81,12 @@ void Missile::Explode()
|
|||
Sfx::Add(this, Sfx::TYPE_EXPLOSION);
|
||||
}
|
||||
|
||||
void Missile::NotifyDeath(const Body* const dyingBody)
|
||||
void Missile::NotifyDeleted(const Body* const deletedBody)
|
||||
{
|
||||
if (m_owner == dyingBody) {
|
||||
if (m_owner == deletedBody) {
|
||||
Explode();
|
||||
}
|
||||
else if (m_target == dyingBody) {
|
||||
else if (m_target == deletedBody) {
|
||||
Explode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ public:
|
|||
virtual ~Missile() {}
|
||||
void TimeStepUpdate(const float timeStep);
|
||||
bool OnDamage(Object *attacker, float kgDamage);
|
||||
virtual void NotifyDeath(const Body* const dyingBody);
|
||||
virtual void NotifyDeleted(const Body* const deletedBody);
|
||||
virtual void PostLoadFixup();
|
||||
void ECMAttack(int power_val);
|
||||
protected:
|
||||
|
|
10
src/Object.h
10
src/Object.h
|
@ -3,13 +3,13 @@
|
|||
|
||||
class Object {
|
||||
public:
|
||||
enum Type { OBJECT, BODY, MODELBODY, DYNAMICBODY, SHIP, PLAYER, SPACESTATION, PLANET, STAR, CARGOBODY, CITYONPLANET, PROJECTILE, MISSILE };
|
||||
virtual Type GetType() { return OBJECT; }
|
||||
virtual bool IsType(Type c) { return GetType() == c; }
|
||||
enum Type { OBJECT, BODY, MODELBODY, DYNAMICBODY, SHIP, PLAYER, SPACESTATION, PLANET, STAR, CARGOBODY, CITYONPLANET, PROJECTILE, MISSILE, HYPERSPACECLOUD };
|
||||
virtual Type GetType() const { return OBJECT; }
|
||||
virtual bool IsType(Type c) const { return GetType() == c; }
|
||||
};
|
||||
#define OBJDEF(__thisClass,__parentClass,__TYPE) \
|
||||
virtual Object::Type GetType() { return Object::__TYPE; } \
|
||||
virtual bool IsType(Type c) { \
|
||||
virtual Object::Type GetType() const { return Object::__TYPE; } \
|
||||
virtual bool IsType(Type c) const { \
|
||||
if (__thisClass::GetType() == (c)) return true; \
|
||||
else return __parentClass::IsType(c); }
|
||||
#endif /* _OBJECT_H */
|
||||
|
|
|
@ -71,7 +71,7 @@ bool Pi::showDebugInfo;
|
|||
int Pi::statSceneTris;
|
||||
bool Pi::isGameStarted = false;
|
||||
struct DetailLevel Pi::detail = { 1, 1 };
|
||||
const float Pi::timeAccelRates[] = { 0.0, 1.0, 10.0, 100.0, 1000.0, 10000.0 };
|
||||
const float Pi::timeAccelRates[] = { 0.0, 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0 };
|
||||
const char * const Pi::combatRating[] = {
|
||||
"Harmless",
|
||||
"Mostly harmless",
|
||||
|
@ -324,10 +324,15 @@ void Pi::HandleEvents()
|
|||
ship->SetFrame(Pi::player->GetFrame());
|
||||
ship->SetPosition(Pi::player->GetPosition()+100.0*dir);
|
||||
ship->SetVelocity(Pi::player->GetVelocity());
|
||||
ship->m_equipment.Add(Equip::DRIVE_CLASS1);
|
||||
ship->m_equipment.Add(Equip::DRIVE_CLASS2);
|
||||
ship->m_equipment.Add(Equip::RADAR_MAPPER);
|
||||
ship->m_equipment.Add(Equip::SCANNER);
|
||||
ship->m_equipment.Add(Equip::SHIELD_GENERATOR);
|
||||
ship->m_equipment.Add(Equip::HYDROGEN);
|
||||
ship->m_equipment.Add(Equip::HYDROGEN);
|
||||
ship->m_equipment.Add(Equip::HYDROGEN);
|
||||
ship->m_equipment.Add(Equip::HYDROGEN);
|
||||
ship->m_equipment.Add(Equip::HYDROGEN);
|
||||
Space::AddBody(ship);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ void Player::Save()
|
|||
}
|
||||
wr_int(m_killCount);
|
||||
wr_int(m_knownKillCount);
|
||||
m_hyperspaceTarget.Serialize();
|
||||
}
|
||||
|
||||
void Player::Load()
|
||||
|
@ -65,7 +64,6 @@ void Player::Load()
|
|||
m_killCount = 0;
|
||||
m_knownKillCount = 0;
|
||||
}
|
||||
SBodyPath::Unserialize(&m_hyperspaceTarget);
|
||||
}
|
||||
|
||||
void Player::OnHaveKilled(Body *guyWeKilled)
|
||||
|
@ -91,12 +89,6 @@ void Player::TakeMission(Mission *m)
|
|||
Pi::onPlayerMissionListChanged.emit();
|
||||
}
|
||||
|
||||
void Player::SetHyperspaceTarget(const SBodyPath *path)
|
||||
{
|
||||
m_hyperspaceTarget = *path;
|
||||
Pi::onPlayerChangeHyperspaceTarget.emit();
|
||||
}
|
||||
|
||||
void Player::SetFlightControlState(enum FlightControlState s)
|
||||
{
|
||||
m_flightControlState = s;
|
||||
|
|
|
@ -22,8 +22,6 @@ public:
|
|||
FlightControlState GetFlightControlState() const { return m_flightControlState; }
|
||||
void SetFlightControlState(FlightControlState s);
|
||||
float GetSetSpeed() const { return m_setSpeed; }
|
||||
const SBodyPath *GetHyperspaceTarget() const { return &m_hyperspaceTarget; }
|
||||
void SetHyperspaceTarget(const SBodyPath *path);
|
||||
void TakeMission(Mission *);
|
||||
const std::list<Mission*> &GetMissions() const { return m_missions; }
|
||||
virtual bool OnDamage(Object *attacker, float kgDamage);
|
||||
|
@ -40,7 +38,6 @@ private:
|
|||
float m_setSpeed;
|
||||
int m_killCount;
|
||||
int m_knownKillCount; // updated on docking
|
||||
SBodyPath m_hyperspaceTarget;
|
||||
};
|
||||
|
||||
#endif /* _PLAYER_H */
|
||||
|
|
|
@ -55,6 +55,11 @@ void Projectile::SetPosition(vector3d p)
|
|||
m_orient[14] = p.z;
|
||||
}
|
||||
|
||||
void Projectile::NotifyDeleted(const Body* const deletedBody)
|
||||
{
|
||||
if (m_parent == deletedBody) m_parent = 0;
|
||||
}
|
||||
|
||||
void Projectile::TimeStepUpdate(const float timeStep)
|
||||
{
|
||||
m_age += timeStep;
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
virtual void Render(const Frame *camFrame);
|
||||
void TimeStepUpdate(const float timeStep);
|
||||
void StaticUpdate(const float timeStep);
|
||||
virtual void NotifyDeleted(const Body* const deletedBody);
|
||||
|
||||
virtual void PostLoadFixup();
|
||||
protected:
|
||||
|
|
|
@ -305,7 +305,8 @@ void SectorView::Update()
|
|||
char buf[256];
|
||||
SBodyPath sbody_path(m_secx, m_secy, m_selected);
|
||||
int fuelRequired;
|
||||
bool canJump = Pi::player->CanHyperspaceTo(&sbody_path, fuelRequired);
|
||||
double dur;
|
||||
bool canJump = Pi::player->CanHyperspaceTo(&sbody_path, fuelRequired, dur);
|
||||
if (canJump) {
|
||||
snprintf(buf, sizeof(buf), "Dist. %.2f light years (fuel required: %dt)", dist, fuelRequired);
|
||||
} else if (fuelRequired) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "Player.h"
|
||||
#include "perlin.h"
|
||||
|
||||
void Ship::AIBodyHasDied(const Body* const body)
|
||||
void Ship::AIBodyDeleted(const Body* const body)
|
||||
{
|
||||
for (std::list<AIInstruction>::iterator i = m_todo.begin(); i != m_todo.end(); ) {
|
||||
switch ((*i).cmd) {
|
||||
|
@ -107,6 +107,7 @@ bool Ship::AICmdKamikaze(const Ship *enemy)
|
|||
return false;
|
||||
}
|
||||
|
||||
#include "Space.h"
|
||||
bool Ship::AICmdKill(const Ship *enemy)
|
||||
{
|
||||
SetGunState(0,0);
|
||||
|
@ -124,7 +125,9 @@ bool Ship::AICmdKill(const Ship *enemy)
|
|||
GetRotMatrix(rot);
|
||||
const vector3d zaxis = vector3d(-rot[8], -rot[9], -rot[10]);
|
||||
const float dot = vector3d::Dot(dir, vector3d(-rot[8], -rot[9], -rot[10]));
|
||||
if (dot > 0.95f) SetGunState(0,1);
|
||||
if (dot > 0.95f) {
|
||||
SetGunState(0,1);
|
||||
}
|
||||
} else {
|
||||
// if too close turn away!
|
||||
AIFaceDirection(-dir);
|
||||
|
|
72
src/Ship.cpp
72
src/Ship.cpp
|
@ -48,6 +48,10 @@ void Ship::Save()
|
|||
wr_float(m_launchLockTimeout);
|
||||
wr_bool(m_testLanded);
|
||||
wr_int((int)m_flightState);
|
||||
|
||||
m_hyperspace.dest.Serialize();
|
||||
wr_float(m_hyperspace.countdown);
|
||||
|
||||
for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) {
|
||||
wr_int(m_gunState[i]);
|
||||
wr_float(m_gunRecharge[i]);
|
||||
|
@ -90,6 +94,10 @@ void Ship::Load()
|
|||
m_launchLockTimeout = rd_float();
|
||||
m_testLanded = rd_bool();
|
||||
m_flightState = (FlightState) rd_int();
|
||||
|
||||
SBodyPath::Unserialize(&m_hyperspace.dest);
|
||||
m_hyperspace.countdown = rd_float();
|
||||
|
||||
for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) {
|
||||
m_gunState[i] = rd_int();
|
||||
if (IsOlderThan(3)) m_gunRecharge[i] = 0;
|
||||
|
@ -158,6 +166,7 @@ Ship::Ship(ShipType::Type shipType): DynamicBody()
|
|||
m_shipFlavour = ShipFlavour(shipType);
|
||||
m_angThrusters[0] = m_angThrusters[1] = m_angThrusters[2] = 0;
|
||||
m_equipment.InitSlotSizes(shipType);
|
||||
m_hyperspace.countdown = 0;
|
||||
for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) {
|
||||
m_gunState[i] = 0;
|
||||
m_gunRecharge[i] = 0;
|
||||
|
@ -169,6 +178,12 @@ Ship::Ship(ShipType::Type shipType): DynamicBody()
|
|||
Init();
|
||||
}
|
||||
|
||||
void Ship::SetHyperspaceTarget(const SBodyPath *path)
|
||||
{
|
||||
m_hyperspace.dest = *path;
|
||||
if (this == (Ship*)Pi::player) Pi::onPlayerChangeHyperspaceTarget.emit();
|
||||
}
|
||||
|
||||
float Ship::GetPercentHull() const
|
||||
{
|
||||
const ShipType &stype = GetShipType();
|
||||
|
@ -208,7 +223,7 @@ bool Ship::OnDamage(Object *attacker, float kgDamage)
|
|||
}
|
||||
m_stats.hull_mass_left -= dam;
|
||||
if (m_stats.hull_mass_left < 0) {
|
||||
if (attacker->IsType(Object::BODY)) static_cast<Body*>(attacker)->OnHaveKilled(this);
|
||||
if (attacker && attacker->IsType(Object::BODY)) static_cast<Body*>(attacker)->OnHaveKilled(this);
|
||||
Space::KillBody(this);
|
||||
Sfx::Add(this, Sfx::TYPE_EXPLOSION);
|
||||
} else {
|
||||
|
@ -301,17 +316,18 @@ static float distance_to_system(const SBodyPath *dest)
|
|||
void Ship::UseHyperspaceFuel(const SBodyPath *dest)
|
||||
{
|
||||
int fuel_cost;
|
||||
bool hscheck = CanHyperspaceTo(dest, fuel_cost);
|
||||
double dur;
|
||||
bool hscheck = CanHyperspaceTo(dest, fuel_cost, dur);
|
||||
assert(hscheck);
|
||||
m_equipment.Remove(Equip::HYDROGEN, fuel_cost);
|
||||
}
|
||||
|
||||
bool Ship::CanHyperspaceTo(const SBodyPath *dest, int &fuelRequired)
|
||||
bool Ship::CanHyperspaceTo(const SBodyPath *dest, int &outFuelRequired, double &outDurationSecs)
|
||||
{
|
||||
Equip::Type t = m_equipment.Get(Equip::SLOT_ENGINE);
|
||||
float hyperclass = (float)EquipType::types[t].pval;
|
||||
int fuel = m_equipment.Count(Equip::SLOT_CARGO, Equip::HYDROGEN);
|
||||
fuelRequired = 0;
|
||||
outFuelRequired = 0;
|
||||
if (hyperclass == 0) return false;
|
||||
|
||||
float dist;
|
||||
|
@ -322,17 +338,35 @@ bool Ship::CanHyperspaceTo(const SBodyPath *dest, int &fuelRequired)
|
|||
}
|
||||
|
||||
this->CalcStats();
|
||||
fuelRequired = (int)ceil(hyperclass*hyperclass*dist / m_stats.hyperspace_range_max);
|
||||
if (fuelRequired > hyperclass*hyperclass) fuelRequired = hyperclass*hyperclass;
|
||||
if (fuelRequired < 1) fuelRequired = 1;
|
||||
outFuelRequired = (int)ceil(hyperclass*hyperclass*dist / m_stats.hyperspace_range_max);
|
||||
if (outFuelRequired > hyperclass*hyperclass) outFuelRequired = hyperclass*hyperclass;
|
||||
if (outFuelRequired < 1) outFuelRequired = 1;
|
||||
if (dist > m_stats.hyperspace_range) {
|
||||
fuelRequired = 0;
|
||||
outFuelRequired = 0;
|
||||
return false;
|
||||
} else {
|
||||
return fuelRequired <= fuel;
|
||||
// take at most a week. why a week? because a week is a
|
||||
// fundamental physical unit in the same sense that the planck length
|
||||
// is, and so it is very probable that future hyperspace
|
||||
// technologies will involve travelling a week through time.
|
||||
outDurationSecs = (dist / m_stats.hyperspace_range) * 60.0 * 60.0 * 24.0 * 7.0;
|
||||
return outFuelRequired <= fuel;
|
||||
}
|
||||
}
|
||||
|
||||
void Ship::TryHyperspaceTo(const SBodyPath *dest)
|
||||
{
|
||||
int fuelUsage;
|
||||
double dur;
|
||||
if (m_hyperspace.countdown) return;
|
||||
if (!CanHyperspaceTo(dest, fuelUsage, dur)) return;
|
||||
if (Pi::currentSystem->IsSystem(dest->sectorX, dest->sectorY, dest->systemIdx)) {
|
||||
return;
|
||||
}
|
||||
m_hyperspace.countdown = 2.5;
|
||||
m_hyperspace.dest = *dest;
|
||||
}
|
||||
|
||||
float Ship::GetECMRechargeTime()
|
||||
{
|
||||
const Equip::Type t = m_equipment.Get(Equip::SLOT_ECM);
|
||||
|
@ -553,15 +587,27 @@ void Ship::StaticUpdate(const float timeStep)
|
|||
}
|
||||
|
||||
if (m_testLanded) TestLanded();
|
||||
|
||||
// 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 NotifyDeleted()
|
||||
if (m_hyperspace.countdown) {
|
||||
m_hyperspace.countdown = MAX(m_hyperspace.countdown - timeStep, 0);
|
||||
printf("Hyperspacing! %f\n", m_hyperspace.countdown);
|
||||
if (m_hyperspace.countdown == 0) {
|
||||
Space::StartHyperspaceTo(this, &m_hyperspace.dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ship::NotifyDeath(const Body* const dyingBody)
|
||||
void Ship::NotifyDeleted(const Body* const deletedBody)
|
||||
{
|
||||
if(GetNavTarget() == dyingBody)
|
||||
if(GetNavTarget() == deletedBody)
|
||||
SetNavTarget(0);
|
||||
if(GetCombatTarget() == dyingBody)
|
||||
if(GetCombatTarget() == deletedBody)
|
||||
SetCombatTarget(0);
|
||||
AIBodyHasDied(dyingBody);
|
||||
AIBodyDeleted(deletedBody);
|
||||
}
|
||||
|
||||
const ShipType &Ship::GetShipType() const
|
||||
|
|
19
src/Ship.h
19
src/Ship.h
|
@ -7,10 +7,11 @@
|
|||
#include "sbre/sbre.h"
|
||||
#include "MarketAgent.h"
|
||||
#include "ShipFlavour.h"
|
||||
// only for SBodyPath
|
||||
#include "StarSystem.h"
|
||||
#include <list>
|
||||
|
||||
class SpaceStation;
|
||||
struct SBodyPath;
|
||||
|
||||
struct shipstats_t {
|
||||
int max_capacity;
|
||||
|
@ -52,7 +53,7 @@ public:
|
|||
void Blastoff();
|
||||
virtual void TimeStepUpdate(const float timeStep);
|
||||
virtual void StaticUpdate(const float timeStep);
|
||||
virtual void NotifyDeath(const Body* const dyingBody);
|
||||
virtual void NotifyDeleted(const Body* const deletedBody);
|
||||
virtual bool OnCollision(Object *o, Uint32 flags, double relVel);
|
||||
virtual bool OnDamage(Object *attacker, float kgDamage);
|
||||
enum FlightState { FLYING, LANDED, DOCKING };
|
||||
|
@ -60,7 +61,10 @@ public:
|
|||
void SetFlightState(FlightState s) { m_flightState = s; }
|
||||
float GetWheelState() const { return m_wheelState; }
|
||||
bool Jettison(Equip::Type t);
|
||||
bool CanHyperspaceTo(const SBodyPath *dest, int &fuelRequired);
|
||||
const SBodyPath *GetHyperspaceTarget() const { return &m_hyperspace.dest; }
|
||||
void SetHyperspaceTarget(const SBodyPath *path);
|
||||
void TryHyperspaceTo(const SBodyPath *dest);
|
||||
bool CanHyperspaceTo(const SBodyPath *dest, int &outFuelRequired, double &outDurationSecs);
|
||||
void UseHyperspaceFuel(const SBodyPath *dest);
|
||||
void UseECM();
|
||||
void AIFaceDirection(const vector3d &dir);
|
||||
|
@ -122,6 +126,13 @@ private:
|
|||
Body* m_navTarget;
|
||||
Body* m_combatTarget;
|
||||
shipstats_t m_stats;
|
||||
|
||||
struct HyperspacingOut {
|
||||
SBodyPath dest;
|
||||
// > 0 means active
|
||||
float countdown;
|
||||
} m_hyperspace;
|
||||
|
||||
class AIInstruction {
|
||||
public:
|
||||
AICommand cmd;
|
||||
|
@ -129,7 +140,7 @@ private:
|
|||
AIInstruction(AICommand c, void *a): cmd(c), arg(a) {}
|
||||
};
|
||||
std::list<AIInstruction> m_todo;
|
||||
void AIBodyHasDied(const Body* const body);
|
||||
void AIBodyDeleted(const Body* const body);
|
||||
bool AICmdKill(const Ship *);
|
||||
bool AICmdKamikaze(const Ship *);
|
||||
bool AICmdFlyTo(const Body *);
|
||||
|
|
|
@ -177,7 +177,7 @@ void ShipCpanel::Update()
|
|||
}
|
||||
// make requested but not selected icon blink
|
||||
if (timeAccel != requested) {
|
||||
m_timeAccelButtons[requested]->SetSelected(SDL_GetTicks() & 0x200);
|
||||
m_timeAccelButtons[CLAMP(requested,0,5)]->SetSelected(SDL_GetTicks() & 0x200);
|
||||
}
|
||||
|
||||
m_scanner->Update();
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "Pi.h"
|
||||
#include "Player.h"
|
||||
#include "Missile.h"
|
||||
#include "HyperspaceCloud.h"
|
||||
#include "Sector.h"
|
||||
|
||||
#define SCANNER_SCALE 0.01f
|
||||
#define SCANNER_YSHRINK 0.75f
|
||||
|
@ -292,6 +294,27 @@ void UseEquipWidget::UseRadarMapper()
|
|||
}
|
||||
}
|
||||
|
||||
void UseEquipWidget::UseHypercloudAnalyzer()
|
||||
{
|
||||
Body *target = Pi::player->GetNavTarget();
|
||||
|
||||
if ((!target) || (!target->IsType(Object::HYPERSPACECLOUD))) {
|
||||
Pi::cpan->MsgLog()->Message("", "Hypercloud Analyzer: You must target a hyperspace cloud");
|
||||
return;
|
||||
}
|
||||
HyperspaceCloud *cloud = static_cast<HyperspaceCloud*>(target);
|
||||
const SBodyPath *dest = cloud->GetShip()->GetHyperspaceTarget();
|
||||
Sector s(dest->sectorX, dest->sectorY);
|
||||
Pi::cpan->MsgLog()->Message("", stringf(512,
|
||||
"Hyperspace departure cloud: Ship mass %dt\n"
|
||||
"Destination: %s\n"
|
||||
"Date due: %s\n",
|
||||
cloud->GetShip()->CalcStats()->total_mass,
|
||||
s.m_systems[dest->systemIdx].name.c_str(),
|
||||
format_date(cloud->GetDueDate()).c_str()
|
||||
));
|
||||
}
|
||||
|
||||
void UseEquipWidget::UpdateEquip()
|
||||
{
|
||||
DeleteAllChildren();
|
||||
|
@ -347,6 +370,15 @@ void UseEquipWidget::UpdateEquip()
|
|||
Add(b, 64, 0);
|
||||
}
|
||||
}
|
||||
{
|
||||
const Equip::Type t = Pi::player->m_equipment.Get(Equip::SLOT_HYPERCLOUD);
|
||||
if (t != Equip::NONE) {
|
||||
Gui::Button *b = new Gui::ImageButton("icons/hypercloud_anal.png");
|
||||
b->onClick.connect(sigc::mem_fun(this, &UseEquipWidget::UseHypercloudAnalyzer));
|
||||
Add(b, 96, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UseEquipWidget::Update()
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
private:
|
||||
void UpdateEquip();
|
||||
void UseRadarMapper();
|
||||
void UseHypercloudAnalyzer();
|
||||
enum { MAX_MISSILE_SLOTS = 8 };
|
||||
|
||||
sigc::connection m_onPlayerEquipChangedCon;
|
||||
|
|
|
@ -14,7 +14,7 @@ const ShipType ShipType::types[] = {
|
|||
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
|
||||
{ vector3f(0,0,0), vector3f(0,0,1) }
|
||||
},
|
||||
{ 20, 1, 1, 3, 1, 1, 1 },
|
||||
{ 20, 1, 1, 3, 1, 1, 1, 1 },
|
||||
20, 5, 4000000,
|
||||
Equip::DRIVE_CLASS1,
|
||||
}, {
|
||||
|
@ -28,7 +28,7 @@ const ShipType ShipType::types[] = {
|
|||
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
|
||||
{ vector3f(0,-0.5,0), vector3f(0,0,1) }
|
||||
},
|
||||
{ 90, 1, 2, 8, 1, 1, 1 },
|
||||
{ 90, 1, 2, 8, 1, 1, 1, 1 },
|
||||
90, 20, 16000000,
|
||||
Equip::DRIVE_CLASS3,
|
||||
}, {
|
||||
|
@ -41,7 +41,7 @@ const ShipType ShipType::types[] = {
|
|||
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
|
||||
{ vector3f(0,0,0), vector3f(0,0,1) }
|
||||
},
|
||||
{ 60, 1, 1, 2, 1, 1, 1 },
|
||||
{ 60, 1, 1, 2, 1, 1, 1, 1 },
|
||||
60, 15, 8700000,
|
||||
Equip::DRIVE_CLASS2,
|
||||
}, {
|
||||
|
@ -53,7 +53,7 @@ const ShipType ShipType::types[] = {
|
|||
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
|
||||
{ vector3f(0,0,0), vector3f(0,0,1) }
|
||||
},
|
||||
{ 240, 1, 1, 4, 1, 1, 1 },
|
||||
{ 240, 1, 1, 4, 1, 1, 1, 1 },
|
||||
240, 55, 56000000,
|
||||
Equip::DRIVE_CLASS4,
|
||||
}, {
|
||||
|
@ -65,7 +65,7 @@ const ShipType ShipType::types[] = {
|
|||
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
|
||||
{ vector3f(0,0,0), vector3f(0,0,1) }
|
||||
},
|
||||
{ 320, 1, 1, 6, 1, 1, 1 },
|
||||
{ 320, 1, 1, 6, 1, 1, 1, 1 },
|
||||
320, 80, 35000000,
|
||||
Equip::DRIVE_CLASS5,
|
||||
}, {
|
||||
|
@ -77,7 +77,7 @@ const ShipType ShipType::types[] = {
|
|||
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
|
||||
{ vector3f(0,0,0), vector3f(0,0,1) }
|
||||
},
|
||||
{ 500, 1, 2, 4, 1, 1, 1 },
|
||||
{ 500, 1, 2, 4, 1, 1, 1, 1 },
|
||||
500, 125, 55000000,
|
||||
Equip::DRIVE_CLASS6,
|
||||
}, {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "pirates.h"
|
||||
#include "Sfx.h"
|
||||
#include "Missile.h"
|
||||
#include "HyperspaceCloud.h"
|
||||
|
||||
namespace Space {
|
||||
|
||||
|
@ -29,6 +30,7 @@ static void ApplyGravity();
|
|||
static std::list<Body*> corpses;
|
||||
static SBodyPath *hyperspacingTo;
|
||||
static float hyperspaceAnim;
|
||||
static double hyperspaceEndTime;
|
||||
|
||||
void Init()
|
||||
{
|
||||
|
@ -101,6 +103,7 @@ void Serialize()
|
|||
wr_byte(1);
|
||||
hyperspacingTo->Serialize();
|
||||
wr_float(hyperspaceAnim);
|
||||
wr_double(hyperspaceEndTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,6 +124,7 @@ void Unserialize()
|
|||
hyperspacingTo = new SBodyPath;
|
||||
SBodyPath::Unserialize(hyperspacingTo);
|
||||
hyperspaceAnim = rd_float();
|
||||
hyperspaceEndTime = rd_double();
|
||||
}
|
||||
// bodies with references to others must fix these up
|
||||
Serializer::IndexBodies();
|
||||
|
@ -566,11 +570,16 @@ void ApplyGravity()
|
|||
void TimeStep(float step)
|
||||
{
|
||||
if (hyperspacingTo) {
|
||||
Pi::RequestTimeAccel(6);
|
||||
|
||||
hyperspaceAnim += step;
|
||||
if (hyperspaceAnim > 1.0) {
|
||||
if (Pi::GetGameTime() > hyperspaceEndTime) {
|
||||
DoHyperspaceTo(0);
|
||||
Pi::RequestTimeAccel(1);
|
||||
hyperspaceAnim = 0;
|
||||
}
|
||||
// don't take a physics step at this mental time accel
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyGravity();
|
||||
|
@ -595,7 +604,7 @@ void PruneCorpses()
|
|||
{
|
||||
for (bodiesIter_t corpse = corpses.begin(); corpse != corpses.end(); ++corpse) {
|
||||
for (bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i)
|
||||
(*i)->NotifyDeath(*corpse);
|
||||
(*i)->NotifyDeleted(*corpse);
|
||||
bodies.remove(*corpse);
|
||||
delete *corpse;
|
||||
}
|
||||
|
@ -607,22 +616,46 @@ static bool jumped_within_same_system;
|
|||
/*
|
||||
* Called during play to initiate hyperspace sequence.
|
||||
*/
|
||||
void StartHyperspaceTo(const SBodyPath *dest)
|
||||
void StartHyperspaceTo(Ship *ship, const SBodyPath *dest)
|
||||
{
|
||||
int fuelUsage;
|
||||
if (!Pi::player->CanHyperspaceTo(dest, fuelUsage)) return;
|
||||
double duration;
|
||||
if (!ship->CanHyperspaceTo(dest, fuelUsage, duration)) return;
|
||||
if (Pi::currentSystem->IsSystem(dest->sectorX, dest->sectorY, dest->systemIdx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Space::Clear();
|
||||
Pi::player->UseHyperspaceFuel(dest);
|
||||
Pi::player->DisableBodyOnly();
|
||||
|
||||
if (!hyperspacingTo) hyperspacingTo = new SBodyPath;
|
||||
*hyperspacingTo = *dest;
|
||||
hyperspaceAnim = 0.0f;
|
||||
printf("Started hyperspacing...\n");
|
||||
ship->UseHyperspaceFuel(dest);
|
||||
ship->DisableBodyOnly();
|
||||
|
||||
if (Pi::player == ship) {
|
||||
Space::Clear();
|
||||
if (!hyperspacingTo) hyperspacingTo = new SBodyPath;
|
||||
*hyperspacingTo = *dest;
|
||||
hyperspaceAnim = 0.0f;
|
||||
hyperspaceEndTime = Pi::GetGameTime() + duration;
|
||||
printf("Started hyperspacing...\n");
|
||||
} else {
|
||||
HyperspaceCloud *cloud = new HyperspaceCloud(ship, Pi::GetGameTime() + duration);
|
||||
cloud->SetFrame(ship->GetFrame());
|
||||
cloud->SetPosition(ship->GetPosition());
|
||||
// need to swap ship out of bodies list, replacing it with
|
||||
// cloud
|
||||
for (bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
||||
if (*i == ship) {
|
||||
*i = cloud;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Hyperspacing ship must drop references to all other bodies,
|
||||
// and they must all drop references to it.
|
||||
// make other objects drop their references to this dude
|
||||
for (bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
||||
if (*i != cloud) {
|
||||
(*i)->NotifyDeleted(ship);
|
||||
ship->NotifyDeleted(*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Space {
|
|||
extern void DoECM(const Frame *f, const vector3d &pos, int power_val);
|
||||
extern float GetHyperspaceAnim();
|
||||
extern void Render(const Frame *cam_frame);
|
||||
extern void StartHyperspaceTo(const SBodyPath *);
|
||||
extern void StartHyperspaceTo(Ship *s, const SBodyPath *);
|
||||
extern void DoHyperspaceTo(const SBodyPath *);
|
||||
// make sure SBody* is in Pi::currentSystem
|
||||
extern Frame *GetFrameWithSBody(const SBody *b);
|
||||
|
|
|
@ -728,10 +728,10 @@ bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel)
|
|||
}
|
||||
}
|
||||
|
||||
void SpaceStation::NotifyDeath(const Body* const dyingBody)
|
||||
void SpaceStation::NotifyDeleted(const Body* const deletedBody)
|
||||
{
|
||||
for (int i=0; i<MAX_DOCKING_PORTS; i++) {
|
||||
if (m_shipDocking[i].ship == dyingBody) {
|
||||
if (m_shipDocking[i].ship == deletedBody) {
|
||||
m_shipDocking[i].ship = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
// does not dealloc
|
||||
bool BBRemoveMission(Mission *m);
|
||||
virtual void PostLoadFixup();
|
||||
virtual void NotifyDeath(const Body* const dyingBody);
|
||||
virtual void NotifyDeleted(const Body* const deletedBody);
|
||||
void PositionDockedShip(Ship *ship, int port);
|
||||
sigc::signal<void> onShipsForSaleChanged;
|
||||
sigc::signal<void> onBulletinBoardChanged;
|
||||
|
|
|
@ -208,7 +208,7 @@ void WorldView::OnClickBlastoff()
|
|||
void WorldView::OnClickHyperspace()
|
||||
{
|
||||
const SBodyPath *path = Pi::player->GetHyperspaceTarget();
|
||||
Space::StartHyperspaceTo(path);
|
||||
Pi::player->TryHyperspaceTo(path);
|
||||
}
|
||||
|
||||
void WorldView::DrawBgStars()
|
||||
|
@ -256,7 +256,7 @@ void WorldView::DrawBgStars()
|
|||
vtx[i*12+5] = s_bgstar[i].b;
|
||||
|
||||
vector3d v(s_bgstar[i].x, s_bgstar[i].y, s_bgstar[i].z);
|
||||
v += pz*hyperspaceAnim*200.0;
|
||||
v += pz*hyperspaceAnim*0.001;
|
||||
|
||||
vtx[i*12+6] = v.x;
|
||||
vtx[i*12+7] = v.y;
|
||||
|
@ -510,7 +510,8 @@ void WorldView::OnChangeHyperspaceTarget()
|
|||
delete system;
|
||||
|
||||
int fuelReqd;
|
||||
if (Pi::player->CanHyperspaceTo(path, fuelReqd)) m_hyperspaceButton->Show();
|
||||
double dur;
|
||||
if (Pi::player->CanHyperspaceTo(path, fuelReqd, dur)) m_hyperspaceButton->Show();
|
||||
else m_hyperspaceButton->Hide();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue