[Add] Body death and associated cleanup. Space::KillBody() to kill a
body.
This commit is contained in:
parent
4595e1f643
commit
84530e9771
@ -7,6 +7,12 @@ Body::Body(void) {
|
||||
m_flags = 0;
|
||||
m_projectedPos = vector3d(0.0f, 0.0f, 0.0f);
|
||||
m_onscreen = false;
|
||||
m_dead = false;
|
||||
}
|
||||
|
||||
Body::~Body(void) {
|
||||
/* Do not call delete body. Call Space::KillBody(body). */
|
||||
assert(m_dead);
|
||||
}
|
||||
|
||||
/* f == NULL, then absolute position within system. */
|
||||
|
@ -11,7 +11,7 @@ class ObjMesh;
|
||||
class Body: public Object {
|
||||
public:
|
||||
Body(void);
|
||||
virtual ~Body(void) { };
|
||||
virtual ~Body(void);
|
||||
virtual Object::Type GetType(void) { return Object::BODY; }
|
||||
virtual void SetPosition(vector3d p) = 0;
|
||||
virtual vector3d GetPosition(void) = 0; /* Within frame. */
|
||||
@ -32,6 +32,11 @@ public:
|
||||
bool IsOnscreen() const { return m_onscreen; }
|
||||
void SetOnscreen(const bool onscreen) { m_onscreen = onscreen; }
|
||||
virtual void TimeStepUpdate(const float timeStep) {}
|
||||
/* Override to clear any pointers you hold to the dying body. */
|
||||
virtual void NotifyDeath(const Body* const dyingBody) {}
|
||||
/* Only Space::KillBody() should call this method. */
|
||||
void MarkDead(void) { m_dead = true; }
|
||||
|
||||
enum { FLAG_CAN_MOVE_FRAME = 1 };
|
||||
|
||||
protected:
|
||||
@ -43,5 +48,7 @@ private:
|
||||
std::string m_label;
|
||||
bool m_onscreen;
|
||||
vector3d m_projectedPos;
|
||||
/* Checked in destructor to make sure has been marked dead. */
|
||||
bool m_dead;
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,11 @@ Player::Player(ShipType::Type shipType) : Ship(shipType) {
|
||||
UpdateMass();
|
||||
}
|
||||
|
||||
Player::~Player(void) {
|
||||
assert(this == L3D::player);
|
||||
L3D::player = 0;
|
||||
}
|
||||
|
||||
void Player::Render(const Frame* camFrame) {
|
||||
if(L3D::GetCamType() == L3D::CAM_EXTERNAL) {
|
||||
Ship::Render(camFrame);
|
||||
@ -134,6 +139,11 @@ void Player::PollControls(void) {
|
||||
if(L3D::KeyState(SDLK_MINUS)) m_external_view_dist += 10;
|
||||
m_external_view_dist = MAX(50, m_external_view_dist);
|
||||
}
|
||||
|
||||
if(GetNavTarget() && L3D::KeyState(SDLK_END)) {
|
||||
/* Temp test: Kill ("end") the target. */
|
||||
Space::KillBody(GetNavTarget());
|
||||
}
|
||||
}
|
||||
|
||||
#define HUD_CROSSHAIR_SIZE 24.0f
|
||||
@ -171,7 +181,7 @@ void Player::DrawHUD(const Frame* cam_frame) {
|
||||
}
|
||||
}
|
||||
|
||||
DrawTargetSquare();
|
||||
DrawTargetSquares();
|
||||
|
||||
GLdouble pos[3];
|
||||
|
||||
@ -249,13 +259,28 @@ void Player::DrawHUD(const Frame* cam_frame) {
|
||||
Gui::Screen::LeaveOrtho();
|
||||
}
|
||||
|
||||
void Player::DrawTargetSquare(void) {
|
||||
if(GetTarget() && GetTarget()->IsOnscreen()) {
|
||||
void Player::DrawTargetSquares(void) {
|
||||
glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT);
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
glLineWidth(2.0f);
|
||||
|
||||
const vector3d& _pos = GetTarget()->GetProjectedPos();
|
||||
if(GetNavTarget()) {
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
DrawTargetSquare(GetNavTarget());
|
||||
}
|
||||
|
||||
if(GetCombatTarget()) {
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
DrawTargetSquare(GetNavTarget());
|
||||
}
|
||||
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
void Player::DrawTargetSquare(const Body* const target) {
|
||||
if(target->IsOnscreen()) {
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
|
||||
const vector3d& _pos = target->GetProjectedPos();
|
||||
const float x1 = _pos.x - WorldView::PICK_OBJECT_RECT_SIZE * 0.5f;
|
||||
const float x2 = x1 + WorldView::PICK_OBJECT_RECT_SIZE;
|
||||
const float y1 = _pos.y - WorldView::PICK_OBJECT_RECT_SIZE * 0.5f;
|
||||
@ -268,8 +293,6 @@ void Player::DrawTargetSquare(void) {
|
||||
glVertex2f(x1, y2);
|
||||
glVertex2f(x1, y1);
|
||||
glEnd();
|
||||
|
||||
glPopAttrib();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
class Player : public Ship {
|
||||
public:
|
||||
Player(ShipType::Type shipType);
|
||||
virtual ~Player(void);
|
||||
void PollControls(void);
|
||||
virtual void Render(const Frame* camFrame);
|
||||
void DrawHUD(const Frame* cam_frame);
|
||||
@ -12,7 +13,8 @@ public:
|
||||
vector3d GetExternalViewTranslation(void);
|
||||
void ApplyExternalViewRotation(void);
|
||||
private:
|
||||
void DrawTargetSquare();
|
||||
void DrawTargetSquares();
|
||||
void DrawTargetSquare(const Body* const target);
|
||||
float m_mouseCMov[2];
|
||||
float m_external_view_rotx, m_external_view_roty;
|
||||
float m_external_view_dist;
|
||||
|
10
src/ship.cpp
10
src/ship.cpp
@ -25,7 +25,8 @@ Ship::Ship(ShipType::Type shipType) : RigidBody() {
|
||||
m_wheelTransition = 0;
|
||||
m_wheelState = 0;
|
||||
m_dockedWith = 0;
|
||||
m_target = 0;
|
||||
m_navTarget = 0;
|
||||
m_combatTarget = 0;
|
||||
m_shipType = shipType;
|
||||
m_angThrusters[0] = m_angThrusters[1] = m_angThrusters[2] = 0;
|
||||
m_laserCollisionObj.owner = this;
|
||||
@ -126,6 +127,13 @@ void Ship::TimeStepUpdate(const float timeStep) {
|
||||
}
|
||||
}
|
||||
|
||||
void Ship::NotifyDeath(const Body* const dyingBody) {
|
||||
if(GetNavTarget() == dyingBody)
|
||||
SetNavTarget(0);
|
||||
if(GetCombatTarget() == dyingBody)
|
||||
SetCombatTarget(0);
|
||||
}
|
||||
|
||||
const ShipType& Ship::GetShipType(void) {
|
||||
return ShipType::types[m_shipType];
|
||||
}
|
||||
|
10
src/ship.h
10
src/ship.h
@ -20,8 +20,10 @@ public:
|
||||
virtual Object::Type GetType(void) { return Object::SHIP; }
|
||||
virtual void SetDockedWith(SpaceStation*);
|
||||
SpaceStation* GetDockedWith(void) { return m_dockedWith; }
|
||||
void SetTarget(Body* const target) { m_target = target; }
|
||||
Body* GetTarget(void) const { return m_target; }
|
||||
void SetNavTarget(Body* const target) { m_navTarget = target; }
|
||||
Body* GetNavTarget(void) const { return m_navTarget; }
|
||||
void SetCombatTarget(Body* const target) { m_combatTarget = target; }
|
||||
Body* GetCombatTarget(void) const { return m_combatTarget; }
|
||||
virtual void Render(const Frame* camFrame);
|
||||
void SetThrusterState(enum ShipType::Thruster t, float level);
|
||||
void SetAngThrusterState(int axis, float level) { m_angThrusters[axis] = CLAMP(level, -1, 1); }
|
||||
@ -32,6 +34,7 @@ public:
|
||||
void UpdateMass(void);
|
||||
void SetWheelState(bool down);
|
||||
virtual void TimeStepUpdate(const float timeStep);
|
||||
virtual void NotifyDeath(const Body* const dyingBody);
|
||||
|
||||
class LaserObj : public Object {
|
||||
public:
|
||||
@ -55,6 +58,7 @@ private:
|
||||
dGeomID m_tempLaserGeom[ShipType::GUNMOUNT_MAX];
|
||||
|
||||
LaserObj m_laserCollisionObj;
|
||||
Body* m_target;
|
||||
Body* m_navTarget;
|
||||
Body* m_combatTarget;
|
||||
};
|
||||
|
||||
|
@ -15,6 +15,7 @@ dWorldID Space::world;
|
||||
std::list<Body*> Space::bodies;
|
||||
Frame* Space::rootFrame;
|
||||
static dJointGroupID _contactgroup;
|
||||
std::list<Body*> Space::corpses;
|
||||
|
||||
void Space::Init(void) {
|
||||
world = dWorldCreate();
|
||||
@ -83,6 +84,11 @@ void Space::AddBody(Body* b) {
|
||||
bodies.push_back(b);
|
||||
}
|
||||
|
||||
void Space::KillBody(Body* const b) {
|
||||
b->MarkDead();
|
||||
corpses.push_back(b);
|
||||
}
|
||||
|
||||
void Space::UpdateFramesOfReference(void) {
|
||||
for(std::list<Body*>::iterator i = bodies.begin(); i != bodies.end(); ++i) {
|
||||
Body* b = *i;
|
||||
@ -212,6 +218,19 @@ void Space::TimeStep(float step) {
|
||||
for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
||||
(*i)->TimeStepUpdate(step);
|
||||
}
|
||||
/* Prune dead bodies. */
|
||||
for(bodiesIter_t i = corpses.begin(); i != corpses.end(); i++) {
|
||||
ProcessCorpse(*i);
|
||||
}
|
||||
corpses.clear();
|
||||
}
|
||||
|
||||
void Space::ProcessCorpse(Body* const b) {
|
||||
for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
||||
(*i)->NotifyDeath(b);
|
||||
}
|
||||
bodies.remove(b);
|
||||
delete b;
|
||||
}
|
||||
|
||||
struct body_zsort_t {
|
||||
|
@ -15,6 +15,7 @@ public:
|
||||
static void GenBody(StarSystem* s, StarSystem::SBody* b, Frame* f);
|
||||
static void TimeStep(float step);
|
||||
static void AddBody(Body*);
|
||||
static void KillBody(Body*);
|
||||
static void Render(const Frame* cam_frame);
|
||||
static Frame* GetRootFrame(void) { return rootFrame; }
|
||||
|
||||
@ -24,8 +25,10 @@ public:
|
||||
private:
|
||||
static void UpdateFramesOfReference(void);
|
||||
static void CollideFrame(Frame* f);
|
||||
static void ProcessCorpse(Body* const b);
|
||||
|
||||
static Frame* rootFrame;
|
||||
//static std::list<Frame*> rootFrames;
|
||||
static std::list<Body*> corpses;
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ SpaceStation::SpaceStation(void) : StaticRigidBody() {
|
||||
}
|
||||
|
||||
SpaceStation::~SpaceStation(void) {
|
||||
dGeomDestroy(m_geom);
|
||||
|
||||
}
|
||||
|
||||
bool SpaceStation::OnCollision(Body* b) {
|
||||
|
@ -19,6 +19,7 @@ StaticRigidBody::~StaticRigidBody(void) {
|
||||
free(sbreCollMesh->pFlag);
|
||||
free(sbreCollMesh);
|
||||
}
|
||||
GetFrame()->RemoveGeom(m_geom);
|
||||
dGeomDestroy(m_geom);
|
||||
}
|
||||
|
||||
|
@ -67,26 +67,26 @@ void WorldView::Draw3D(void) {
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if(L3D::player) {
|
||||
/* Make temporary camera frame at player. */
|
||||
Frame* cam_frame = new Frame(L3D::player->GetFrame(), "", Frame::TEMP_VIEWING);
|
||||
Frame cam_frame(L3D::player->GetFrame(), "", Frame::TEMP_VIEWING);
|
||||
|
||||
if(L3D::GetCamType() == L3D::CAM_FRONT) {
|
||||
cam_frame->SetPosition(L3D::player->GetPosition());
|
||||
cam_frame.SetPosition(L3D::player->GetPosition());
|
||||
} else if(L3D::GetCamType() == L3D::CAM_REAR) {
|
||||
glRotatef(180.0f, 0, 1, 0);
|
||||
cam_frame->SetPosition(L3D::player->GetPosition());
|
||||
cam_frame.SetPosition(L3D::player->GetPosition());
|
||||
} else { /* CAM_EXTERNAL */
|
||||
cam_frame->SetPosition(L3D::player->GetPosition() + L3D::player->GetExternalViewTranslation());
|
||||
cam_frame.SetPosition(L3D::player->GetPosition() + L3D::player->GetExternalViewTranslation());
|
||||
L3D::player->ApplyExternalViewRotation();
|
||||
}
|
||||
|
||||
L3D::player->ViewingRotation();
|
||||
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, &viewingRotation[0]);
|
||||
|
||||
glCallList(m_bgstarsDlist);
|
||||
/* Position light at sol. */
|
||||
vector3d lpos = Frame::GetFramePosRelativeToOther(Space::GetRootFrame(), cam_frame);
|
||||
vector3d lpos = Frame::GetFramePosRelativeToOther(Space::GetRootFrame(), &cam_frame);
|
||||
float lightPos[4];
|
||||
lightPos[0] = lpos.x;
|
||||
lightPos[1] = lpos.y;
|
||||
@ -96,11 +96,11 @@ void WorldView::Draw3D(void) {
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT_AND_DIFFUSE, lightCol);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, lightCol);
|
||||
|
||||
Space::Render(cam_frame);
|
||||
L3D::player->DrawHUD(cam_frame);
|
||||
Space::Render(&cam_frame);
|
||||
L3D::player->DrawHUD(&cam_frame);
|
||||
|
||||
L3D::player->GetFrame()->RemoveChild(cam_frame);
|
||||
delete cam_frame;
|
||||
L3D::player->GetFrame()->RemoveChild(&cam_frame);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldView::Update(void) {
|
||||
@ -110,18 +110,23 @@ void WorldView::Update(void) {
|
||||
m_hyperspaceButton->Hide();
|
||||
}
|
||||
/* Player control inputs. */
|
||||
if(L3D::player)
|
||||
L3D::player->PollControls();
|
||||
}
|
||||
|
||||
void WorldView::OnMouseDown(Gui::MouseButtonEvent* e) {
|
||||
if(1 == e->button) {
|
||||
/* Left click in view => Select target. */
|
||||
if(1 == e->button && !L3D::MouseButtonState(3)) {
|
||||
/* Left click in view when RMB not pressed => Select target. */
|
||||
float screenPos[2];
|
||||
GetPosition(screenPos);
|
||||
/* Put mouse coords into screen space. */
|
||||
screenPos[0] += e->x;
|
||||
screenPos[1] += e->y;
|
||||
L3D::player->SetTarget(PickBody(screenPos[0], screenPos[1]));
|
||||
Body* const target = PickBody(screenPos[0], screenPos[1]);
|
||||
if(L3D::player) {
|
||||
/* TODO: If in nav mode, SetNavTarget(), else SetCombatTarget(). */
|
||||
L3D::player->SetNavTarget(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user