Lephisto/src/player.cpp
Allanis e43c75060f [Change] Improved mouse control.
[Add] Added a few shiptypes. Don't yell at me for pathetic names.
2017-11-12 20:19:10 +00:00

243 lines
7.1 KiB
C++

#include "l3d.h"
#include "player.h"
#include "frame.h"
#include "space.h"
#include "gui.h"
#include "world_view.h"
#include "space_station_view.h"
#define DEG_2_RAD 0.0174532925
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;
}
void Player::Render(const Frame* camFrame) {
if(L3D::GetCamType() == L3D::CAM_EXTERNAL) {
Ship::Render(camFrame);
} else {
glPushMatrix();
/* Could only rotate, since transform is zero (camFrame is at player origin). */
TransformToModelCoords(camFrame);
RenderLaserfire();
glPopMatrix();
}
}
void Player::SetDockedWith(SpaceStation* s) {
Ship::SetDockedWith(s);
if(s) {
L3D::SetView(L3D::spaceStationView);
}
}
vector3d Player::GetExternalViewTranslation(void) {
vector3d p = vector3d(0, 0, m_external_view_dist);
p = matrix4x4d::RotateXMatrix(-DEG_2_RAD*m_external_view_rotx) * p;
p = matrix4x4d::RotateYMatrix(-DEG_2_RAD*m_external_view_roty) * p;
matrix4x4d m;
GetRotMatrix(m);
p = m*p;
//printf("%f,%f,%f\n", p.x, p.y, p.z);
return p;
}
void Player::ApplyExternalViewRotation(void) {
//glTranslatef(0, 0, m_external_view_dist);
glRotatef(-m_external_view_rotx, 1, 0, 0);
glRotatef(-m_external_view_roty, 0, 1, 0);
}
#define MOUSE_CTRL_AREA 10.0f
#define MOUSE_RESTITUTION 0.9f
void Player::AITurn(void) {
int mouseMotion[2];
float time_step = L3D::GetTimeStep();
float ts2 = time_step*time_step;
SetAngThrusterState(0, 0.0f);
SetAngThrusterState(1, 0.0f);
SetAngThrusterState(2, 0.0f);
if(time_step == 0) return;
if(GetDockedWith()) return;
float mx, my;
{
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;
}
ClearThrusterState();
if(L3D::KeyState(SDLK_w)) SetThrusterState(ShipType::THRUSTER_REAR, 1.0f);
if(L3D::KeyState(SDLK_s)) SetThrusterState(ShipType::THRUSTER_FRONT, 1.0f);
if(L3D::KeyState(SDLK_2)) SetThrusterState(ShipType::THRUSTER_TOP, 1.0f);
if(L3D::KeyState(SDLK_x)) SetThrusterState(ShipType::THRUSTER_BOTTOM,1.0f);
if(L3D::KeyState(SDLK_a)) SetThrusterState(ShipType::THRUSTER_LEFT, 1.0f);
if(L3D::KeyState(SDLK_d)) SetThrusterState(ShipType::THRUSTER_RIGHT, 1.0f);
if(L3D::KeyState(SDLK_SPACE)) SetGunState(0,1);
else SetGunState(0,0);
/* No torques at huge time accels -- ODE hates it. */
if(time_step <= 10) {
/*
* Dividing by time step so controls don't go totally mental 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);
}
if(time_step > 10) {
dBodySetAngularVel(m_body, 0, 0, 0);
}
if(L3D::GetCamType() == L3D::CAM_EXTERNAL) {
if(L3D::KeyState(SDLK_UP)) m_external_view_rotx -= 1;
if(L3D::KeyState(SDLK_DOWN)) m_external_view_rotx += 1;
if(L3D::KeyState(SDLK_LEFT)) m_external_view_roty -= 1;
if(L3D::KeyState(SDLK_RIGHT)) m_external_view_roty += 1;
if(L3D::KeyState(SDLK_EQUALS)) m_external_view_dist -= 10;
if(L3D::KeyState(SDLK_MINUS)) m_external_view_dist += 10;
m_external_view_dist = MAX(50, m_external_view_dist);
}
Ship::AITurn();
}
#define HUD_CROSSHAIR_SIZE 24.0f
void Player::DrawHUD(const Frame* cam_frame) {
GLdouble modelMatrix[16];
GLdouble projMatrix[16];
GLint viewport[4];
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
glGetIntegerv(GL_VIEWPORT, viewport);
const dReal* vel = dBodyGetLinearVel(m_body);
const matrix4x4d& rot = L3D::world_view->viewingRotation;
vector3d loc_v = rot*vector3d(vel[0], vel[1], vel[2]);
Gui::Screen::EnterOrtho();
glColor3f(.7, .7, .7);
{
for(std::list<Body*>::iterator i = Space::bodies.begin(); i != Space::bodies.end(); ++i) {
Body* b = *i;
if(b == this) continue;
vector3d _pos = b->GetPositionRelTo(cam_frame);
vector3d cam_coord = rot*_pos;
if(cam_coord.z < 0)
if(Gui::Screen::Project(_pos.x, _pos.y, _pos.z, modelMatrix, projMatrix,
viewport, &_pos.x, &_pos.y, &_pos.z)) {
Gui::Screen::RenderLabel(b->GetLabel(), _pos.x, _pos.y);
}
}
}
GLdouble pos[3];
const float sz = HUD_CROSSHAIR_SIZE;
/* If velocity vector is in front ofus. Draw indicator. */
if(loc_v.z < 0) {
if(Gui::Screen::Project(vel[0],vel[1],vel[2], modelMatrix, projMatrix, viewport,
&pos[0], &pos[1], &pos[2])) {
glBegin(GL_LINES);
glVertex2f(pos[0]-sz, pos[1]-sz);
glVertex2f(pos[0]-0.5*sz, pos[1]-0.5*sz);
glVertex2f(pos[0]+sz, pos[1]-sz);
glVertex2f(pos[0]+0.5*sz, pos[1]-0.5*sz);
glVertex2f(pos[0]+sz, pos[1]+sz);
glVertex2f(pos[0]+0.5*sz, pos[1]+0.5*sz);
glVertex2f(pos[0]-sz, pos[1]+sz);
glVertex2f(pos[0]-0.5*sz, pos[1]+0.5*sz);
glEnd();
}
}
if(L3D::GetCamType() == L3D::CAM_FRONT) {
/* Normal crosshairs. */
float px = Gui::Screen::GetWidth()/2.0;
float py = Gui::Screen::GetHeight()/2.0;
glBegin(GL_LINES);
glVertex2f(px-sz, py);
glVertex2f(px-0.5*sz, py);
glVertex2f(px+sz, py);
glVertex2f(px+0.5*sz, py);
glVertex2f(px, py-sz);
glVertex2f(px, py-0.5*sz);
glVertex2f(px, py+sz);
glVertex2f(px, py+0.5*sz);
glEnd();
}
{
char buf[1024];
glPushMatrix();
glTranslatef(0, 440, 0);
vector3d pos = GetPosition();
vector3d abs_pos = GetPositionRelTo(Space::GetRootFrame());
const char* rel_to = (GetFrame() ? GetFrame()->GetLabel() : "System");
snprintf(buf, sizeof(buf), "Pos: %.1f,%.1f,%.1f\n"
"AbsPos: %.1f,%.1f,%.1f\n"
"Rel-to: %s",
pos.x, pos.y, pos.z,
abs_pos.x, abs_pos.y, abs_pos.z,
rel_to);
Gui::Screen::RenderString(buf);
glPopMatrix();
}
{
double _vel = sqrt(vel[0]*vel[0] + vel[1]*vel[1] + vel[2]*vel[2]);
char buf[128];
if(_vel > 1000) {
snprintf(buf, sizeof(buf), "Velocity: %.2f km/s", _vel*0.001);
} else {
snprintf(buf, sizeof(buf), "Velocity: %.0f m/s", _vel);
}
glPushMatrix();
glTranslatef(2, 66, 0);
Gui::Screen::RenderString(buf);
glPopMatrix();
}
Gui::Screen::LeaveOrtho();
}