obj-select -- object selection functionality

is-camera -- Adds a test for determining if object is a camera.
cam-speed -- added method for getting the camera movement speed.
zoned-in -- connection is flagged as "zoned-in" when client is fully connected and user can interact with it.
This commit is contained in:
Marc Chapman 2017-07-26 23:59:44 +01:00
parent d4c2eeea98
commit fcce9be33c
7 changed files with 250 additions and 1 deletions

View file

@ -61,6 +61,7 @@
#include "core/stream/fileStream.h"
#endif
#include "afx/arcaneFX.h"
//----------------------------------------------------------------------------
#define MAX_MOVE_PACKET_SENDS 4
@ -191,6 +192,12 @@ bool GameConnection::client_cache_on = false;
//----------------------------------------------------------------------------
GameConnection::GameConnection()
{
mRolloverObj = NULL;
mPreSelectedObj = NULL;
mSelectedObj = NULL;
mChangedSelectedObj = false;
mPreSelectTimestamp = 0;
zoned_in = false;
#ifdef AFX_CAP_DATABLOCK_CACHE
client_db_stream = new InfiniteBitStream;
@ -1168,6 +1175,17 @@ void GameConnection::readPacket(BitStream *bstream)
{
mMoveList->clientReadMovePacket(bstream);
// selected object - do we have a change in status?
if (bstream->readFlag())
{
if (bstream->readFlag())
{
S32 gIndex = bstream->readInt(NetConnection::GhostIdBitSize);
setSelectedObj(static_cast<SceneObject*>(resolveGhost(gIndex)));
}
else
setSelectedObj(NULL);
}
bool hadFlash = mDamageFlash > 0 || mWhiteOut > 0;
mDamageFlash = 0;
mWhiteOut = 0;
@ -1411,6 +1429,35 @@ void GameConnection::writePacket(BitStream *bstream, PacketNotify *note)
// all the damage flash & white out
S32 gIndex = -1;
if (mChangedSelectedObj)
{
S32 gidx;
// send NULL player
if ((mSelectedObj == NULL) || mSelectedObj.isNull())
{
bstream->writeFlag(true);
bstream->writeFlag(false);
mChangedSelectedObj = false;
}
// send ghost-idx
else if ((gidx = getGhostIndex(mSelectedObj)) != -1)
{
Con::printf("SEND OBJECT SELECTION");
bstream->writeFlag(true);
bstream->writeFlag(true);
bstream->writeInt(gidx, NetConnection::GhostIdBitSize);
mChangedSelectedObj = false;
}
// not fully changed yet
else
{
bstream->writeFlag(false);
mChangedSelectedObj = true;
}
}
else
bstream->writeFlag(false);
if (!mControlObject.isNull())
{
gIndex = getGhostIndex(mControlObject);
@ -2405,6 +2452,135 @@ DefineEngineMethod( GameConnection, getVisibleGhostDistance, F32, (),,
return object->getVisibleGhostDistance();
}
// The object selection code here is, in part, based, on functionality described
// in the following resource:
// Object Selection in Torque by Dave Myers
// http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=7335
ConsoleMethod(GameConnection, setSelectedObj, bool, 3, 4, "(object, [propagate_to_client])")
{
SceneObject* pending_selection;
if (!Sim::findObject(argv[2], pending_selection))
return false;
bool propagate_to_client = (argc > 3) ? dAtob(argv[3]) : false;
object->setSelectedObj(pending_selection, propagate_to_client);
return true;
}
ConsoleMethod(GameConnection, getSelectedObj, S32, 2, 2, "()")
{
SimObject* selected = object->getSelectedObj();
return (selected) ? selected->getId(): -1;
}
ConsoleMethod(GameConnection, clearSelectedObj, void, 2, 3, "([propagate_to_client])")
{
bool propagate_to_client = (argc > 2) ? dAtob(argv[2]) : false;
object->setSelectedObj(NULL, propagate_to_client);
}
ConsoleMethod(GameConnection, setPreSelectedObjFromRollover, void, 2, 2, "()")
{
object->setPreSelectedObjFromRollover();
}
ConsoleMethod(GameConnection, clearPreSelectedObj, void, 2, 2, "()")
{
object->clearPreSelectedObj();
}
ConsoleMethod(GameConnection, setSelectedObjFromPreSelected, void, 2, 2, "()")
{
object->setSelectedObjFromPreSelected();
}
void GameConnection::setSelectedObj(SceneObject* so, bool propagate_to_client)
{
if (!isConnectionToServer())
{
// clear previously selected object
if (mSelectedObj)
clearNotify(mSelectedObj);
// save new selection
mSelectedObj = so;
// mark selected object
if (mSelectedObj)
deleteNotify(mSelectedObj);
// mark selection dirty
if (propagate_to_client)
mChangedSelectedObj = true;
return;
}
// clear previously selected object
if (mSelectedObj)
{
mSelectedObj->setSelectionFlags(mSelectedObj->getSelectionFlags() & ~SceneObject::SELECTED);
clearNotify(mSelectedObj);
Con::executef(this, "onObjectDeselected", mSelectedObj->getIdString());
}
// save new selection
mSelectedObj = so;
// mark selected object
if (mSelectedObj)
{
mSelectedObj->setSelectionFlags(mSelectedObj->getSelectionFlags() | SceneObject::SELECTED);
deleteNotify(mSelectedObj);
}
// mark selection dirty
//mChangedSelectedObj = true;
// notify appropriate script of the change
if (mSelectedObj)
Con::executef(this, "onObjectSelected", mSelectedObj->getIdString());
}
void GameConnection::setRolloverObj(SceneObject* so)
{
// save new selection
mRolloverObj = so;
// notify appropriate script of the change
Con::executef(this, "onObjectRollover", (mRolloverObj) ? mRolloverObj->getIdString() : "");
}
void GameConnection::setPreSelectedObjFromRollover()
{
mPreSelectedObj = mRolloverObj;
mPreSelectTimestamp = Platform::getRealMilliseconds();
}
void GameConnection::clearPreSelectedObj()
{
mPreSelectedObj = 0;
mPreSelectTimestamp = 0;
}
void GameConnection::setSelectedObjFromPreSelected()
{
U32 now = Platform::getRealMilliseconds();
if (now - mPreSelectTimestamp < arcaneFX::sTargetSelectionTimeoutMS)
setSelectedObj(mPreSelectedObj);
mPreSelectedObj = 0;
}
void GameConnection::onDeleteNotify(SimObject* obj)
{
if (obj == mSelectedObj)
setSelectedObj(NULL);
Parent::onDeleteNotify(obj);
}
#ifdef AFX_CAP_DATABLOCK_CACHE
void GameConnection::tempDisableStringBuffering(BitStream* bs) const