mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-03 20:40:35 +00:00
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:
parent
d4c2eeea98
commit
fcce9be33c
7 changed files with 250 additions and 1 deletions
|
|
@ -20,6 +20,11 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#ifndef _CAMERA_H_
|
||||
#define _CAMERA_H_
|
||||
|
||||
|
|
@ -246,6 +251,8 @@ class Camera: public ShapeBase
|
|||
DECLARE_CONOBJECT( Camera );
|
||||
DECLARE_CATEGORY( "Game" );
|
||||
DECLARE_DESCRIPTION( "Represents a position, direction and field of view to render a scene from." );
|
||||
static F32 getMovementSpeed() { return smMovementSpeed; }
|
||||
bool isCamera() const { return true; }
|
||||
};
|
||||
|
||||
typedef Camera::CameraMotionMode CameraMotionMode;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -386,6 +386,36 @@ protected:
|
|||
DECLARE_CALLBACK( void, onDataBlocksDone, (U32 sequence) );
|
||||
DECLARE_CALLBACK( void, onFlash, (bool state) );
|
||||
|
||||
// GameConnection is modified to keep track of object selections which are used in
|
||||
// spell targeting. This code stores the current object selection as well as the
|
||||
// current rollover object beneath the cursor. The rollover object is treated as a
|
||||
// pending object selection and actual object selection is usually made by promoting
|
||||
// the rollover object to the current object selection.
|
||||
private:
|
||||
SimObjectPtr<SceneObject> mRolloverObj;
|
||||
SimObjectPtr<SceneObject> mPreSelectedObj;
|
||||
SimObjectPtr<SceneObject> mSelectedObj;
|
||||
bool mChangedSelectedObj;
|
||||
U32 mPreSelectTimestamp;
|
||||
protected:
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
public:
|
||||
void setRolloverObj(SceneObject*);
|
||||
SceneObject* getRolloverObj() { return mRolloverObj; }
|
||||
void setSelectedObj(SceneObject*, bool propagate_to_client=false);
|
||||
SceneObject* getSelectedObj() { return mSelectedObj; }
|
||||
void setPreSelectedObjFromRollover();
|
||||
void clearPreSelectedObj();
|
||||
void setSelectedObjFromPreSelected();
|
||||
// Flag is added to indicate when a client is fully connected or "zoned-in".
|
||||
// This information determines when AFX will startup active effects on a newly
|
||||
// added client.
|
||||
private:
|
||||
bool zoned_in;
|
||||
public:
|
||||
bool isZonedIn() const { return zoned_in; }
|
||||
void setZonedIn() { zoned_in = true; }
|
||||
|
||||
#ifdef AFX_CAP_DATABLOCK_CACHE
|
||||
private:
|
||||
static StringTableEntry server_cache_filename;
|
||||
|
|
|
|||
|
|
@ -5885,7 +5885,12 @@ void Player::applyImpulse(const Point3F&,const VectorF& vec)
|
|||
|
||||
bool Player::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
|
||||
{
|
||||
if (getDamageState() != Enabled)
|
||||
// In standard Torque there's a rather brute force culling of all
|
||||
// non-enabled players (corpses) from the ray cast. But, to
|
||||
// demonstrate a resurrection spell, we need corpses to be
|
||||
// selectable, so this code change allows consideration of corpses
|
||||
// in the ray cast if corpsesHiddenFromRayCast is set to false.
|
||||
if (sCorpsesHiddenFromRayCast && getDamageState() != Enabled)
|
||||
return false;
|
||||
|
||||
// Collide against bounding box. Need at least this for the editor.
|
||||
|
|
|
|||
|
|
@ -790,6 +790,9 @@ private:
|
|||
void afx_init();
|
||||
U32 afx_packUpdate(NetConnection*, U32 mask, BitStream*, U32 retMask);
|
||||
void afx_unpackUpdate(NetConnection*, BitStream*);
|
||||
private:
|
||||
static bool sCorpsesHiddenFromRayCast;
|
||||
|
||||
};
|
||||
|
||||
typedef Player::Pose PlayerPose;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "scene/sceneObject.h"
|
||||
|
||||
|
|
@ -144,6 +149,7 @@ SceneObject::SceneObject()
|
|||
mIsScopeAlways = false;
|
||||
|
||||
mAccuTex = NULL;
|
||||
mSelectionFlags = 0;
|
||||
mPathfindingIgnore = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#ifndef _SCENEOBJECT_H_
|
||||
#define _SCENEOBJECT_H_
|
||||
|
||||
|
|
@ -778,6 +783,23 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
|
|||
// Note: This was placed in SceneObject to both ShapeBase and TSStatic could support it.
|
||||
public:
|
||||
GFXTextureObject* mAccuTex;
|
||||
// mSelectionFlags field keeps track of flags related to object selection.
|
||||
// PRE_SELECTED marks an object as pre-selected (object under cursor)
|
||||
// SELECTED marks an object as selected (a target)
|
||||
protected:
|
||||
U8 mSelectionFlags;
|
||||
public:
|
||||
enum {
|
||||
SELECTED = BIT(0),
|
||||
PRE_SELECTED = BIT(1),
|
||||
};
|
||||
virtual void setSelectionFlags(U8 flags) { mSelectionFlags = flags; }
|
||||
U8 getSelectionFlags() const { return mSelectionFlags; }
|
||||
bool needsSelectionHighlighting() const { return (mSelectionFlags != 0); }
|
||||
// This should only return true if the object represents an independent camera
|
||||
// as opposed to something like a Player that has a built-in camera that requires
|
||||
// special calculations to determine the view transform.
|
||||
virtual bool isCamera() const { return false; }
|
||||
};
|
||||
|
||||
#endif // _SCENEOBJECT_H_
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue