📄 gametsctrl.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, 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"
#include "gui/core/guiCanvas.h"
#ifdef TGE_RPG
#include "game/aiPlayer.h"
#include "rpg/gobjects/RPGBase.h"
#include "rpg/gobjects/GNpc.h"
#include "rpg/gobjects/GPlayer.h"
//---------------------------------------------------------------------------
using namespace RPG;
//---------------------------------------------------------------------------
Vector<GameBase*> GameTSCtrl::ms_arGameBases(1024);
Vector<GameBase*> GameTSCtrl::ms_arNormals(1024);
Vector<GameBase*> GameTSCtrl::ms_arTaskNpcs(128);
Vector<GameBase*> GameTSCtrl::ms_arTaskLocks(128);
Point3F GameTSCtrl::ms_posMainRole;
//char GameTSCtrl::ms_sMainRolePos = {0};
//Point2I GameTSCtrl::ms_posMainRoleGrid;
F32 GameTSCtrl::ms_fRangeRadiusSqt = 50.f*50.f;
#endif
//---------------------------------------------------------------------------
// Debug stuff:
//Point3F lineTestStart = Point3F(0, 0, 0);
//Point3F lineTestEnd = Point3F(0, 1000, 0);
//Point3F lineTestIntersect = Point3F(0, 0, 0);
//bool gSnapLine = false;
U32 GameTSCtrl::ms_uDownLength = 3000;
U32 GameTSCtrl::ms_uUpdateCycle = 500;
F32 GameTSCtrl::ms_fTalkDistance = 1.0f;
//----------------------------------------------------------------------------
// Class: GameTSCtrl
//----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(GameTSCtrl);
GameTSCtrl::GameTSCtrl()
{
m_uMouseDownTimer = 0;
m_uUpdateTimer = 0;
#ifdef TGE_RPG
m_cursorState = TSC_NORMAL;
dMemset(m_arCursors,0,sizeof(m_arCursors));
#endif
}
#ifdef TGE_RPG
void GameTSCtrl::initPersistFields()
{
Parent::initPersistFields();
addField("arCursors", TypeGuiCursorPtr, Offset(m_arCursors,GameTSCtrl),TSC_AMOUNT);
}
void GameTSCtrl::getCursor(GuiCursor *&cursor, bool &visible, const GuiEvent &event)
{
cursor = m_arCursors[m_cursorState];
visible = true;
}
bool GameTSCtrl::onWake()
{
if(!Parent::onWake())
return false;
Sim::findObject(CURSOR_HAND_TXT, m_arCursors[TSC_NPC]);
Sim::findObject(CURSOR_HAND_TXT, m_arCursors[TSC_ITEM]);
return true;
}
#endif
//---------------------------------------------------------------------------
bool GameTSCtrl::processCameraQuery(CameraQuery *camq)
{
GameUpdateCameraFov();
#ifdef TGE_RPG
bool bRet = GameProcessCameraQuery(camq);
//if(bRet)
// camq->ortho = true;
return bRet;
#else
return GameProcessCameraQuery(camq);
#endif
}
//---------------------------------------------------------------------------
void GameTSCtrl::renderWorld(const RectI &updateRect)
{
GameRenderWorld();
dglSetClipRect(updateRect);
}
void GameTSCtrl::onMouseUp(const GuiEvent &evt)
{
#ifdef TGE_RPG
//Con::warnf("up...");
if(Platform::getVirtualMilliseconds() - m_uMouseDownTimer < ms_uDownLength)
{
m_uMouseDownTimer = 0;
processMouseMove(evt.mousePoint.x, evt.mousePoint.y,GMS_RELEASE);
}
#endif
mouseUnlock();
}
void GameTSCtrl::onMouseDown(const GuiEvent &evt)
{
mouseLock();
#ifdef TGE_RPG
if(m_uMouseDownTimer && Platform::getVirtualMilliseconds() - m_uMouseDownTimer >= ms_uDownLength)
{
m_uMouseDownTimer = 0;
processMouseMove(evt.mousePoint.x, evt.mousePoint.y,GMS_RELEASE);
}
else
#endif
m_uMouseDownTimer = Platform::getVirtualMilliseconds();
}
void GameTSCtrl::onRightMouseDown(const GuiEvent & event)
{
// always process the right mouse event first...
#ifdef TGE_RPG
Platform::setWindowLocked(true);
Canvas->setCursorON(false);
setFirstResponder();
#else
if(mProfile->mCanKeyFocus)
{
// ok, gotta disable the mouse
// script functions are lockMouse(true); Canvas.cursorOff();
Platform::setWindowLocked(true);
Canvas->setCursorON(false);
setFirstResponder();
}
#endif
}
void GameTSCtrl::onRightMouseUp(const GuiEvent & event)
{
}
bool GameTSCtrl::onInputEvent(const InputEvent & event)
{
#ifdef TGE_RPG
if(event.deviceType == MouseDeviceType &&
event.objInst == KEY_BUTTON1 && event.action == SI_BREAK)
{
Platform::setWindowLocked(false);
Canvas->setCursorON(true);
}
#else
if(mRightMousePassThru && event.deviceType == MouseDeviceType &&
event.objInst == KEY_BUTTON1 && event.action == SI_BREAK)
{
// if the right mouse pass thru is enabled,
// we want to reactivate mouse on a right mouse button up
Platform::setWindowLocked(false);
Canvas->setCursorON(true);
}
#endif
// we return false so that the canvas can properly process the right mouse button up...
return false;
}
//---------------------------------------------------------------------------
void GameTSCtrl::onMouseMove(const GuiEvent &evt)
{
//Con::warnf("move...");
}
void GameTSCtrl::onMouseDragged(const GuiEvent &evt)
{
}
#ifdef TGE_RPG
static void FindObjectsCallback(SceneObject* obj, void * val)
{
//Vector<GameBase*> *list = (Vector<GameBase*>*)val;
GameBase* pBase = static_cast<GameBase*>(obj);
if(pBase)
{
RPGBase* pRPGObject = pBase->getRPGBase();
if(!pRPGObject || pRPGObject->IsMainRole())
return;
VectorF shapeDir = pBase->getPosition() - GameTSCtrl::ms_posMainRole;
F32 shapeDist = shapeDir.lenSquared();
if (shapeDist == 0 || shapeDist > GameTSCtrl::ms_fRangeRadiusSqt)
return;
GameTSCtrl::ms_arGameBases.push_back(pBase);
if(pRPGObject->IsTaskLock())
GameTSCtrl::ms_arTaskLocks.push_back(pBase);
else if(pRPGObject->IsTaskNpc())
GameTSCtrl::ms_arTaskNpcs.push_back(pBase);
else
GameTSCtrl::ms_arNormals.push_back(pBase);
}
}
void GameTSCtrl::onPreRender()
{
U32 dwTimer = Platform::getVirtualMilliseconds();
if(dwTimer - m_uUpdateTimer < ms_uUpdateCycle)
return;
m_uUpdateTimer =dwTimer;
//////////////////////////////////////
///TGE_Move
Point2I cursorPos = Canvas->getCursorPos();
if(m_uMouseDownTimer)
processMouseMove(cursorPos.x, cursorPos.y,GMS_DRAG);
else
processMouseMove(cursorPos.x, cursorPos.y,GMS_MOVE);
//////////////////////////////////////
//控制物位置输出
///TGE_Move
GameConnection * connection = GameConnection::getConnectionToServer();
ms_arGameBases.clear();
ms_arNormals.clear();
ms_arTaskLocks.clear();
ms_arTaskNpcs.clear();
if(connection && connection->getControlObject())
{
static char buffer[64];
ms_posMainRole = connection->getControlObject()->getPosition();
//ms_posMainRoleGrid.x = (S32)mFloor(ms_posMainRole.x);
//ms_posMainRoleGrid.y = (S32)mFloor(ms_posMainRole.y);
dSprintf(buffer,64,"%2.0f %2.0f",mFloor(ms_posMainRole.x),mFloor(ms_posMainRole.y) );
Con::setVariable("$Player::Position", buffer );
//////////////////////////////////////
///GameBaseList
static U32 mask = PlayerObjectType | VehicleObjectType;
gClientContainer.findObjects(mask, FindObjectsCallback, NULL);
}//if(connection)
}
#endif
void GameTSCtrl::onRender(Point2I offset, const RectI &updateRect)
{
// check if should bother with a render
GameConnection * con = GameConnection::getConnectionToServer();
bool skipRender = !con || (con->getWhiteOut() >= 1.f) || (con->getDamageFlash() >= 1.f) || (con->getBlackOut() >= 1.f);
if(!skipRender)
Parent::onRender(offset, updateRect);
dglSetViewport(updateRect);
CameraQuery camq = mLastCameraQuery;
if(GameProcessCameraQuery(&camq))
GameRenderFilters(camq);
// Draw controls after so they aren't affected by the filters. (If we're doing that.)
if(!skipRender && !mApplyFilterToChildren)
Parent::renderChildControls(offset, updateRect);
}
#ifdef TGE_RPG
/// TGE_Move
///-----------------------------------------------------------------
void GameTSCtrl::processMouseMove(S32 x, S32 y,GameMouseStates state)
{
MatrixF mat;
Point3F vel;
if ( GameGetCameraTransform(&mat, &vel) )
{
Point3F camPos;
mat.getColumn(3,&camPos);
//Point3F screenPoint(evt.mousePoint.x, evt.mousePoint.y, 1);
Point3F worldPoint;
//Point2I cursorPos =Canvas->getCursorPos();
Point3F screenPoint(x, y, 1);
if (unproject(screenPoint, &worldPoint))
{
mMouse3DPos = camPos;
mMouse3DVec = worldPoint - camPos;
mMouse3DVec.normalizeSafe();
ProcessClickOnGround(state);
//Con::executef(this, 1, "onMouseDown");
}
}
}
/// TGE_Move
//--------------------------------------------------------------------------
void GameTSCtrl::ProcessClickOnGround(GameMouseStates state)
{
// Must have a connection and player control object
GameConnection* conn = GameConnection::getConnectionToServer();
if (!conn)
return;
ShapeBase* control = conn->getControlObject();
if (!control || !(control->getType() & PlayerObjectType) )
return;
control->disableCollision();
Point3F endPos;
RayInfo info;
U32 dwMask;
RPGBase* pRPGBase;
GameBase* pGameBase;
BOOL bWalk;
//bPress = (state == GMS_DRAG || state == GMS_PRESS);
endPos = mMouse3DPos + mMouse3DVec * 2000.f ;
bWalk = FALSE;
m_cursorState = TSC_NORMAL;
dwMask = PlayerObjectType | ItemObjectType;
if(state != GMS_MOVE)
dwMask |= TerrainObjectType;
if(gClientContainer.castRay(mMouse3DPos, endPos, dwMask, &info))
{
//点击人物处理
if(info.object->getType() & PlayerObjectType)
{
pGameBase = dynamic_cast<GameBase*>(info.object);
if(pGameBase)
{
pRPGBase = dynamic_cast<RPGBase*>(pGameBase->getRPGBase());
//NPC处理
if(pRPGBase && pRPGBase->IsNpc())
{
//改变鼠标形状
m_cursorState = TSC_NPC;
if(state == GMS_RELEASE)
{
//Canvas->setCursor(m_arCursors[TSC_NPC]);
Point3F posVec = pGameBase->getPosition() - control->getPosition();
//F32 fDisc = Con::getFloatVariable("$RPG::TalkDistance",1.f);
//if(fDisc < 1.f)
// fDisc = 1.f;
if(posVec.len() <= ms_fTalkDistance)
{
GNpc* pNpc = dynamic_cast<GNpc*>(pRPGBase);
if(pNpc)
{
pNpc->ProcessTalk(g_pGPlayer);
bWalk = FALSE;
}
}
else
{
F32 fTolerance = ms_fTalkDistance * 0.6f;
posVec.normalizeSafe();
endPos = pGameBase->getPosition() - posVec*fTolerance;
bWalk = TRUE;
AIPlayer* pAIPlayer = dynamic_cast<AIPlayer*>(control);
if(pAIPlayer)
{
pAIPlayer->setMoveTolerance(fTolerance);
pAIPlayer->setMoveTo();
pAIPlayer->setAimObject(pGameBase);
}
}//else
}//if
}//if NPC处理
}//if(pGameBase)
}//if(info.object->getType() & PlayerObjectType)
//点击地面处理
else if(info.object->getType() & TerrainObjectType)
{
endPos = info.point;
bWalk = TRUE;
if(state == GMS_PRESS)
{
GNpc::ToggleNpc(NULL);
AIPlayer* pAIPlayer = dynamic_cast<AIPlayer*>(control);
if(pAIPlayer)
{
pAIPlayer->setMoveTo();
pAIPlayer->setAimObject(NULL);
}
}
}//if
}
control->enableCollision();
if(bWalk)
{
char* szBuf = Con::getArgBuffer(64);
//dSprintf(szBuf,64,"%3f %3f %3f",info.point.x,info.point.y,info.point.z);
dSprintf(szBuf,64,"%3f %3f %3f",endPos.x,endPos.y,endPos.z);
Con::executef(this,3, "onClickToGround",
szBuf,
Con::getIntArg((S32) (state == GMS_DRAG || state == GMS_PRESS)) );
}
}
//void GameTSCtrl::ProcessNpcTalk(GNpc* pNpc)
//{
// if(pNpc)
// pNpc->ProcessTalk();
//
//}
//---------------------------------------------------------------------------
static const char* cGetMouse3DVec(SimObject *ptr, S32 argc, const char **argv)
{
GameTSCtrl* obj = static_cast<GameTSCtrl*>(ptr);
char* retBuffer = Con::getReturnBuffer(256);
const Point3F &vec = obj->getMouse3DVec();
dSprintf(retBuffer, 256, "%g %g %g", vec.x, vec.y, vec.z);
return retBuffer;
}
static const char* cGetMouse3DPos(SimObject *ptr, S32 argc, const char **argv)
{
GameTSCtrl* obj = static_cast<GameTSCtrl*>(ptr);
char* retBuffer = Con::getReturnBuffer(256);
const Point3F &pos = obj->getMouse3DPos();
dSprintf(retBuffer, 256, "%g %g %g", pos.x, pos.y, pos.z);
return retBuffer;
}
void GameTSCtrl::consoleInit()
{
Con::addCommand("GameTSCtrl", "getMouse3DVec", cGetMouse3DVec, "GameTSCtrl.getMouse3DVec();", 2, 2);
Con::addCommand("GameTSCtrl", "getMouse3DPos", cGetMouse3DPos, "GameTSCtrl.getMouse3DPos();", 2, 2);
Con::addVariable("$RPG::DragWalkDelay", TypeS32, & ms_uDownLength );
Con::addVariable("$RPG::GameUpdateDelay", TypeS32, & ms_uUpdateCycle );
Con::addVariable("$RPG::TalkDistance", TypeF32, & ms_fTalkDistance);
//Con::addVariable("$Player::Position", TypeString, &ms_sMainRolePos);
//Con::addVariable("$Player::Position",TypePoint2I,&ms_posMainRoleGrid);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -