mirror of
https://github.com/tribes2/engine.git
synced 2026-01-21 12:14:46 +00:00
395 lines
12 KiB
C++
395 lines
12 KiB
C++
//-----------------------------------------------------------------------------
|
|
// V12 Engine
|
|
//
|
|
// Copyright (c) 2001 GarageGames.Com
|
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "game/gameTSCtrl.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "game/projectile.h"
|
|
#include "game/gameBase.h"
|
|
#include "game/gameConnection.h"
|
|
#include "game/shapeBase.h"
|
|
#include "game/player.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Debug stuff:
|
|
Point3F lineTestStart = Point3F(0, 0, 0);
|
|
Point3F lineTestEnd = Point3F(0, 1000, 0);
|
|
Point3F lineTestIntersect = Point3F(0, 0, 0);
|
|
bool gSnapLine = false;
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Class: GameTSCtrl
|
|
//----------------------------------------------------------------------------
|
|
IMPLEMENT_CONOBJECT(GameTSCtrl);
|
|
|
|
GameTSCtrl::GameTSCtrl()
|
|
{
|
|
// field data
|
|
mBeaconBaseTextureName = StringTable->insert("gui/beacon_base");
|
|
mBeaconTargetTextureName = StringTable->insert("gui/crosshairs");
|
|
mBeaconTargetPeriod = 4000;
|
|
mBeaconsVisible = true;
|
|
mBeaconLineWidth = 2.5f;
|
|
mBeaconLineBeginColor = ColorF(0.f, 1.f, 0.f, 0.2f);
|
|
mBeaconLineEndColor = ColorF(0.f, 1.f, 0.f, 0.8f);
|
|
mVehicleBeaconBeginColor = ColorF(1.f, 0.f, 0.f, 0.2f);
|
|
mVehicleBeaconEndColor = ColorF(1.f, 0.f, 0.f, 0.8f);
|
|
mFriendBeaconBeginColor = ColorF(1.f, 1.f, 0.f, 0.2f);
|
|
mFriendBeaconEndColor = ColorF(1.f, 1.f, 0.f, 0.8f);
|
|
mBeaconTextYOffset = 14;
|
|
mShowAlternateTarget = false;
|
|
}
|
|
|
|
bool GameTSCtrl::onWake()
|
|
{
|
|
if(!Parent::onWake())
|
|
return(false);
|
|
|
|
mBeaconTargetTexture = TextureHandle(mBeaconTargetTextureName);
|
|
mBeaconBaseTexture = TextureHandle(mBeaconBaseTextureName);
|
|
return(true);
|
|
}
|
|
|
|
void GameTSCtrl::onSleep()
|
|
{
|
|
Parent::onSleep();
|
|
mBeaconTargetTexture = 0;
|
|
mBeaconBaseTexture = 0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
bool GameTSCtrl::processCameraQuery(CameraQuery *camq)
|
|
{
|
|
GameUpdateCameraFov();
|
|
return GameProcessCameraQuery(camq);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void GameTSCtrl::renderBeacon(const GameBase * beaconObj, const Point3F & eyePos,
|
|
const Point3F & sourcePos, const VectorF & sourceVel,
|
|
const ProjectileData * projectile,
|
|
const bool pilot, const F32 pilotHeight)
|
|
{
|
|
Point3F pos;
|
|
beaconObj->getTransform().getColumn(3, &pos);
|
|
ShapeBase * shBeacon = static_cast<ShapeBase *>(const_cast<GameBase *>(beaconObj));
|
|
mBeaconTextPos.push_back(Point3F(pos.x, pos.y, (pilot) ? pilotHeight : pos.z));
|
|
|
|
Point3F dir = Point3F(pos - eyePos);
|
|
if( dir.isZero() ) return;
|
|
dir.normalize();
|
|
|
|
F32 width = F32(mBeaconBaseTexture.getWidth()) * (100.f * mTan(mDegToRad(GameGetCameraFov()/2.f))) / F32(getExtent().x);
|
|
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, mBeaconBaseTexture.getGLName());
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
ColorF beginColor(mBeaconLineBeginColor);
|
|
ColorF endColor(mBeaconLineEndColor);
|
|
S32 beaconType = shBeacon->getBeaconType();
|
|
if(beaconType == GameBase::vehicleBeacon)
|
|
{
|
|
beginColor = mVehicleBeaconBeginColor;
|
|
endColor = mVehicleBeaconEndColor;
|
|
}
|
|
else if(beaconType == GameBase::friendBeacon)
|
|
{
|
|
beginColor = mFriendBeaconBeginColor;
|
|
endColor = mFriendBeaconEndColor;
|
|
}
|
|
|
|
glColor4f(beginColor.red, beginColor.green,
|
|
beginColor.blue, beginColor.alpha);
|
|
|
|
dglDrawBillboard(eyePos + dir * 100.f, width, 0.f);
|
|
|
|
// targeted image:
|
|
if(!projectile && !pilot || (beaconType == GameBase::friendBeacon))
|
|
return;
|
|
|
|
VectorF vector[2];
|
|
F32 time[2];
|
|
Point3F hit;
|
|
|
|
if(!pilot)
|
|
{
|
|
// solveQuartic has problems if both velocities are |0|
|
|
Point3F vel = beaconObj->getVelocity();
|
|
Point3F srcVel = sourceVel;
|
|
if(vel.isZero() && srcVel.isZero())
|
|
{
|
|
vel.set(1.f,0.f,0.f);
|
|
srcVel.set(1.f,0.f,0.f);
|
|
}
|
|
|
|
// can reach it?
|
|
if(!(const_cast<ProjectileData*>(projectile))->calculateAim(pos, vel, sourcePos, srcVel,
|
|
&vector[0], &time[0], &vector[1], &time[1]))
|
|
return;
|
|
|
|
if(mShowAlternateTarget)
|
|
{
|
|
vector[0] = vector[1];
|
|
time[0] = time[1];
|
|
}
|
|
|
|
// just show the min time target:
|
|
dir = Point3F(pos - sourcePos);
|
|
if( dir.isZero() ) return;
|
|
dir.normalize();
|
|
|
|
PlaneF plane(sourcePos + dir * 100.f, -vector[0]);
|
|
F32 dist = plane.distToPlane(sourcePos);
|
|
|
|
hit = sourcePos + (eyePos - sourcePos) + vector[0] * dist;
|
|
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, mBeaconTargetTexture.getGLName());
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
F32 rot = 0.f;
|
|
if(mBeaconTargetPeriod > 0)
|
|
rot = (F32(Sim::getCurrentTime() % mBeaconTargetPeriod) * 2.f * M_PI) / F32(mBeaconTargetPeriod);
|
|
|
|
width = F32(mBeaconTargetTexture.getWidth()) * (dist * mTan(mDegToRad(GameGetCameraFov()/2.f))) / F32(getExtent().x);
|
|
glColor4f(beginColor.red, beginColor.green,
|
|
beginColor.blue, beginColor.alpha);
|
|
|
|
dglDrawBillboard(hit, width, rot);
|
|
}
|
|
else
|
|
{
|
|
width = 5;
|
|
dglDrawBillboard(Point3F(pos.x, pos.y, pilotHeight), width, 0.f);
|
|
hit.set(pos.x, pos.y, pilotHeight - (width * 0.31f));
|
|
}
|
|
|
|
// render a line:
|
|
glDisable(GL_TEXTURE_2D);
|
|
glLineWidth(mBeaconLineWidth);
|
|
|
|
glBegin(GL_LINES);
|
|
glColor4f(beginColor.red, beginColor.green,
|
|
beginColor.blue, beginColor.alpha);
|
|
glVertex3f(pos.x, pos.y, pos.z);
|
|
|
|
glColor4f(beginColor.red, beginColor.green,
|
|
beginColor.blue, beginColor.alpha);
|
|
glVertex3f(hit.x, hit.y, hit.z);
|
|
glEnd();
|
|
|
|
glLineWidth(1.f);
|
|
}
|
|
|
|
void GameTSCtrl::renderBeacons()
|
|
{
|
|
if(!mBeaconsVisible)
|
|
return;
|
|
|
|
mBeaconTextPos.clear();
|
|
|
|
if(!bool(mBeaconBaseTexture) || !bool(mBeaconTargetTexture))
|
|
return;
|
|
|
|
GameConnection * gc = GameConnection::getServerConnection();
|
|
if(!gc)
|
|
return;
|
|
|
|
U32 sensorGroup = gc->getSensorGroup();
|
|
|
|
// make sure firstperson...
|
|
if(!gc->isFirstPerson())
|
|
return;
|
|
|
|
// make sure its a player?
|
|
Player * player = static_cast<Player *>(gc->getControlObject());
|
|
if(!player)
|
|
return;
|
|
|
|
F32 pilotHeight = 0.0f;
|
|
if(player->isPilot())
|
|
{
|
|
Point3F pilotPos;
|
|
player->getTransform().getColumn(3, &pilotPos);
|
|
pilotHeight = pilotPos.z;
|
|
}
|
|
|
|
// grab the control object
|
|
ShapeBase * controlObj = player->getControlObject();
|
|
if(!controlObj)
|
|
controlObj = player;
|
|
|
|
// grab the weapon image:
|
|
ShapeBaseImageData * weaponImage = controlObj->getMountedImage(controlObj->getActiveImage());
|
|
|
|
ProjectileData * projectile = 0;
|
|
if(weaponImage)
|
|
projectile = weaponImage->projectile;
|
|
|
|
// get the source point:
|
|
Point3F muzzlePos;
|
|
controlObj->getMuzzlePoint(0, &muzzlePos);
|
|
|
|
// get the eye point;
|
|
MatrixF mat;
|
|
controlObj->getEyeTransform(&mat);
|
|
|
|
Point3F eyePos;
|
|
mat.getColumn(3, &eyePos);
|
|
|
|
SimSet * targetSet = Sim::getClientTargetSet();
|
|
for(SimSet::iterator itr = targetSet->begin(); itr != targetSet->end(); ++itr)
|
|
{
|
|
GameBase * target = dynamic_cast<GameBase*>(*itr);
|
|
if(!target || !target->isBeacon())
|
|
continue;
|
|
|
|
S32 targId = target->getTarget();
|
|
if((targId != -1) && (gTargetManager->getTargetSensorGroup(targId) == sensorGroup))
|
|
renderBeacon(target, eyePos, muzzlePos, controlObj->getVelocity(), projectile, player->isPilot(), pilotHeight);
|
|
}
|
|
}
|
|
|
|
void GameTSCtrl::renderBeaconsText()
|
|
{
|
|
if(!mBeaconsVisible || !mBeaconTextPos.size())
|
|
return;
|
|
|
|
GameConnection * gc = GameConnection::getServerConnection();
|
|
if(!gc)
|
|
return;
|
|
|
|
// grab the control object
|
|
ShapeBase * controlObj = gc->getControlObject();
|
|
if(!controlObj)
|
|
return;
|
|
|
|
// get the eye point;
|
|
MatrixF mat;
|
|
controlObj->getEyeTransform(&mat);
|
|
|
|
Point3F eyePos;
|
|
mat.getColumn(3, &eyePos);
|
|
|
|
U32 height = mProfile->mFont->getHeight();
|
|
|
|
Point3F sPos;
|
|
for(U32 i = 0; i < mBeaconTextPos.size(); i++)
|
|
{
|
|
if(project(mBeaconTextPos[i], &sPos))
|
|
{
|
|
F32 dist = Point3F(mBeaconTextPos[i] - eyePos).len();
|
|
dist = mClampF(dist, 0.f, 999.9f);
|
|
|
|
char buf[40];
|
|
dSprintf(buf, sizeof(buf), "%3.1f", dist);
|
|
|
|
U32 width = mProfile->mFont->getStrWidth(buf);
|
|
|
|
dglClearBitmapModulation();
|
|
|
|
Point2I pos(S32(sPos.x - F32(width / 2)), S32(sPos.y - F32(height / 2)) + mBeaconTextYOffset);
|
|
dglDrawText(mProfile->mFont, pos, buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
static bool gHudHackCalled = false;
|
|
void GameTSCtrl::renderWorld(const RectI &updateRect)
|
|
{
|
|
//#pragma message("E3 hack here to reshow the HUD elements after loading is complete.");
|
|
if (! gHudHackCalled)
|
|
{
|
|
gHudHackCalled = true;
|
|
Con::executef(2, "HideHudHACK", "true");
|
|
}
|
|
|
|
GameRenderWorld();
|
|
|
|
renderBeacons();
|
|
dglSetClipRect(updateRect);
|
|
renderBeaconsText();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void GameTSCtrl::onMouseMove(const GuiEvent &evt)
|
|
{
|
|
if(gSnapLine)
|
|
return;
|
|
|
|
MatrixF mat;
|
|
Point3F vel;
|
|
if ( GameGetCameraTransform(&mat, &vel) )
|
|
{
|
|
Point3F pos;
|
|
mat.getColumn(3,&pos);
|
|
Point3F screenPoint(evt.mousePoint.x, evt.mousePoint.y, -1);
|
|
Point3F worldPoint;
|
|
if (unproject(screenPoint, &worldPoint)) {
|
|
Point3F vec = worldPoint - pos;
|
|
lineTestStart = pos;
|
|
vec.normalizeSafe();
|
|
lineTestEnd = pos + vec * 1000;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GameTSCtrl::onRender(Point2I offset, const RectI &updateRect, GuiControl *firstResponder)
|
|
{
|
|
// check if should bother with a render
|
|
GameConnection * con = GameConnection::getServerConnection();
|
|
bool skipRender = !con || (con->getWhiteOut() >= 1.f) || (con->getDamageFlash() >= 1.f) || (con->getBlackOut() >= 1.f);
|
|
|
|
if(!skipRender)
|
|
{
|
|
Parent::onRender(offset, updateRect, firstResponder);
|
|
renderChildControls(offset, updateRect, firstResponder);
|
|
}
|
|
|
|
dglSetViewport(updateRect);
|
|
CameraQuery camq;
|
|
if(GameProcessCameraQuery(&camq))
|
|
GameRenderFilters(camq);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void GameTSCtrl::initPersistFields()
|
|
{
|
|
Parent::initPersistFields();
|
|
addField("beaconBaseTextureName", TypeString, Offset(mBeaconBaseTextureName, GameTSCtrl));
|
|
addField("beaconTargetTextureName", TypeString, Offset(mBeaconTargetTextureName, GameTSCtrl));
|
|
addField("beaconTargetPeriod", TypeS32, Offset(mBeaconTargetPeriod, GameTSCtrl));
|
|
addField("beaconsVisible", TypeBool, Offset(mBeaconsVisible, GameTSCtrl));
|
|
addField("enemyBeaconLineBeginColor", TypeColorF, Offset(mBeaconLineBeginColor, GameTSCtrl));
|
|
addField("enemyBeaconLineEndColor", TypeColorF, Offset(mBeaconLineEndColor, GameTSCtrl));
|
|
addField("vehicleBeaconLineBeginColor", TypeColorF, Offset(mVehicleBeaconBeginColor, GameTSCtrl));
|
|
addField("vehicleBeaconLineEndColor", TypeColorF, Offset(mVehicleBeaconEndColor, GameTSCtrl));
|
|
addField("friendBeaconLineBeginColor", TypeColorF, Offset(mFriendBeaconBeginColor, GameTSCtrl));
|
|
addField("friendBeaconLineEndColor", TypeColorF, Offset(mFriendBeaconEndColor, GameTSCtrl));
|
|
addField("beaconLineWidth", TypeF32, Offset(mBeaconLineWidth, GameTSCtrl));
|
|
addField("beaconTextYOffset", TypeS32, Offset(mBeaconTextYOffset, GameTSCtrl));
|
|
addField("showAlternateTarget", TypeBool, Offset(mShowAlternateTarget, GameTSCtrl));
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void cSnapToggle(SimObject *, S32, const char **)
|
|
{
|
|
gSnapLine = !gSnapLine;
|
|
}
|
|
|
|
void GameTSCtrl::consoleInit()
|
|
{
|
|
Con::addCommand("snapToggle", cSnapToggle, "snapToggle();", 1, 1);
|
|
}
|