diff --git a/.gitignore b/.gitignore
index 22fc997..f2c3d13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
*Lephisto3D*
*ModelViewer*
bin/*
+*.sav
*Makefile
*Makefile.in
*.stash
diff --git a/src/Makefile.am b/src/Makefile.am
index a663bec..6b9094c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,7 +10,7 @@ include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h
planet.h player.h dynamic_body.h sector.h sector_view.h ship_cpanel.h ship.h space.h star.h star_system.h system_info_view.h \
system_view.h vector3.h view.h world_view.h date.h space_station.h space_station_view.h model_body.h gui_iselectable.h \
ship_type.h object.h info_view.h model_coll_mesh_data.h object_viewer_view.h fixed.h custom_starsystems.h gameconsts.h \
- aabb.h
+ aabb.h serializer.h
libgui_a_SOURCES = gui_button.cpp gui.cpp gui_fixed.cpp gui_screen.cpp gui_label.cpp gui_toggle_button.cpp gui_radio_button.cpp \
gui_radio_group.cpp gui_image_button.cpp gui_image.cpp gui_image_radio_button.cpp gui_multi_state_image_button.cpp gui_widget.cpp \
@@ -20,7 +20,7 @@ Lephisto3D_SOURCES = main.cpp glfreetype.cpp body.cpp space.cpp ship.cpp player.
star.cpp frame.cpp ship_cpanel.cpp sector_view.cpp mtrand.cpp world_view.cpp system_view.cpp \
star_system.cpp sector.cpp system_info_view.cpp generic_system_view.cpp date.cpp space_station.cpp \
space_station_view.cpp model_body.cpp ship_type.cpp info_view.cpp model_coll_mesh_data.cpp \
- object_viewer_view.cpp custom_starsystems.cpp
+ object_viewer_view.cpp custom_starsystems.cpp serializer.cpp
Lephisto3D_LDADD = sbre/libsbre.a libgui.a
ModelViewer_SOURCES = sbre_viewer.cpp glfreetype.cpp
diff --git a/src/body.cpp b/src/body.cpp
index cd3f3ef..4b9b3ce 100644
--- a/src/body.cpp
+++ b/src/body.cpp
@@ -15,6 +15,10 @@ Body::~Body(void) {
assert(m_dead);
}
+void Body::Serialize(void) { }
+
+Body* Body::Unserialize(void) { }
+
/* f == NULL, then absolute position within system. */
vector3d Body::GetPositionRelTo(const Frame* relTo) {
matrix4x4d m;
diff --git a/src/body.h b/src/body.h
index 48dce3c..186c43a 100644
--- a/src/body.h
+++ b/src/body.h
@@ -10,9 +10,11 @@ class ObjMesh;
class Body: public Object {
public:
+ OBJDEF(Body, Object, BODY);
Body(void);
virtual ~Body(void);
- virtual Object::Type GetType(void) { return Object::BODY; }
+ void Serialize(void);
+ static Body* Unserialize(void);
virtual void SetPosition(vector3d p) = 0;
virtual vector3d GetPosition(void) const = 0; /* Within frame. */
virtual void SetVelocity(vector3d v) { assert(0); }
diff --git a/src/dynamic_body.h b/src/dynamic_body.h
index 019cd42..d37f9e3 100644
--- a/src/dynamic_body.h
+++ b/src/dynamic_body.h
@@ -8,6 +8,7 @@ class ObjMesh;
class DynamicBody : public ModelBody {
public:
+ OBJDEF(DynamicBody, ModelBody, DYNAMICBODY);
DynamicBody(void);
virtual ~DynamicBody(void);
virtual void SetRotMatrix(const matrix4x4d& r);
diff --git a/src/frame.cpp b/src/frame.cpp
index 6a5d23f..1596588 100644
--- a/src/frame.cpp
+++ b/src/frame.cpp
@@ -1,5 +1,6 @@
#include "frame.h"
#include "space.h"
+#include "serializer.h"
Frame::Frame(void) {
Init(NULL, "", 0);
@@ -13,6 +14,39 @@ Frame::Frame(Frame* parent, const char* label, unsigned int flags) {
Init(parent, label, flags);
}
+void Frame::Serialize(Frame* f) {
+ using namespace Serializer::Write;
+ wr_int(f->m_flags);
+ wr_double(f->m_radius);
+ wr_string(f->m_label);
+ for(int i = 0; i < 16; i++) wr_double(f->m_orient[i]);
+ wr_vector3d(f->m_angVel);
+ wr_vector3d(f->m_pos);
+
+ wr_int(f->m_children.size());
+ for(std::list::iterator i = f->m_children.begin();
+ i != f->m_children.end(); ++i) {
+ Serialize(*i);
+ }
+}
+
+Frame* Frame::Unserialize(Frame* parent) {
+ using namespace Serializer::Read;
+ Frame* f = new Frame();
+ f->m_parent = parent;
+ f->m_flags = rd_int();
+ f->m_radius = rd_double();
+ f->m_label = rd_string();
+ for(int i = 0; i < 16; i++) f->m_orient[i] = rd_double();
+ f->m_angVel = rd_vector3d();
+ printf("Frame rad %f, called %s\n", f->m_radius, f->m_label.c_str());
+ for(int i = rd_int(); i > 0; --i) {
+ f->m_children.push_back(Unserialize(f));
+ }
+
+ return f;
+}
+
void Frame::RemoveChild(Frame* f) {
m_children.remove(f);
}
diff --git a/src/frame.h b/src/frame.h
index 069f2f2..6b28f4b 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -14,6 +14,9 @@ public:
Frame(Frame* parent, const char* label, unsigned int flags);
~Frame(void);
+ static void Serialize(Frame*);
+ static Frame* Unserialize(Frame* parent);
+
const char* GetLabel(void) const { return m_label.c_str(); }
void SetLabel(const char* label) { m_label = label; }
void SetPosition(const vector3d &pos) { m_pos = pos; }
diff --git a/src/l3d.h b/src/l3d.h
index c0b87ff..ba7197a 100644
--- a/src/l3d.h
+++ b/src/l3d.h
@@ -43,6 +43,8 @@ public:
static void Start(void);
static void MainLoop(void);
static void Quit(void);
+ static void Serialize(void);
+ static void Unserialize(void);
static float GetFrameTime(void) { return frameTime; }
static double GetGameTime(void) { return gameTime; }
static void SetTimeAccel(float s);
diff --git a/src/main.cpp b/src/main.cpp
index e0c7af3..52fcf32 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,3 +1,4 @@
+#include
#include "libs.h"
#include "l3d.h"
#include "gui.h"
@@ -17,6 +18,7 @@
#include "space_station.h"
#include "space_station_view.h"
#include "info_view.h"
+#include "serializer.h"
float L3D::timeAccel = 1.0f;
int L3D::scrWidth;
@@ -185,6 +187,7 @@ void L3D::HandleEvents(void) {
#endif
if(event.key.keysym.sym == SDLK_F11) SDL_WM_ToggleFullScreen(L3D::scrSurface);
if(event.key.keysym.sym == SDLK_F10) L3D::SetView(L3D::objectViewerView);
+ if(event.key.keysym.sym == SDLK_F9) Serializer::Write::Game("quicksave.sav");
L3D::keyState[event.key.keysym.sym] = 1;
L3D::onKeyPress.emit(&event.key.keysym);
break;
@@ -269,17 +272,20 @@ void L3D::Start(void) {
const float w = Gui::Screen::GetWidth() / 2;
const float h = Gui::Screen::GetHeight() / 2;
- const int OPTS = 3;
+ const int OPTS = 4;
Gui::ToggleButton* opts[OPTS];
opts[0] = new Gui::ToggleButton(); opts[0]->SetShortcut(SDLK_1, KMOD_NONE);
opts[1] = new Gui::ToggleButton(); opts[1]->SetShortcut(SDLK_2, KMOD_NONE);
opts[2] = new Gui::ToggleButton(); opts[2]->SetShortcut(SDLK_3, KMOD_NONE);
+ opts[3] = new Gui::ToggleButton(); opts[3]->SetShortcut(SDLK_4, KMOD_NONE);
splash->Add(opts[0], w, h+64);
splash->Add(new Gui::Label("New game starting on Earth"), w+32, h+64);
splash->Add(opts[1], w, h+32);
splash->Add(new Gui::Label("New game starting on debug point"), w+32, h+32);
splash->Add(opts[2], w, h);
- splash->Add(new Gui::Label("Quit"), w+32, h);
+ splash->Add(new Gui::Label("Load quicksave"), w+32, h);
+ splash->Add(opts[3], w, h-32);
+ splash->Add(new Gui::Label("Quit"), w+32, h-32);
splash->ShowAll();
@@ -319,7 +325,7 @@ void L3D::Start(void) {
/* TODO: There isn't a sensible way to find stations for a planet. */
SpaceStation* station = 0;
for(Space::bodiesIter_t i = Space::bodies.begin(); i!=Space::bodies.end(); i++) {
- if((*i)->GetType() == Object::SPACESTATION) { station = (SpaceStation*)*i; break; }
+ if((*i)->IsType(Object::SPACESTATION)) { station = (SpaceStation*)*i; break; }
}
assert(station);
player->SetFrame(station->GetFrame());
@@ -333,6 +339,9 @@ void L3D::Start(void) {
player->SetFrame(pframe);
player->SetPosition(vector3d(0,0,EARTH_RADIUS));
MainLoop();
+ } else if(choice == 3) {
+ /* Load quicksave. */
+ Serializer::Read::Game("quicksave.sav");
}
}
@@ -440,6 +449,22 @@ void L3D::HyperspaceTo(StarSystem* dest) {
dest->GetPos(&L3D::playerLocSecX, &L3D::playerLocSecY, &L3D::playerLocSysIdx);
}
+void L3D::Serialize(void) {
+ using namespace Serializer::Write;
+ StarSystem::Serialize(selectedSystem);
+ wr_double(gameTime);
+ StarSystem::Serialize(currentSystem);
+ Space::Serialize();
+}
+
+void L3D::Unserialize(void) {
+ using namespace Serializer::Read;
+ selectedSystem = StarSystem::Unserialize();
+ gameTime = rd_double();
+ currentSystem = StarSystem::Unserialize();
+ Space::Unserialize();
+}
+
IniConfig::IniConfig(const char* filename) {
FILE* f = fopen(filename, "r");
if(!f) {
@@ -466,9 +491,18 @@ IniConfig::IniConfig(const char* filename) {
fclose(f);
}
+void sigsegv_handler(int signum) {
+ if(signum == SIGSEGV) {
+ printf("Segfault! All is lost! Abondon ship\n");
+ SDL_Quit();
+ abort();
+ }
+}
+
int main(int argc, char** argv) {
printf("Lephisto3D's super high tech demo!\n");
+ signal(SIGSEGV, sigsegv_handler);
IniConfig cfg("config.ini");
L3D::Init(cfg);
diff --git a/src/model_body.h b/src/model_body.h
index 226f6c3..b017d5b 100644
--- a/src/model_body.h
+++ b/src/model_body.h
@@ -10,6 +10,7 @@ class CollMeshSet;
class ModelBody: public Body {
public:
+ OBJDEF(ModelBody, Body, MODELBODY);
ModelBody(void);
virtual ~ModelBody(void);
void SetPosition(vector3d p);
@@ -33,7 +34,7 @@ public:
class Geom : public Object {
public:
- virtual Type GetType(void) { return Object::GEOM; }
+ OBJDEF(Geom, Object, GEOM);
Body* parent;
int flags;
};
diff --git a/src/object.h b/src/object.h
index a6e4403..01af994 100644
--- a/src/object.h
+++ b/src/object.h
@@ -2,7 +2,15 @@
class Object {
public:
- enum Type { NONE, BODY, SHIP, SPACESTATION, LASER, GEOM, PLANET };
- virtual Type GetType(void) = 0;
+ enum Type { OBJECT, BODY, MODELBODY, DYNAMICBODY, SHIP, PLAYER, SPACESTATION, LASER, GEOM, PLANET, STAR };
+ virtual Type GetType(void) { return OBJECT; }
+ virtual bool IsType(Type c) { return GetType() == c; }
};
+#define OBJDEF(__thisClass, __parentClass, __TYPE) \
+ virtual Object::Type GetType(void) { return Object::__TYPE; } \
+ virtual bool IsType(Type c) { \
+ if(__thisClass::GetType() == (c)) return true; \
+ else return __parentClass::IsType(c); \
+ }
+
diff --git a/src/planet.h b/src/planet.h
index 0fd8deb..323097a 100644
--- a/src/planet.h
+++ b/src/planet.h
@@ -5,6 +5,7 @@
class Frame;
class Planet : public Body {
public:
+ OBJDEF(Planet, Body, PLANET);
Planet(StarSystem::SBody*);
virtual ~Planet(void);
virtual void SetPosition(vector3d p);
@@ -15,7 +16,6 @@ public:
virtual void SetFrame(Frame* f);
virtual bool OnCollision(Body* b, Uint32 flags) { return true; }
virtual double GetMass(void) const { return m_mass; }
- virtual Object::Type GetType(void) { return Object::PLANET; }
private:
void DrawRockyPlanet(void);
void DrawGasGiant(void);
diff --git a/src/player.h b/src/player.h
index 52ebfc5..979c8da 100644
--- a/src/player.h
+++ b/src/player.h
@@ -4,6 +4,7 @@
class Player : public Ship {
public:
+ OBJDEF(Player, Ship, PLAYER);
Player(ShipType::Type shipType);
virtual ~Player(void);
void PollControls(void);
diff --git a/src/serializer.cpp b/src/serializer.cpp
new file mode 100644
index 0000000..fb77585
--- /dev/null
+++ b/src/serializer.cpp
@@ -0,0 +1,278 @@
+#include "serializer.h"
+#include "l3d.h"
+#include "frame.h"
+#include "space.h"
+
+namespace Serializer {
+
+static std::vector g_frames;
+
+Frame* LookupFrame(int index) {
+ return g_frames[index];
+}
+
+int LoopupFrame(Frame* f) {
+ for(unsigned int i = 0; i < g_frames.size(); i++) {
+ if(g_frames[i] == f) return i;
+ }
+ assert(0);
+}
+
+static void AddFrame(Frame* f) {
+ g_frames.push_back(f);
+ for(std::list::iterator i = f->m_children.begin();
+ i != f->m_children.end(); ++i) {
+ AddFrame(*i);
+ }
+}
+
+void IndexFrames(void) {
+ g_frames.clear();
+ AddFrame(Space::rootFrame);
+ printf("%d frames indexed\n", g_frames.size());
+}
+
+namespace Write {
+ static int checksum;
+ static FILE* sfptr;
+
+ bool Game(const char* filename) {
+ struct Object* o;
+ sfptr = fopen(filename, "wb");
+
+ if(sfptr == NULL) {
+ return false;
+ }
+
+ checksum = 0;
+
+ wr_byte('L');
+ wr_byte('E');
+ wr_byte('P');
+ wr_byte('H');
+ wr_byte('I');
+ wr_byte('S');
+ wr_byte('T');
+ wr_byte('O');
+
+ /* Save file version. */
+ wr_int(SAVEFILE_VERSION);
+ fclose(sfptr);
+ fprintf(stderr, "Game saved to '%s'\n", filename);
+
+ return true;
+ }
+
+ void wr_byte(unsigned char x) {
+ putc(x, sfptr);
+ checksum += x;
+ }
+
+ void wr_short(short x) {
+ wr_byte((unsigned char)(x & 0xff));
+ wr_byte((unsigned char)((x>>8) & 0xff));
+ }
+
+ void wr_int(int x) {
+ wr_byte((unsigned char)(x & 0xff));
+ wr_byte((unsigned char)((x>>8) & 0xff));
+ wr_byte((unsigned char)((x>>16) & 0xff));
+ wr_byte((unsigned char)((x>>24) & 0xff));
+ }
+
+ /* Not portable. */
+ void wr_float(float f) {
+ unsigned int i;
+ unsigned char* p = (unsigned char*)&f;
+
+ for(i = 0; i < sizeof(float); i++, p++) {
+ wr_byte(*p);
+ }
+ }
+
+ void wr_double(double f) {
+ unsigned int i;
+ unsigned char* p = (unsigned char*)&f;
+
+ for(i = 0; i < sizeof(double); i++, p++) {
+ wr_byte(*p);
+ }
+ }
+
+ /* First byte is string length, including null terminator. */
+ void wr_string(const char* s) {
+ /* We shouldn't fail on null strings. */
+ if(s == NULL) {
+ wr_int(0);
+ return;
+ }
+
+ wr_int(strlen(s)+1);
+
+ while(*s) {
+ wr_byte(*s);
+ s++;
+ }
+ wr_byte(*s);
+ }
+
+ void wr_string(std::string& s) {
+ wr_string(s.c_str());
+ }
+
+ void wr_vector3d(vector3d& vec) {
+ wr_double(vec.x);
+ wr_double(vec.y);
+ wr_double(vec.z);
+ }
+}
+
+namespace Read {
+ static int loadsum;
+ static FILE* lfptr;
+ /* Version of savefile we are loading. */
+ static int version;
+
+ bool Game(const char* filename) {
+ loadsum = 0;
+
+ lfptr = fopen(filename, "rb");
+
+ if(lfptr == NULL) return false;
+
+ if(rd_byte() != 'L') return false;
+ if(rd_byte() != 'E') return false;
+ if(rd_byte() != 'P') return false;
+ if(rd_byte() != 'H') return false;
+ if(rd_byte() != 'I') return false;
+ if(rd_byte() != 'S') return false;
+ if(rd_byte() != 'T') return false;
+ if(rd_byte() != 'O') return false;
+
+ /* Savefile version. */
+ version = rd_int();
+
+ L3D::Unserialize();
+
+ /* Check the checksum. */
+ int i = loadsum;
+ if(i != rd_int()) {
+ fprintf(stderr, "Checksum error loading savefile.\n");
+ return false;
+ }
+
+ fclose(lfptr);
+ fprintf(stderr, "Loaded '%s'\n", filename);
+
+ return true;
+ }
+
+ bool is_olderthan(int ver) {
+ return ver < version;
+ }
+
+ unsigned char rd_byte(void) {
+ int x = getc(lfptr) & 0xff;
+ loadsum += x;
+ return x;
+ }
+
+ short rd_short(void) {
+ int t1, t2;
+ t2 = rd_byte();
+ t1 = rd_byte();
+ return ((t1 << 8) | t2);
+ }
+
+ int rd_int(void) {
+ int t1, t2, t3, t4;
+ t4 = rd_byte();
+ t3 = rd_byte();
+ t2 = rd_byte();
+ t1 = rd_byte();
+ return ((t1 << 24) | (t2 << 16) | (t3 << 8) | t4);
+ }
+
+ float rd_float(void) {
+ unsigned int i ;
+ float f;
+ unsigned char* p = (unsigned char*)&f;
+
+ for(i = 0; i < sizeof(float); i++) {
+ p[i] = rd_byte();
+ }
+ return f;
+ }
+
+ double rd_double(void) {
+ unsigned int i;
+ double f;
+ unsigned char* p = (unsigned char*)& f;
+
+ for(i = 0; i < sizeof(double); i++) {
+ p[i] = rd_byte();
+ }
+ return f;
+ }
+
+ std::string rd_string(void) {
+ char* s = rd_cstring();
+ std::string str(s);
+ free(s);
+ return str;
+ }
+
+ /* Memory leaks included free. */
+ char* rd_cstring(void) {
+ char* buf;
+ int i;
+ unsigned char size;
+
+ /* Size is in first byte. */
+ size = rd_int();
+
+ /* A saved null string. */
+ if(size == 0) {
+ return NULL;
+ }
+
+ buf = (char*) malloc(sizeof(char)*size);
+
+ for(i = 0; i < size; i++) {
+ buf[i] = rd_byte();
+ }
+
+ return buf;
+ }
+
+ void rd_cstring2(char* buf, int len) {
+ int i;
+ int size;
+
+ /* Size is in first byte. */
+ size = rd_int();
+
+ /* A saved null string. */
+ if(size == 0) {
+ buf[0] = '\0';
+ return;
+ }
+
+ assert(size < len);
+
+ for(i = 0; i < size; i++) {
+ buf[i] = rd_byte();
+ }
+ }
+
+ vector3d rd_vector3d(void) {
+ vector3d v;
+ v.x = rd_double();
+ v.y = rd_double();
+ v.z = rd_double();
+ return v;
+ }
+}
+
+}
+
diff --git a/src/serializer.h b/src/serializer.h
new file mode 100644
index 0000000..b2f7efc
--- /dev/null
+++ b/src/serializer.h
@@ -0,0 +1,39 @@
+#pragma once
+#include
+#include "libs.h"
+
+#define SAVEFILE_VERSION 1
+
+class Frame;
+
+namespace Serializer {
+ void IndexFrames(void);
+ Frame* LookupFrame(Frame* f);
+
+ namespace Write {
+ bool Game(const char* filename);
+ void wr_byte(unsigned char x);
+ void wr_short(short x);
+ void wr_int(int x);
+ void wr_float(float f);
+ void wr_double(double f);
+ void wr_cstring(const char* s);
+ void wr_string(std::string& s);
+ void wr_vector3d(vector3d& vec);
+ }
+
+ namespace Read {
+ bool Game(const char* filename);
+ bool is_olderthan(int version);
+ unsigned char rd_byte(void);
+ short rd_short(void);
+ int rd_int(void);
+ float rd_float(void);
+ double rd_double(void);
+ std::string rd_string(void);
+ char* rd_cstring(void);
+ void rd_cstring2(char* buf, int len);
+ vector3d rd_vector3d(void);
+ }
+}
+
diff --git a/src/ship.cpp b/src/ship.cpp
index e7b129e..484bf15 100644
--- a/src/ship.cpp
+++ b/src/ship.cpp
@@ -57,7 +57,7 @@ void Ship::UpdateMass(void) {
}
bool Ship::OnCollision(Body* b, Uint32 flags) {
- if(b->GetType() == Object::PLANET) {
+ if(b->IsType(Object::PLANET)) {
/* Geoms still enabled when landed. */
if(m_flightState != FLYING) return false;
else m_testLanded = true;
diff --git a/src/ship.h b/src/ship.h
index 606c9e0..8f11a8c 100644
--- a/src/ship.h
+++ b/src/ship.h
@@ -16,8 +16,8 @@ struct shipstats_t {
class Ship : public DynamicBody {
public:
+ OBJDEF(Ship, DynamicBody, SHIP);
Ship(ShipType::Type shipType);
- virtual Object::Type GetType(void) { return Object::SHIP; }
virtual void SetDockedWith(SpaceStation*, int port);
SpaceStation* GetDockedWith(void) { return m_dockedWith; }
void SetNavTarget(Body* const target);
@@ -46,7 +46,7 @@ public:
class LaserObj : public Object {
public:
- virtual Object::Type GetType(void) { return Object::LASER; }
+ OBJDEF(LaserObj, Object, LASER);
Ship* owner;
};
diff --git a/src/space.cpp b/src/space.cpp
index 58acbd7..ebafa6d 100644
--- a/src/space.cpp
+++ b/src/space.cpp
@@ -11,6 +11,7 @@
#include "star_system.h"
#include "space_station.h"
#include "sbre/sbre.h"
+#include "serializer.h"
dWorldID Space::world;
std::list Space::bodies;
@@ -26,6 +27,26 @@ void Space::Init(void) {
//dWorldSetGravity(world, 0, -9.81, 0);
}
+void Space::Serialize(void) {
+ using namespace Serializer::Write;
+ Serializer::IndexFrames();
+ printf("%d bodies to write\n", bodies.size());
+ wr_int(bodies.size());
+ for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
+ (*i)->Serialize();
+ }
+}
+
+void Space::Unserialize(void) {
+ using namespace Serializer::Read;
+ Serializer::IndexFrames();
+ int num_bodies = rd_int();
+ printf("%d bodies to read\n", num_bodies);
+ for(int i = 0; i < num_bodies; i++) {
+ bodies.push_back(Body::Unserialize());
+ }
+}
+
void Space::Clear(void) {
for(std::list::iterator i = bodies.begin(); i != bodies.end(); ++i) {
(*i)->SetFrame(NULL);
@@ -242,15 +263,14 @@ void Space::UpdateFramesOfReference(void) {
static bool _OnCollision(dGeomID g1, dGeomID g2, Object* o1, Object* o2,
int numContacts, dContact contacts[]) {
- if((o1->GetType() == Object::LASER) || (o2->GetType() == Object::LASER)) {
- if(o1->GetType() == Object::LASER) {
+ if((o1->IsType(Object::LASER)) || (o2->IsType(Object::LASER))) {
+ if(o1->IsType(Object::LASER)) {
std::swap