[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; }
|
||||
/* return true if to we do collision response and apply damage. */
|
||||
virtual bool OnCollision(Body* b, Uint32 flags) { return false; }
|
||||
virtual bool OnDamage(Body* attacker, float kgDamage) { return false; }
|
||||
virtual void TimeStepUpdate(const float timeStep) {}
|
||||
/* Override to clear any pointers you hold to the dying body. */
|
||||
virtual void NotifyDeath(const Body* const dyingBody) {}
|
||||
@ -46,6 +47,7 @@ public:
|
||||
void SetOnscreen(const bool onscreen) { m_onscreen = onscreen; }
|
||||
/* Only Space::KillBody() should call this method. */
|
||||
void MarkDead(void) { m_dead = true; }
|
||||
bool IsDead(void) const { return m_dead; }
|
||||
|
||||
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);
|
||||
if(isect.triIdx != -1) {
|
||||
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->triIdx = isect.triIdx;
|
||||
c->userData1 = (*i)->GetUserData();
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
static void Init(IniConfig& config);
|
||||
static void Start(void);
|
||||
static void MainLoop(void);
|
||||
static void TombStoneLoop(void);
|
||||
static void Quit(void);
|
||||
static void Serialize(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;
|
||||
#ifdef DEBUG
|
||||
if(event.key.keysym.sym == SDLK_F12) {
|
||||
matrix4x4d m; L3D::player->GetRotMatrix(m);
|
||||
vector3d dir = m*vector3d(0,0,-1);
|
||||
if(KeyState(SDLK_LSHIFT)) {
|
||||
SpaceStation* station = new SpaceStation(SpaceStation::JJHOOP);
|
||||
station->SetLabel("Poemi-chan's Folly");
|
||||
station->SetFrame(L3D::player->GetFrame());
|
||||
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);
|
||||
} else {
|
||||
Ship* body = new Ship(ShipType::LADYBIRD);
|
||||
body->SetLabel("A Friend");
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -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 float lightCol[4] = { 1, 1, 1, 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,
|
||||
{ { 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 wing1model, wing2model;
|
||||
extern Model ship1model, ship2model, ship3model, ship4model, ship5model;
|
||||
extern Model station1model, starport1model;
|
||||
extern Model station1model, starport1model, tomestonemodel;
|
||||
extern Model metalFrameTowerModel;
|
||||
|
||||
/* Common subobject indices. */
|
||||
@ -53,7 +53,7 @@ Model* const ppModel[] = {
|
||||
/* 80. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 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. */
|
||||
&metalFrameTowerModel
|
||||
};
|
||||
|
47
src/ship.cpp
47
src/ship.cpp
@ -44,6 +44,7 @@ void Ship::Save(void) {
|
||||
wr_int(m_dockedWithPort);
|
||||
wr_int(Serializer::LookupBody(m_dockedWith));
|
||||
printf("TODO: NOT SAVING SHIP EQUIPMENT YET!!\n");
|
||||
wr_float(m_stats.hull_mass_left);
|
||||
}
|
||||
|
||||
void Ship::Load(void) {
|
||||
@ -71,6 +72,7 @@ void Ship::Load(void) {
|
||||
/* TODO: */
|
||||
m_equipment = EquipSet(m_shipType);
|
||||
Init();
|
||||
m_stats.hull_mass_left = rd_float(); /* Must be after Init();.. */
|
||||
}
|
||||
|
||||
void Ship::Init(void) {
|
||||
@ -78,6 +80,7 @@ void Ship::Init(void) {
|
||||
SetModel(stype.sbreModel);
|
||||
SetMassDistributionFromCollMesh(GetModelSBRECollMesh(stype.sbreModel));
|
||||
UpdateMass();
|
||||
m_stats.hull_mass_left = stype.hullMass;
|
||||
}
|
||||
|
||||
void Ship::PostLoadFixup(void) {
|
||||
@ -113,24 +116,40 @@ void Ship::UpdateMass(void) {
|
||||
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) {
|
||||
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)) {
|
||||
/* Geoms still enabled when landed. */
|
||||
if(m_flightState != FLYING) return false;
|
||||
else m_testLanded = true;
|
||||
}
|
||||
if(b->IsType(Object::MODELBODY)) {
|
||||
vector3d relVel;
|
||||
if(b->IsType(Object::DYNAMICBODY)) {
|
||||
relVel = static_cast<DynamicBody*>(b)->GetVelocity() - GetVelocity();
|
||||
} else {
|
||||
relVel = GetVelocity();
|
||||
else {
|
||||
if(GetVelocity().Length() < MAX_LANDING_SPEED) {
|
||||
m_testLanded = true;
|
||||
kineticEnergy = 0;
|
||||
}
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -312,9 +331,7 @@ void Ship::TimeStepUpdate(const float timeStep) {
|
||||
GetFrame()->GetCollisionSpace()->TraceRay(pos, dir, 10000.0, &c, GetGeom());
|
||||
if(c.userData1) {
|
||||
Body* hit = static_cast<Body*>(c.userData1);
|
||||
printf("Hit %s\n", hit->GetLabel().c_str());
|
||||
} else {
|
||||
printf("Hit nothing..\n");
|
||||
hit->OnDamage(this, 1000.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ struct shipstats_t {
|
||||
int used_capacity;
|
||||
int free_capacity;
|
||||
int total_mass; /* Cargo, equipment + hull. */
|
||||
float hull_mass_left; /* Effectively hitpoints.. */
|
||||
float hyperspace_range;
|
||||
};
|
||||
|
||||
@ -41,6 +42,7 @@ public:
|
||||
virtual void TimeStepUpdate(const float timeStep);
|
||||
virtual void NotifyDeath(const Body* const dyingBody);
|
||||
virtual bool OnCollision(Body* b, Uint32 flags);
|
||||
virtual bool OnDamage(Body* attacker, float kgDamage);
|
||||
enum FlightState { FLYING, LANDED };
|
||||
FlightState GetFlightState(void) const { return m_flightState; }
|
||||
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) {
|
||||
(*i)->TimeStepUpdate(step);
|
||||
}
|
||||
|
||||
if(L3D::player->IsDead()) {
|
||||
printf("J00 IS DEAD!!\n");
|
||||
L3D::TombStoneLoop();
|
||||
L3D::Quit();
|
||||
}
|
||||
|
||||
PruneCorpses();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user