diff --git a/icons/cpan_f2_normal.png b/icons/cpan_f2_normal.png index a791b57..79f948c 100644 Binary files a/icons/cpan_f2_normal.png and b/icons/cpan_f2_normal.png differ diff --git a/icons/cpan_f3_shipinfo.png b/icons/cpan_f3_shipinfo.png new file mode 100644 index 0000000..843b9a9 Binary files /dev/null and b/icons/cpan_f3_shipinfo.png differ diff --git a/src/Makefile.am b/src/Makefile.am index 377397f..797898d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,7 +7,8 @@ Lephisto3D_SOURCES = main.cpp gui_button.cpp gui.cpp gui_fixed.cpp gui_screen.cp gui_radio_group.cpp rigid_body.cpp planet.cpp star.cpp frame.cpp gui_image_button.cpp gui_image.cpp \ gui_image_radio_button.cpp gui_multi_state_image_button.cpp ship_cpanel.cpp gui_widget.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 \ - gui_container.cpp date.cpp space_station.cpp space_station_view.cpp static_rigid_body.cpp ship_type.cpp + gui_container.cpp date.cpp space_station.cpp space_station_view.cpp static_rigid_body.cpp ship_type.cpp \ + info_view.cpp Lephisto3D_LDADD = sbre/libsbre.a include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h gui_container.h gui_events.h gui_fixed.h \ @@ -15,5 +16,5 @@ include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h gui_radio_group.h gui_screen.h gui_toggle_button.h gui_widget.h libs.h matrix4x4.h mtrand.h objimport.h l3d.h \ planet.h player.h rigid_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 static_rigid_body.h gui_iselectable.h \ - ship_type.h object.h + ship_type.h object.h info_view.h diff --git a/src/info_view.cpp b/src/info_view.cpp new file mode 100644 index 0000000..965ed5d --- /dev/null +++ b/src/info_view.cpp @@ -0,0 +1,46 @@ +#include "info_view.h" +#include "l3d.h" +#include "player.h" +#include "world_view.h" +#include "ship.h" + +InfoView::InfoView(void) : View() { + SetTransparency(false); + SetBgColor(.0, .2, .4); + + float size[2]; + GetSize(size); + + info1 = new Gui::Label("Some star stuff."); + Add(info1, 40, size[1]-40); +} + +void InfoView::UpdateInfo(void) { + char buf[512]; + std::string nfo; + const ShipType& stype = L3D::player->GetShipType(); + nfo = "SHIP INFORMATION: "+std::string(stype.name); + + Equip::Type e = L3D::player->m_equipment.Get(Equip::SLOT_ENGINE); + nfo += std::string("\n\nDrive system: ")+EquipType::types[e].name; + + shipstats_t stats; + L3D::player->CalcStats(&stats); + snprintf(buf, sizeof(buf), "n\nCapacity: %dt\n" + "Free: %dt\n" + "Used: %dt\n" + "All-up weight: %dt", stats.max_capacity, + stats.free_capacity, stats.used_capacity, + stats.total_mass); + nfo += std::string(buf); + info1->SetText(nfo); +} + +void InfoView::Draw3D(void) { + +} + +void InfoView::Update(void) { + +} + diff --git a/src/info_view.h b/src/info_view.h new file mode 100644 index 0000000..cdf66d5 --- /dev/null +++ b/src/info_view.h @@ -0,0 +1,15 @@ +#pragma once +#include "libs.h" +#include "gui.h" +#include "view.h" + +class InfoView : public View { +public: + InfoView(void); + void UpdateInfo(void); + virtual void Update(void); + virtual void Draw3D(void); +private: + Gui::Label* info1; +}; + diff --git a/src/l3d.h b/src/l3d.h index 50032d6..6273839 100644 --- a/src/l3d.h +++ b/src/l3d.h @@ -14,6 +14,7 @@ class SystemInfoView; class ShipCpanel; class StarSystem; class SpaceStationView; +class InfoView; class IniConfig: private std::map { public: @@ -73,7 +74,7 @@ public: static SystemInfoView* system_info_view; static WorldView* world_view; static SpaceStationView* spaceStationView; - + static InfoView* infoView; static ShipCpanel* cpan; static GLUquadric* gluQuadric; diff --git a/src/main.cpp b/src/main.cpp index 4a0bf9b..d4f350a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,7 @@ #include "star_system.h" #include "space_station.h" #include "space_station_view.h" +#include "info_view.h" float L3D::timeStep = 1.0f; int L3D::scrWidth; @@ -35,6 +36,7 @@ Player* L3D::player; View* L3D::current_view; WorldView* L3D::world_view; SpaceStationView* L3D::spaceStationView; +InfoView* L3D::infoView; SectorView* L3D::sector_view; SystemView* L3D::system_view; SystemInfoView* L3D::system_info_view; @@ -234,6 +236,7 @@ void L3D::MainLoop(void) { system_info_view = new SystemInfoView(); world_view = new WorldView(); spaceStationView = new SpaceStationView(); + infoView = new InfoView(); SetView(world_view); diff --git a/src/planet.cpp b/src/planet.cpp index 7d94c2b..f83ddbd 100644 --- a/src/planet.cpp +++ b/src/planet.cpp @@ -7,6 +7,7 @@ Planet::Planet(StarSystem::SBody::SubType subtype) : Body() { m_radius = 6378135.0; m_pos = vector3d(0, 0, 0); m_geom = dCreateSphere(0, m_radius); + dGeomSetData(m_geom, static_cast(this)); m_subtype = subtype; } diff --git a/src/planet.h b/src/planet.h index c56f2f7..50588f9 100644 --- a/src/planet.h +++ b/src/planet.h @@ -15,6 +15,7 @@ public: virtual void TransformToModelCoords(const Frame* camFrame); virtual void TransformCameraTo(void) {}; virtual void SetFrame(Frame* f); + virtual bool OnCollision(Body* b) { return true; } private: vector3d m_pos; double m_radius; diff --git a/src/player.cpp b/src/player.cpp index e123cab..84fc18c 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -12,6 +12,8 @@ Player::Player(ShipType::Type shipType) : Ship(shipType) { m_external_view_rotx = m_external_view_roty = 0; m_external_view_dist = 200; m_mouseCMov[0] = m_mouseCMov[1] = 0; + m_equipment.Set(Equip::SLOT_ENGINE, 0, Equip::DRIVE_CLASS1); + UpdateMass(); } void Player::Render(const Frame* camFrame) { @@ -65,17 +67,17 @@ void Player::AITurn(void) { if(time_step == 0) return; if(GetDockedWith()) return; - float mx, my; + vector3f angThrust(0.0f); - { + if(L3D::MouseButtonState(3)) { float restitution = powf(MOUSE_RESTITUTION, time_step); L3D::GetMouseMotion(mouseMotion); m_mouseCMov[0] += mouseMotion[0]; m_mouseCMov[1] += mouseMotion[1]; m_mouseCMov[0] = CLAMP(m_mouseCMov[0]*restitution, -MOUSE_CTRL_AREA, MOUSE_CTRL_AREA); m_mouseCMov[1] = CLAMP(m_mouseCMov[1]*restitution, -MOUSE_CTRL_AREA, MOUSE_CTRL_AREA); - mx = -m_mouseCMov[0] / MOUSE_CTRL_AREA; - my = m_mouseCMov[1] / MOUSE_CTRL_AREA; + angThrust.y = -m_mouseCMov[0] / MOUSE_CTRL_AREA; + angThrust.x = m_mouseCMov[1] / MOUSE_CTRL_AREA; } ClearThrusterState(); @@ -91,30 +93,32 @@ void Player::AITurn(void) { /* No torques at huge time accels -- ODE hates it. */ if(time_step <= 10) { + if(L3D::GetCamType() != L3D::CAM_EXTERNAL) { + if(L3D::KeyState(SDLK_LEFT)) angThrust.y += 1; + if(L3D::KeyState(SDLK_RIGHT)) angThrust.y += -1; + if(L3D::KeyState(SDLK_UP)) angThrust.x += -1; + if(L3D::KeyState(SDLK_DOWN)) angThrust.x += 1; + } + /* Rotation damping. */ + const dReal* _av = dBodyGetAngularVel(m_body); + vector3d angVel(_av[0], _av[1], _av[2]); + matrix4x4d rot; + GetRotMatrix(rot); + angVel = rot.InverseOf() * angVel; + + angVel *= 0.4; + angThrust.x -= angVel.x; + angThrust.y -= angVel.y; + angThrust.z -= angVel.z; + /* - * Dividing by time step so controls don't go totally mental when + * Divided by time step so controls don't go totally insane when * used at 10x accel. */ - mx /= ts2; - my /= ts2; - if(L3D::MouseButtonState(3)) { - SetAngThrusterState(1, mx); - SetAngThrusterState(0, my); - } else if(L3D::GetCamType() != L3D::CAM_EXTERNAL) { - float ax = 0; - float ay = 0; - if(L3D::KeyState(SDLK_LEFT)) ay += 1; - if(L3D::KeyState(SDLK_RIGHT)) ay += -1; - if(L3D::KeyState(SDLK_UP)) ax += -1; - if(L3D::KeyState(SDLK_DOWN)) ax += 1; - SetAngThrusterState(2, 0); - SetAngThrusterState(1, ay); - SetAngThrusterState(0, ax); - } - - /* Rotation damping. */ - vector3d angDrag = GetAngularMomentum() * time_step; - dBodyAddTorque(m_body, -angDrag.x, -angDrag.y, -angDrag.z); + angThrust *= 1.0f/ts2; + SetAngThrusterState(0, angThrust.x); + SetAngThrusterState(1, angThrust.y); + SetAngThrusterState(2, angThrust.z); } if(time_step > 10) { dBodySetAngularVel(m_body, 0, 0, 0); diff --git a/src/ship.cpp b/src/ship.cpp index 7615b22..a1a19f3 100644 --- a/src/ship.cpp +++ b/src/ship.cpp @@ -12,6 +12,7 @@ Ship::Ship(ShipType::Type shipType) : RigidBody() { m_shipType = shipType; m_angThrusters[0] = m_angThrusters[1] = m_angThrusters[2] = 0; m_laserCollisionObj.owner = this; + m_equipment = EquipSet(shipType); for(int i = 0; i < ShipType::GUNMOUNT_MAX; i++) { m_tempLaserGeom[i] = 0; m_gunState[i] = 0; @@ -19,6 +20,12 @@ Ship::Ship(ShipType::Type shipType) : RigidBody() { dGeomSetData(m_geom, static_cast(this)); } +void Ship::UpdateMass(void) { + shipstats_t s; + CalcStats(&s); + dMassAdjust(&m_mass, s.total_mass*1000); +} + void Ship::SetThrusterState(enum ShipType::Thruster t, float level) { m_thrusters[t] = level; } @@ -27,6 +34,24 @@ void Ship::ClearThrusterState(void) { for(int i = 0; i < ShipType::THRUSTER_MAX; i++) m_thrusters[i] = 0; } +/* Hyperspace range is: + * (200 * hyperspace_class^2) / total_mass (in tonnes) + */ +void Ship::CalcStats(shipstats_t* stats) { + const ShipType& stype = GetShipType(); + stats->max_capacity = stype.capacity; + stats->used_capacity = 0; + + for(int i = 0; i < Equip::SLOT_MAX; i++) { + for(int j = 0; j < stype.equipSlotCapacity[i]; j++) { + Equip::Type t = m_equipment.Get((Equip::Slot)i, j); + if(t) stats->used_capacity += EquipType::types[t].mass; + } + } + stats->free_capacity = stats->max_capacity - stats->used_capacity; + stats->total_mass = stats->used_capacity + stype.hullMass; +} + void Ship::AITurn(void) { const ShipType& stype = GetShipType(); float timeStep = L3D::GetTimeStep(); @@ -55,7 +80,6 @@ void Ship::AITurn(void) { m_tempLaserGeom[i] = 0; if(!m_gunState[i]) continue; dGeomID ray = dCreateRay(GetFrame()->GetSpaceID(), 10000); - const dReal* r = dGeomGetRotation(m_geom); const vector3d pos = GetPosition(); const vector3f _dir = stype.gunMount[i].dir; vector3d dir = vector3d(_dir.x, _dir.y, _dir.z); diff --git a/src/ship.h b/src/ship.h index bb1a581..43f09ae 100644 --- a/src/ship.h +++ b/src/ship.h @@ -5,6 +5,14 @@ class SpaceStation; +struct shipstats_t { + int max_capacity; + int used_capacity; + int free_capacity; + int total_mass; /* Cargo, equipment + hull. */ + float hyperspace_range; +}; + class Ship : public RigidBody { public: Ship(ShipType::Type shipType); @@ -18,16 +26,20 @@ public: void SetAngThrusterState(int axis, float level) { m_angThrusters[axis] = CLAMP(level, -1, 1); } void ClearThrusterState(void); void SetGunState(int idx, int state); + const ShipType& GetShipType(void); + void CalcStats(shipstats_t* stats); + void UpdateMass(void); class LaserObj : public Object { public: virtual Object::Type GetType(void) { return Object::LASER; } Ship* owner; }; + + EquipSet m_equipment; protected: void RenderLaserfire(void); - const ShipType& GetShipType(void); SpaceStation* m_dockedWith; enum ShipType::Type m_shipType; ObjMesh* m_mesh; diff --git a/src/ship_cpanel.cpp b/src/ship_cpanel.cpp index 20906a0..154add6 100644 --- a/src/ship_cpanel.cpp +++ b/src/ship_cpanel.cpp @@ -3,6 +3,7 @@ #include "ship_cpanel.h" #include "space_station_view.h" #include "player.h" +#include "info_view.h" ShipCpanel::ShipCpanel(void) : Gui::Fixed(0, 0, 640, 64) { //SetBgColor(1, 0, 0); @@ -59,6 +60,14 @@ ShipCpanel::ShipCpanel(void) : Gui::Fixed(0, 0, 640, 64) { map_button->onClick.connect(sigc::mem_fun(this, &ShipCpanel::OnChangeMapView)); Add(map_button, 34, 2); + Gui::MultiStateImageButton* info_button = new Gui::MultiStateImageButton(); + g->Add(info_button); + info_button->SetSelected(false); + info_button->SetShortcut(SDLK_F3, KMOD_NONE); + info_button->AddState(0, "icons/cpan_f3_shipinfo.png"); + info_button->onClick.connect(sigc::mem_fun(this, &ShipCpanel::OnChangeInfoView)); + Add(info_button, 66, 2); + Gui::ImageButton* comms_button = new Gui::ImageButton("icons/comms_f4.png"); //g->Add(comms_button); comms_button->SetShortcut(SDLK_F4, KMOD_NONE); @@ -88,6 +97,11 @@ void ShipCpanel::OnChangeCamView(Gui::MultiStateImageButton* b) { L3D::SetCamType((enum L3D::CamType)b->GetState()); } +void ShipCpanel::OnChangeInfoView(Gui::MultiStateImageButton* b) { + L3D::infoView->UpdateInfo(); + L3D::SetView(L3D::infoView); +} + void ShipCpanel::OnChangeMapView(Gui::MultiStateImageButton* b) { L3D::SetMapView((enum L3D::MapView)b->GetState()); } diff --git a/src/ship_cpanel.h b/src/ship_cpanel.h index b5fdf77..f619df9 100644 --- a/src/ship_cpanel.h +++ b/src/ship_cpanel.h @@ -10,6 +10,7 @@ public: private: void OnChangeCamView(Gui::MultiStateImageButton* b); void OnChangeMapView(Gui::MultiStateImageButton* b); + void OnChangeInfoView(Gui::MultiStateImageButton* b); void OnClickTimeaccel(Gui::ISelectable* i, double step); void OnClickComms(void); diff --git a/src/ship_type.cpp b/src/ship_type.cpp index ffa757a..c2f7bc2 100644 --- a/src/ship_type.cpp +++ b/src/ship_type.cpp @@ -8,11 +8,13 @@ const ShipType ShipType::types[] = { */ "Sirius Interdictor", 10, { 250, -250, 50, -50, -50, 50 }, - 700.0, + 2000.0, { { vector3f(0, -0.5, 0), vector3f(0, 0, -1) }, { vector3f(0, 0, 0), vector3f(0, 0, 1) } - } + }, + { 1, 2, 0 }, + 100, 20, }, { /* @@ -25,7 +27,9 @@ const ShipType ShipType::types[] = { { { vector3f(0, -0.5, 0), vector3f(0, 0, -1) }, { vector3f(0, 0, 0), vector3f(0, 0, 1) } - } + }, + { 1, 1, 0 }, + 60, 15, }, { "Flowerfairy Heavy Trader", @@ -35,7 +39,32 @@ const ShipType ShipType::types[] = { { { vector3f(0, -0.5, 0), vector3f(0, 0, -1) }, { vector3f(0, 0, 0), vector3f(0, 0, 1) } - } + }, + { 1, 2, 0 }, + 500, 125, + } +}; + +const EquipType EquipType::types[] = { + { + "None", + Equip::SLOT_ENGINE, + 0, + }, + { + "Interplanetary Drive", + Equip::SLOT_ENGINE, + 1 + }, + { + "Class 1 Hyperdrive", + Equip::SLOT_ENGINE, + 4 + }, + { + "1MW beam laser", + Equip::SLOT_LASER, + 1 } }; diff --git a/src/ship_type.h b/src/ship_type.h index b62b447..73c3b08 100644 --- a/src/ship_type.h +++ b/src/ship_type.h @@ -1,9 +1,14 @@ #pragma once +#include #include "libs.h" #include "vector3.h" +namespace Equip { + enum Slot { SLOT_ENGINE, SLOT_LASER, SLOT_MISSILE, SLOT_MAX }; + enum Type { NONE, DRIVE_INTERPLANETARY, DRIVE_CLASS1, LASER_1MW_BEAM }; +}; + struct ShipType { -public: enum Thruster { THRUSTER_FRONT, THRUSTER_REAR, THRUSTER_TOP, THRUSTER_BOTTOM, THRUSTER_LEFT, THRUSTER_RIGHT, THRUSTER_MAX }; enum Type { SLEEK, LADYBIRD, FLOWERFAIRY }; @@ -18,8 +23,40 @@ public: vector3f pos; vector3f dir; } gunMount[GUNMOUNT_MAX]; + int equipSlotCapacity[Equip::SLOT_MAX]; + int capacity; /* Tonnes. */ + int hullMass; /*******************************/ static const ShipType types[]; }; +class EquipSet { +public: + EquipSet(void) {} + EquipSet(ShipType::Type t) { + for(int i = 0; i < Equip::SLOT_MAX; i++) { + equip[i] = std::vector(ShipType::types[t].equipSlotCapacity[i]); + } + } + Equip::Type Get(Equip::Slot s) { + return equip[s][0]; + } + Equip::Type Get(Equip::Slot s, int idx) { + return equip[s][idx]; + } + void Set(Equip::Slot s, int idx, Equip::Type e) { + equip[s][idx] = e; + } +private: + std::vector equip[Equip::SLOT_MAX]; +}; + +struct EquipType { + const char* name; + Equip::Slot slot; + int mass; + + static const EquipType types[]; +}; +