[Add] Mkay, ships can take damage and die now.
This commit is contained in:
parent
abfd826e73
commit
d455debea6
@ -28,6 +28,7 @@ public:
|
|||||||
virtual void SetFrame(Frame* f) { m_frame = f; }
|
virtual void SetFrame(Frame* f) { m_frame = f; }
|
||||||
/* return true if to we do collision response and apply damage. */
|
/* return true if to we do collision response and apply damage. */
|
||||||
virtual bool OnCollision(Body* b, Uint32 flags) { return false; }
|
virtual bool OnCollision(Body* b, Uint32 flags) { return false; }
|
||||||
|
virtual bool OnDamage(Body* attacker, float kgDamage) { return false; }
|
||||||
virtual void TimeStepUpdate(const float timeStep) {}
|
virtual void TimeStepUpdate(const float timeStep) {}
|
||||||
/* Override to clear any pointers you hold to the dying body. */
|
/* Override to clear any pointers you hold to the dying body. */
|
||||||
virtual void NotifyDeath(const Body* const dyingBody) {}
|
virtual void NotifyDeath(const Body* const dyingBody) {}
|
||||||
@ -46,6 +47,7 @@ public:
|
|||||||
void SetOnscreen(const bool onscreen) { m_onscreen = onscreen; }
|
void SetOnscreen(const bool onscreen) { m_onscreen = onscreen; }
|
||||||
/* Only Space::KillBody() should call this method. */
|
/* Only Space::KillBody() should call this method. */
|
||||||
void MarkDead(void) { m_dead = true; }
|
void MarkDead(void) { m_dead = true; }
|
||||||
|
bool IsDead(void) const { return m_dead; }
|
||||||
|
|
||||||
enum { FLAG_CAN_MOVE_FRAME = 1 };
|
enum { FLAG_CAN_MOVE_FRAME = 1 };
|
||||||
|
|
||||||
|
@ -76,7 +76,11 @@ void CollisionSpace::TraceRay(const vector3d& start, const vector3d& dir,
|
|||||||
(*i)->GetGeomTree()->TraceRay(modelStart, modelDir, &isect);
|
(*i)->GetGeomTree()->TraceRay(modelStart, modelDir, &isect);
|
||||||
if(isect.triIdx != -1) {
|
if(isect.triIdx != -1) {
|
||||||
c->pos = start + dir*isect.dist;
|
c->pos = start + dir*isect.dist;
|
||||||
c->normal = vector3d(0.0);
|
|
||||||
|
vector3f n = (*i)->GetGeomTree()->GetTriNormal(isect.triIdx);
|
||||||
|
c->normal = vector3d(n.x, n.y, n.z);
|
||||||
|
c->normal = (*i)->GetTransform().ApplyRotationOnly(c->normal);
|
||||||
|
|
||||||
c->depth = len - isect.dist;
|
c->depth = len - isect.dist;
|
||||||
c->triIdx = isect.triIdx;
|
c->triIdx = isect.triIdx;
|
||||||
c->userData1 = (*i)->GetUserData();
|
c->userData1 = (*i)->GetUserData();
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
static void Init(IniConfig& config);
|
static void Init(IniConfig& config);
|
||||||
static void Start(void);
|
static void Start(void);
|
||||||
static void MainLoop(void);
|
static void MainLoop(void);
|
||||||
|
static void TombStoneLoop(void);
|
||||||
static void Quit(void);
|
static void Quit(void);
|
||||||
static void Serialize(void);
|
static void Serialize(void);
|
||||||
static void Unserialize(void);
|
static void Unserialize(void);
|
||||||
|
62
src/main.cpp
62
src/main.cpp
@ -166,18 +166,20 @@ void L3D::HandleEvents(void) {
|
|||||||
if(event.key.keysym.sym == SDLK_i) L3D::showDebugInfo = !L3D::showDebugInfo;
|
if(event.key.keysym.sym == SDLK_i) L3D::showDebugInfo = !L3D::showDebugInfo;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if(event.key.keysym.sym == SDLK_F12) {
|
if(event.key.keysym.sym == SDLK_F12) {
|
||||||
|
matrix4x4d m; L3D::player->GetRotMatrix(m);
|
||||||
|
vector3d dir = m*vector3d(0,0,-1);
|
||||||
if(KeyState(SDLK_LSHIFT)) {
|
if(KeyState(SDLK_LSHIFT)) {
|
||||||
SpaceStation* station = new SpaceStation(SpaceStation::JJHOOP);
|
SpaceStation* station = new SpaceStation(SpaceStation::JJHOOP);
|
||||||
station->SetLabel("Poemi-chan's Folly");
|
station->SetLabel("Poemi-chan's Folly");
|
||||||
station->SetFrame(L3D::player->GetFrame());
|
station->SetFrame(L3D::player->GetFrame());
|
||||||
station->SetRotMatrix(matrix4x4d::RotateZMatrix(M_PI));
|
station->SetRotMatrix(matrix4x4d::RotateZMatrix(M_PI));
|
||||||
station->SetPosition(L3D::player->GetPosition()+vector3d(0,0,-5000));
|
station->SetPosition(L3D::player->GetPosition()+5000.0*dir);
|
||||||
Space::AddBody(station);
|
Space::AddBody(station);
|
||||||
} else {
|
} else {
|
||||||
Ship* body = new Ship(ShipType::LADYBIRD);
|
Ship* body = new Ship(ShipType::LADYBIRD);
|
||||||
body->SetLabel("A Friend");
|
body->SetLabel("A Friend");
|
||||||
body->SetFrame(L3D::player->GetFrame());
|
body->SetFrame(L3D::player->GetFrame());
|
||||||
body->SetPosition(L3D::player->GetPosition()+vector3d(0,0,-1000));
|
body->SetPosition(L3D::player->GetPosition()+1000.0*dir);
|
||||||
Space::AddBody(body);
|
Space::AddBody(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,6 +216,62 @@ void L3D::HandleEvents(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void draw_tombstone(float _time) {
|
||||||
|
static float lightCol[4] = { 1, 1, 1, 0 };
|
||||||
|
static float lightDir[4] = { 0, 1, 0, 0 };
|
||||||
|
|
||||||
|
static ObjParams params = {
|
||||||
|
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f },
|
||||||
|
/* pColor[3]. */
|
||||||
|
{
|
||||||
|
{ { 1.0f, 1.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||||
|
{ { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||||
|
{ { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||||
|
},
|
||||||
|
{ "J00 ISH DEAD!" },
|
||||||
|
};
|
||||||
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||||
|
sbreSetViewport(L3D::GetScrWidth(), L3D::GetScrHeight(), L3D::GetScrWidth()*0.5, 1.0f, 1000.0f, 0.0f, 1.0f);
|
||||||
|
sbreSetDirLight(lightCol, lightDir);
|
||||||
|
matrix4x4d rot = matrix4x4d::RotateYMatrix(_time*2);
|
||||||
|
Matrix m;
|
||||||
|
Vector p;
|
||||||
|
m.x1 = rot[0]; m.x2 = rot[4]; m.x3 = rot[ 8];
|
||||||
|
m.y1 = rot[1]; m.y2 = rot[5]; m.y3 = rot[ 9];
|
||||||
|
m.z1 = rot[2]; m.z2 = rot[6]; m.z3 = rot[10];
|
||||||
|
p.x = 0; p.y = 0; p.z = MAX(150 - 30*_time, 30);
|
||||||
|
sbreRenderModel(&p, &m, 91, ¶ms);
|
||||||
|
glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
|
void L3D::TombStoneLoop(void) {
|
||||||
|
Uint32 last_time = SDL_GetTicks();
|
||||||
|
float _time = 0;
|
||||||
|
cpan->HideAll();
|
||||||
|
currentView->HideAll();
|
||||||
|
do {
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glClearColor(0, 0, 0, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
L3D::HandleEvents();
|
||||||
|
SDL_ShowCursor(1);
|
||||||
|
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||||
|
|
||||||
|
draw_tombstone(_time);
|
||||||
|
Gui::Draw();
|
||||||
|
glFlush();
|
||||||
|
SDL_GL_SwapBuffers();
|
||||||
|
|
||||||
|
L3D::frameTime = 0.001*(SDL_GetTicks() - last_time);
|
||||||
|
_time += L3D::frameTime;
|
||||||
|
last_time = SDL_GetTicks();
|
||||||
|
} while(!((_time > 2.0) && ((L3D::MouseButtonState(1)) || L3D::KeyState(SDLK_SPACE))));
|
||||||
|
}
|
||||||
|
|
||||||
static void draw_intro(float _time) {
|
static void draw_intro(float _time) {
|
||||||
static float lightCol[4] = { 1, 1, 1, 0 };
|
static float lightCol[4] = { 1, 1, 1, 0 };
|
||||||
static float lightDir[4] = { 0, 1, 0, 0 };
|
static float lightDir[4] = { 0, 1, 0, 0 };
|
||||||
|
@ -1339,3 +1339,37 @@ static uint16 starport1data[] = {
|
|||||||
Model starport1model = { 100.0f, 55.0f, 17, starport1vtx1, 17, 0, dummyvtx2, 1,
|
Model starport1model = { 100.0f, 55.0f, 17, starport1vtx1, 17, 0, dummyvtx2, 1,
|
||||||
{ { 0, starport1data, 0, 0, 0 } } };
|
{ { 0, starport1data, 0, 0, 0 } } };
|
||||||
|
|
||||||
|
static PlainVertex tomestonevtx1[] = {
|
||||||
|
{ VTYPE_PLAIN, { 0.6f, 1.0f, -0.1f } }, /* Front quad. */
|
||||||
|
{ VTYPE_PLAIN, { 0.6f, -1.0f, -0.1f } },
|
||||||
|
{ VTYPE_PLAIN, { -0.6f, -1.0f, -0.1f } },
|
||||||
|
{ VTYPE_PLAIN, { -0.6f, 1.0f, -0.1f } },
|
||||||
|
{ VTYPE_PLAIN, { 0, 1, 0.1 } }, /* Cylinder. */
|
||||||
|
{ VTYPE_PLAIN, { 0, 1, -0.1 } },
|
||||||
|
{ VTYPE_PLAIN, { 0.6f, 1.0f, 0.1f } }, /* Rear quad. */
|
||||||
|
{ VTYPE_PLAIN, { 0.6f, -1.0f, 0.1f } },
|
||||||
|
{ VTYPE_PLAIN, { -0.6f, -1.0f, 0.1f } },
|
||||||
|
{ VTYPE_PLAIN, { -0.6f, 1.0f, 0.1f } },
|
||||||
|
{ VTYPE_PLAIN, { -0.5, 0.8, -0.1 } }, /* Text start. */
|
||||||
|
{ VTYPE_PLAIN, { 0.5, 0.8, 0.1 } }, /* Text start. */
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16 tomestonedata[] = {
|
||||||
|
PTYPE_MATFIXED, 50, 50, 50, 0, 0, 0, 100, 0, 0, 0,
|
||||||
|
PTYPE_QUADFLAT, 6, 7, 8, 9,
|
||||||
|
PTYPE_QUADFLAT, 15, 14, 13, 12,
|
||||||
|
PTYPE_QUADFLAT, 6, 12, 13, 7,
|
||||||
|
PTYPE_QUADFLAT, 9, 8, 14, 15,
|
||||||
|
PTYPE_QUADFLAT, 9, 7, 13, 14,
|
||||||
|
PTYPE_CYLINDER, 0x8000, 16, 10, 11, 1, 60,
|
||||||
|
PTYPE_MATFIXED, 100, 100, 100, 0, 0, 0, 100, 100, 100, 0,
|
||||||
|
PTYPE_ZBIAS, 16, 5, 0,
|
||||||
|
PTYPE_TEXT, 0, 0x8000, 16, 5, 0, 0, 0, 10,
|
||||||
|
PTYPE_ZBIAS, 17, 2, 0,
|
||||||
|
PTYPE_TEXT, 0, 0x8000, 17, 2, 3, 0, 0, 10,
|
||||||
|
PTYPE_END
|
||||||
|
};
|
||||||
|
|
||||||
|
Model tomestonemodel = { 10.0f, 2.0f, 18, tomestonevtx1, 18, 0, dummyvtx2, 1,
|
||||||
|
{ { 0, tomestonedata, 0, 0, 0 } } };
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
extern Model dishmodel, nosewheelmodel, nwunitmodel, mainwheelmodel, mwunitmodel;
|
extern Model dishmodel, nosewheelmodel, nwunitmodel, mainwheelmodel, mwunitmodel;
|
||||||
extern Model wing1model, wing2model;
|
extern Model wing1model, wing2model;
|
||||||
extern Model ship1model, ship2model, ship3model, ship4model, ship5model;
|
extern Model ship1model, ship2model, ship3model, ship4model, ship5model;
|
||||||
extern Model station1model, starport1model;
|
extern Model station1model, starport1model, tomestonemodel;
|
||||||
extern Model metalFrameTowerModel;
|
extern Model metalFrameTowerModel;
|
||||||
|
|
||||||
/* Common subobject indices. */
|
/* Common subobject indices. */
|
||||||
@ -53,7 +53,7 @@ Model* const ppModel[] = {
|
|||||||
/* 80. */
|
/* 80. */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
/* 90, other people's ships. */
|
/* 90, other people's ships. */
|
||||||
&starport1model, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
&starport1model, &tomestonemodel, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
/* 100, more sub-objects. */
|
/* 100, more sub-objects. */
|
||||||
&metalFrameTowerModel
|
&metalFrameTowerModel
|
||||||
};
|
};
|
||||||
|
45
src/ship.cpp
45
src/ship.cpp
@ -44,6 +44,7 @@ void Ship::Save(void) {
|
|||||||
wr_int(m_dockedWithPort);
|
wr_int(m_dockedWithPort);
|
||||||
wr_int(Serializer::LookupBody(m_dockedWith));
|
wr_int(Serializer::LookupBody(m_dockedWith));
|
||||||
printf("TODO: NOT SAVING SHIP EQUIPMENT YET!!\n");
|
printf("TODO: NOT SAVING SHIP EQUIPMENT YET!!\n");
|
||||||
|
wr_float(m_stats.hull_mass_left);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ship::Load(void) {
|
void Ship::Load(void) {
|
||||||
@ -71,6 +72,7 @@ void Ship::Load(void) {
|
|||||||
/* TODO: */
|
/* TODO: */
|
||||||
m_equipment = EquipSet(m_shipType);
|
m_equipment = EquipSet(m_shipType);
|
||||||
Init();
|
Init();
|
||||||
|
m_stats.hull_mass_left = rd_float(); /* Must be after Init();.. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ship::Init(void) {
|
void Ship::Init(void) {
|
||||||
@ -78,6 +80,7 @@ void Ship::Init(void) {
|
|||||||
SetModel(stype.sbreModel);
|
SetModel(stype.sbreModel);
|
||||||
SetMassDistributionFromCollMesh(GetModelSBRECollMesh(stype.sbreModel));
|
SetMassDistributionFromCollMesh(GetModelSBRECollMesh(stype.sbreModel));
|
||||||
UpdateMass();
|
UpdateMass();
|
||||||
|
m_stats.hull_mass_left = stype.hullMass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ship::PostLoadFixup(void) {
|
void Ship::PostLoadFixup(void) {
|
||||||
@ -113,24 +116,40 @@ void Ship::UpdateMass(void) {
|
|||||||
SetMass(m_stats.total_mass*1000);
|
SetMass(m_stats.total_mass*1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Ship::OnDamage(Body* attacker, float kgDamage) {
|
||||||
|
m_stats.hull_mass_left -= kgDamage*0.001;
|
||||||
|
if(m_stats.hull_mass_left < 0) Space::KillBody(this);
|
||||||
|
printf("Auch! %s took %.1f kilos of damage from %s! (%.1f t hull left)\n",
|
||||||
|
GetLabel().c_str(), kgDamage, attacker->GetLabel().c_str(), m_stats.hull_mass_left);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define KINETIC_ENERGY_MULT 0.01
|
||||||
bool Ship::OnCollision(Body* b, Uint32 flags) {
|
bool Ship::OnCollision(Body* b, Uint32 flags) {
|
||||||
|
float kineticEnergy = 0;
|
||||||
|
if(b->IsType(Object::DYNAMICBODY)) {
|
||||||
|
const vector3d relVel = static_cast<DynamicBody*>(b)->GetVelocity() - GetVelocity();
|
||||||
|
const float v = relVel.Length();
|
||||||
|
kineticEnergy = KINETIC_ENERGY_MULT * m_stats.total_mass * v * v;
|
||||||
|
} else {
|
||||||
|
const float v = GetVelocity().Length();
|
||||||
|
kineticEnergy = KINETIC_ENERGY_MULT * m_stats.total_mass * v * v;
|
||||||
|
}
|
||||||
|
if(b->IsType(Object::SPACESTATION) && (flags & 0x10)) {
|
||||||
|
kineticEnergy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(b->IsType(Object::PLANET)) {
|
if(b->IsType(Object::PLANET)) {
|
||||||
/* Geoms still enabled when landed. */
|
/* Geoms still enabled when landed. */
|
||||||
if(m_flightState != FLYING) return false;
|
if(m_flightState != FLYING) return false;
|
||||||
else m_testLanded = true;
|
else {
|
||||||
|
if(GetVelocity().Length() < MAX_LANDING_SPEED) {
|
||||||
|
m_testLanded = true;
|
||||||
|
kineticEnergy = 0;
|
||||||
}
|
}
|
||||||
if(b->IsType(Object::MODELBODY)) {
|
|
||||||
vector3d relVel;
|
|
||||||
if(b->IsType(Object::DYNAMICBODY)) {
|
|
||||||
relVel = static_cast<DynamicBody*>(b)->GetVelocity() - GetVelocity();
|
|
||||||
} else {
|
|
||||||
relVel = GetVelocity();
|
|
||||||
}
|
}
|
||||||
/* Crappy recalculation of all this... */
|
|
||||||
float v = relVel.Length();
|
|
||||||
float kineticEnergy = m_stats.total_mass * v * v;
|
|
||||||
printf("%f ek\n", kineticEnergy);
|
|
||||||
}
|
}
|
||||||
|
if(kineticEnergy) OnDamage(b, kineticEnergy);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,9 +331,7 @@ void Ship::TimeStepUpdate(const float timeStep) {
|
|||||||
GetFrame()->GetCollisionSpace()->TraceRay(pos, dir, 10000.0, &c, GetGeom());
|
GetFrame()->GetCollisionSpace()->TraceRay(pos, dir, 10000.0, &c, GetGeom());
|
||||||
if(c.userData1) {
|
if(c.userData1) {
|
||||||
Body* hit = static_cast<Body*>(c.userData1);
|
Body* hit = static_cast<Body*>(c.userData1);
|
||||||
printf("Hit %s\n", hit->GetLabel().c_str());
|
hit->OnDamage(this, 1000.0);
|
||||||
} else {
|
|
||||||
printf("Hit nothing..\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ struct shipstats_t {
|
|||||||
int used_capacity;
|
int used_capacity;
|
||||||
int free_capacity;
|
int free_capacity;
|
||||||
int total_mass; /* Cargo, equipment + hull. */
|
int total_mass; /* Cargo, equipment + hull. */
|
||||||
|
float hull_mass_left; /* Effectively hitpoints.. */
|
||||||
float hyperspace_range;
|
float hyperspace_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,6 +42,7 @@ public:
|
|||||||
virtual void TimeStepUpdate(const float timeStep);
|
virtual void TimeStepUpdate(const float timeStep);
|
||||||
virtual void NotifyDeath(const Body* const dyingBody);
|
virtual void NotifyDeath(const Body* const dyingBody);
|
||||||
virtual bool OnCollision(Body* b, Uint32 flags);
|
virtual bool OnCollision(Body* b, Uint32 flags);
|
||||||
|
virtual bool OnDamage(Body* attacker, float kgDamage);
|
||||||
enum FlightState { FLYING, LANDED };
|
enum FlightState { FLYING, LANDED };
|
||||||
FlightState GetFlightState(void) const { return m_flightState; }
|
FlightState GetFlightState(void) const { return m_flightState; }
|
||||||
float GetWheelState(void) const { return m_wheelState; }
|
float GetWheelState(void) const { return m_wheelState; }
|
||||||
|
@ -403,6 +403,13 @@ void Space::TimeStep(float step) {
|
|||||||
for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
||||||
(*i)->TimeStepUpdate(step);
|
(*i)->TimeStepUpdate(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(L3D::player->IsDead()) {
|
||||||
|
printf("J00 IS DEAD!!\n");
|
||||||
|
L3D::TombStoneLoop();
|
||||||
|
L3D::Quit();
|
||||||
|
}
|
||||||
|
|
||||||
PruneCorpses();
|
PruneCorpses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user