mirror of
https://github.com/worldforge/worldforge
synced 2026-08-17 16:26:05 -04:00
Use milliseconds for all time.
And remove "seconds" in favour of always using "stamp".
This commit is contained in:
parent
2e537a2fef
commit
e598eee88d
133 changed files with 2032 additions and 2340 deletions
1
.gdbinit
1
.gdbinit
|
|
@ -9,6 +9,7 @@ def release_mouse (event):
|
|||
gdb.write("GDB/SDL2: Releasing mouse\n")
|
||||
try:
|
||||
gdb.execute("call SDL_SetRelativeMouseMode(0)")
|
||||
gdb.write("GDB/SDL2: Released mouse\n")
|
||||
except gdb.error:
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -174,8 +174,6 @@ to the builder, and the PropertyFactories to the CorePropertyManager. Then
|
|||
both those can be made independant of server. It could also handle all the
|
||||
really core types being added to Inheritance.
|
||||
|
||||
Is PyCreator/PyCharacter still needed in the client side? It seems to have
|
||||
been abandoned before being fully introduced.
|
||||
|
||||
Add Arithmetic functionality to all scripts. Cos you know.
|
||||
Add the concept of the Property script in general and use it to replace the
|
||||
|
|
@ -190,8 +188,6 @@ Make it possible to forget
|
|||
|
||||
Use "name" as the property that is supposed to get an operation
|
||||
|
||||
EntityBuilder shouldn't need a permenent reference to the world.
|
||||
|
||||
Allow long cut and cross cut with saws. Long cut is along grain, bisecting by longest dimension. cross cut is across both grains
|
||||
|
||||
Sort out a better way to handle materials. We shouldn't have a base class
|
||||
|
|
@ -219,10 +215,6 @@ entities which can create further persistent entities.
|
|||
|
||||
Frontends, backends, routers based architecture
|
||||
|
||||
Use 64bit milliseconds everywhere. Merge SECONDS and STAMP into a single
|
||||
attribute. Get rid of FUTURE_SECONDS in favor of things being able to set
|
||||
STAMP/SECONDS in advance. Use time for STAMP instead of incrementing integer.
|
||||
|
||||
Character should inherit from and implement the Agent interface, which
|
||||
the server code uses when talking to it. This de-couples server from most
|
||||
of the rulesets directory.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Chase(DynamicGoal):
|
|||
|
||||
def event(self, me, original_op, op):
|
||||
# FIXME Now that this code is trigger goal, has this update been done?
|
||||
other = me.map.update(op[0], op.get_seconds())
|
||||
other = me.map.update(op[0], op.get_stamp())
|
||||
if other.id == me.entity.id:
|
||||
return
|
||||
# target=op[0].location.copy()
|
||||
|
|
|
|||
|
|
@ -1,40 +1,43 @@
|
|||
<atlas>
|
||||
<map>
|
||||
<map name="attributes">
|
||||
<map name="geometry">
|
||||
<map name="default">
|
||||
<string name="path">dural/items/tools/spade/model/spade.mesh</string>
|
||||
<string name="type">box</string>
|
||||
</map>
|
||||
</map>
|
||||
<map name="present">
|
||||
<string name="default">dural/items/tools/spade/spade.modeldef</string>
|
||||
</map>
|
||||
<map name="density">
|
||||
<float name="default">2000</float>
|
||||
</map>
|
||||
<map name="cooldown">
|
||||
<float name="default">5</float>
|
||||
</map>
|
||||
<map name="usages">
|
||||
<map name="default">
|
||||
<map name="dig">
|
||||
<string name="name">Dig</string>
|
||||
<map name="params">
|
||||
<map name="targets">
|
||||
<string name="type">entity_location</string>
|
||||
<string name="constraint">entity instance_of types.game_entity && actor can_reach entity_location with tool</string>
|
||||
</map>
|
||||
</map>
|
||||
<string name="handler">world.objects.tools.GenericTool.use</string>
|
||||
<string name="constraint">get_entity(actor.attached_hand_primary) = tool</string>
|
||||
<string name="description">Dig with shovel.</string>
|
||||
</map>
|
||||
</map>
|
||||
</map>
|
||||
</map>
|
||||
<string name="id">shovel</string>
|
||||
<string name="objtype">class</string>
|
||||
<string name="parent">thing</string>
|
||||
</map>
|
||||
<map>
|
||||
<map name="attributes">
|
||||
<map name="geometry">
|
||||
<map name="default">
|
||||
<string name="path">dural/items/tools/spade/model/spade.mesh</string>
|
||||
<string name="type">box</string>
|
||||
</map>
|
||||
</map>
|
||||
<map name="present">
|
||||
<string name="default">dural/items/tools/spade/spade.modeldef</string>
|
||||
</map>
|
||||
<map name="density">
|
||||
<float name="default">2000</float>
|
||||
</map>
|
||||
<map name="cooldown">
|
||||
<float name="default">5</float>
|
||||
</map>
|
||||
<map name="usages">
|
||||
<map name="default">
|
||||
<map name="dig">
|
||||
<string name="name">Dig</string>
|
||||
<map name="params">
|
||||
<map name="targets">
|
||||
<string name="type">entity_location</string>
|
||||
<string name="constraint">describe("Target needs to be in game.", entity instance_of
|
||||
types.game_entity) && describe("Can't reach.", actor can_reach
|
||||
entity_location with tool)
|
||||
</string>
|
||||
</map>
|
||||
</map>
|
||||
<string name="handler">world.objects.tools.GenericTool.use</string>
|
||||
<string name="constraint">get_entity(actor.attached_hand_primary) = tool</string>
|
||||
<string name="description">Dig with shovel.</string>
|
||||
</map>
|
||||
</map>
|
||||
</map>
|
||||
</map>
|
||||
<string name="id">shovel</string>
|
||||
<string name="objtype">class</string>
|
||||
<string name="parent">thing</string>
|
||||
</map>
|
||||
</atlas>
|
||||
|
|
|
|||
|
|
@ -30,16 +30,18 @@ class Operation:
|
|||
pass
|
||||
def get_from(self):
|
||||
pass
|
||||
def get_future_milliseconds(self):
|
||||
pass
|
||||
def get_future_seconds(self):
|
||||
pass
|
||||
def get_name(self):
|
||||
pass
|
||||
def get_refno(self):
|
||||
pass
|
||||
def get_seconds(self):
|
||||
pass
|
||||
def get_serialno(self):
|
||||
pass
|
||||
def get_stamp(self):
|
||||
pass
|
||||
def get_to(self):
|
||||
pass
|
||||
def is_default_serialno(self):
|
||||
|
|
@ -50,6 +52,8 @@ class Operation:
|
|||
def set_from(self, string):
|
||||
"""Sets from which entity the operation is from."""
|
||||
pass
|
||||
def set_future_milliseconds(self):
|
||||
pass
|
||||
def set_future_seconds(self):
|
||||
pass
|
||||
def set_name(self):
|
||||
|
|
@ -57,11 +61,11 @@ class Operation:
|
|||
def set_refno(self, long):
|
||||
"""Sets the reference number."""
|
||||
pass
|
||||
def set_seconds(self):
|
||||
pass
|
||||
def set_serialno(self, long):
|
||||
"""Sets the serial number."""
|
||||
pass
|
||||
def set_stamp(self):
|
||||
pass
|
||||
def set_to(self, string):
|
||||
"""Sets to which entity the operation is directed."""
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <Atlas/Objects/Anonymous.h>
|
||||
#include <Atlas/Objects/Operation.h>
|
||||
#include <Atlas/Objects/Entity.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -97,12 +98,11 @@ void BaseClient::externalOperation(const Operation& op, Link& link) {
|
|||
/// @param password Password of the new account
|
||||
void BaseClient::createSystemAccount(const std::string& usernameSuffix) {
|
||||
|
||||
Anonymous player_ent;
|
||||
Atlas::Objects::Entity::SystemAccount player_ent;
|
||||
m_username = create_session_username() + usernameSuffix;
|
||||
player_ent->setAttr("username", m_username);
|
||||
m_password = fmt::format("{}{}", ::rand(), ::rand());
|
||||
player_ent->setAttr("password", m_password);
|
||||
player_ent->setParent("sys");
|
||||
|
||||
Create createAccountOp;
|
||||
createAccountOp->setArgs1(player_ent);
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ using Atlas::Objects::Root;
|
|||
using Atlas::Objects::Entity::Anonymous;
|
||||
using Atlas::Objects::Operation::RootOperation;
|
||||
|
||||
long PossessionClient::operations_in = 0;
|
||||
long PossessionClient::operations_out = 0;
|
||||
size_t PossessionClient::operations_in = 0;
|
||||
size_t PossessionClient::operations_out = 0;
|
||||
|
||||
PossessionClient::PossessionClient(CommSocket& commSocket,
|
||||
MindKit& mindFactory,
|
||||
|
|
@ -87,7 +87,7 @@ void PossessionClient::operationFromEntity(const Operation& op, Ref<BaseMind> lo
|
|||
|
||||
OpVector res;
|
||||
//Adjust the time of the operation to fit with the server's time
|
||||
op->setSeconds(op->getSeconds() - m_serverLocalTimeDiff);
|
||||
op->setStamp(op->getStamp() - m_serverLocalTimeDiff.count());
|
||||
processOperation(op, res);
|
||||
operations_out += res.size();
|
||||
send(res);
|
||||
|
|
@ -97,23 +97,23 @@ void PossessionClient::operationFromEntity(const Operation& op, Ref<BaseMind> lo
|
|||
void PossessionClient::operation(const Operation& op, OpVector& res) {
|
||||
rmt_ScopedCPUSample(operation, 0)
|
||||
operations_in++;
|
||||
if (!op->isDefaultSeconds()) {
|
||||
if (!op->isDefaultStamp()) {
|
||||
//Store the difference between server time and local time, so we can properly adjust the time of any locally scheduled ops when they are dispatched.
|
||||
m_serverLocalTimeDiff = std::chrono::duration_cast<std::chrono::duration<float>>(getTime()).count() - op->getSeconds();
|
||||
m_serverLocalTimeDiff = std::chrono::duration_cast<std::chrono::milliseconds>(getTime()) - std::chrono::milliseconds(op->getStamp());
|
||||
}
|
||||
processOperation(op, res);
|
||||
operations_out += res.size();
|
||||
}
|
||||
|
||||
void PossessionClient::resolveDispatchTimeForOp(Atlas::Objects::Operation::RootOperationData& op) {
|
||||
if (!op.isDefaultFutureSeconds()) {
|
||||
if (!op.isDefaultFutureMilliseconds()) {
|
||||
auto timeNow = std::chrono::steady_clock::now() - m_startTime;
|
||||
auto timeAsSeconds = std::chrono::duration_cast<std::chrono::duration<float>>(timeNow).count();
|
||||
double t = timeAsSeconds + op.getFutureSeconds();
|
||||
op.setSeconds(t);
|
||||
op.removeAttrFlag(Atlas::Objects::Operation::FUTURE_SECONDS_FLAG);
|
||||
} else if (op.isDefaultSeconds()) {
|
||||
op.setSeconds(std::chrono::duration_cast<std::chrono::duration<float>>(getTime()).count());
|
||||
auto timeAsMilliseSeconds = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow);
|
||||
auto t = timeAsMilliseSeconds + std::chrono::milliseconds(op.getFutureMilliseconds());
|
||||
op.setStamp(t.count());
|
||||
op.removeAttrFlag(Atlas::Objects::Operation::FUTURE_MILLISECONDS_FLAG);
|
||||
} else if (op.isDefaultStamp()) {
|
||||
op.setStamp(std::chrono::duration_cast<std::chrono::milliseconds>(getTime()).count());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ public:
|
|||
|
||||
void processResponses(const OpVector& incomingRes, OpVector& outgoingRes);
|
||||
|
||||
static long operations_in;
|
||||
static long operations_out;
|
||||
static size_t operations_in;
|
||||
static size_t operations_out;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ protected:
|
|||
* This is needed when scheduling operations locally. When they are later dispatched
|
||||
* their "seconds" needs to match the time it would be on the server.
|
||||
*/
|
||||
double m_serverLocalTimeDiff;
|
||||
std::chrono::milliseconds m_serverLocalTimeDiff;
|
||||
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -291,8 +291,8 @@ int main(int argc, char** argv) {
|
|||
|
||||
monitors.watch("accounts", PossessionAccount::account_count);
|
||||
monitors.watch("minds", PossessionAccount::mind_count);
|
||||
monitors.watch("operations_in", PossessionClient::operations_in);
|
||||
monitors.watch("operations_out", PossessionClient::operations_out);
|
||||
monitors.watch("operations_in", (long&) PossessionClient::operations_in);
|
||||
monitors.watch("operations_out", (long&) PossessionClient::operations_out);
|
||||
|
||||
|
||||
//Reload the script factory when scripts changes.
|
||||
|
|
|
|||
|
|
@ -61,10 +61,9 @@ void BaseClient::send(const Operation& op) {
|
|||
/// @param name User name of the new account
|
||||
/// @param password Password of the new account
|
||||
Root BaseClient::createSystemAccount() {
|
||||
Anonymous player_ent;
|
||||
Atlas::Objects::Entity::SystemAccount player_ent;
|
||||
player_ent->setAttr("username", create_session_username());
|
||||
player_ent->setAttr("password", fmt::format("{}{}", ::rand(), ::rand()));
|
||||
player_ent->setParent("sys");
|
||||
|
||||
Create createAccountOp;
|
||||
createAccountOp->setArgs1(player_ent);
|
||||
|
|
|
|||
|
|
@ -120,5 +120,5 @@ Ref<LocatedEntity> CharacterClient::sendLook(const Operation& op) {
|
|||
} else {
|
||||
std::cout << "Seen: " << sight_id << std::endl;
|
||||
}
|
||||
return m_map.updateAdd(seen, res->getSeconds());
|
||||
return m_map.updateAdd(seen, std::chrono::milliseconds(res->getStamp()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ CreatorClient::CreatorClient(RouterId mindId,
|
|||
}
|
||||
|
||||
LocatedEntity* CreatorClient::handleMakeResponse(const RootOperation& op,
|
||||
double create_time) {
|
||||
std::chrono::milliseconds create_time) {
|
||||
if (op->getArgs().empty()) {
|
||||
std::cerr << "Arg of reply to make has no args"
|
||||
<< std::endl;
|
||||
|
|
@ -103,9 +103,9 @@ Ref<LocatedEntity> CreatorClient::make(const RootEntity& entity) {
|
|||
<< std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
return handleMakeResponse(arg, res->getSeconds());
|
||||
return handleMakeResponse(arg, std::chrono::milliseconds(res->getStamp()));
|
||||
} else if (res->getClassNo() == Atlas::Objects::Operation::INFO_NO) {
|
||||
return handleMakeResponse(res, res->getSeconds());
|
||||
return handleMakeResponse(res, std::chrono::milliseconds(res->getStamp()));
|
||||
} else {
|
||||
std::cerr << "Reply to make isn't sight or info"
|
||||
<< std::endl;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public:
|
|||
TypeStore& typeStore);
|
||||
|
||||
LocatedEntity* handleMakeResponse(const Atlas::Objects::Operation::RootOperation&,
|
||||
double);
|
||||
std::chrono::milliseconds);
|
||||
|
||||
Ref<LocatedEntity> make(const Atlas::Objects::Entity::RootEntity&);
|
||||
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@ void installStandardObjects(TypeStore& i) {
|
|||
i.addChild(atlasObjDefinition<Atlas::Objects::Entity::AdminData>());
|
||||
i.addChild(atlasObjDefinition<Atlas::Objects::Entity::GameData>());
|
||||
i.addChild(atlasObjDefinition<Atlas::Objects::Entity::GameEntityData>());
|
||||
i.addChild(atlasObjDefinition<Atlas::Objects::Entity::SystemAccountData>());
|
||||
|
||||
//We should now have just as many types registered as there are standard types in Atlas.
|
||||
auto typeCount = i.getTypeCount();
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ struct OpQueEntry {
|
|||
OpQueEntry(Operation op_, Ref<T> from_, long sequence_)
|
||||
: op(std::move(op_)),
|
||||
from(std::move(from_)),
|
||||
time_for_dispatch(std::chrono::milliseconds(static_cast<std::int64_t>(op->getSeconds() * 1000))),
|
||||
time_for_dispatch(std::chrono::milliseconds(op->getStamp())),
|
||||
sequence(sequence_) {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ template<typename T>
|
|||
OpQueEntry<T>::OpQueEntry(Operation o, T& f, long sequence_) :
|
||||
op(std::move(o)),
|
||||
from(&f),
|
||||
time_for_dispatch(std::chrono::milliseconds(static_cast<std::int64_t>(op->getSeconds() * 1000))),
|
||||
time_for_dispatch(std::chrono::milliseconds(op->getStamp())),
|
||||
sequence(sequence_) {
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ template<typename T>
|
|||
OpQueEntry<T>::OpQueEntry(const OpQueEntry& o) :
|
||||
op(o.op),
|
||||
from(o.from),
|
||||
time_for_dispatch(std::chrono::milliseconds(static_cast<std::int64_t>(op->getSeconds() * 1000))),
|
||||
time_for_dispatch(std::chrono::milliseconds(op->getStamp())),
|
||||
sequence(o.sequence) {
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ template<typename T>
|
|||
OpQueEntry<T>::OpQueEntry(OpQueEntry&& o) noexcept
|
||||
: op(std::move(o.op)),
|
||||
from(std::move(o.from)),
|
||||
time_for_dispatch(std::chrono::milliseconds(static_cast<std::int64_t>(op->getSeconds() * 1000))),
|
||||
time_for_dispatch(std::chrono::milliseconds(op->getStamp())),
|
||||
sequence(std::move(o.sequence)) {
|
||||
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ void OperationsDispatcher<T>::clearQueues() {
|
|||
template<typename T>
|
||||
void OperationsDispatcher<T>::addOperationToQueue(Operation op, Ref<T> ent) {
|
||||
assert(op.isValid());
|
||||
assert(!op->isDefaultSeconds());
|
||||
assert(!op->isDefaultStamp());
|
||||
|
||||
//Check the sequence number of the first op at start.
|
||||
long topSequenceNr = 0;
|
||||
|
|
|
|||
|
|
@ -104,6 +104,12 @@ static const int EXPECTED_LAYERS_PER_TILE = 1;
|
|||
|
||||
using namespace boost::multi_index;
|
||||
|
||||
namespace {
|
||||
double to_seconds(std::chrono::milliseconds duration) {
|
||||
return std::chrono::duration_cast<std::chrono::duration<float>>(duration).count();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A Most Recently Used list implemented using boost::multi_index.
|
||||
*
|
||||
|
|
@ -453,7 +459,7 @@ void Awareness::removeEntity(const MemEntity& observer, const MemEntity& entity)
|
|||
}
|
||||
}
|
||||
|
||||
bool Awareness::processEntityUpdate(EntityEntry& entityEntry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, double timestamp)
|
||||
bool Awareness::processEntityUpdate(EntityEntry& entityEntry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, std::chrono::milliseconds timestamp)
|
||||
{
|
||||
bool hasNewPosition = false;
|
||||
bool hasNewBbox = false;
|
||||
|
|
@ -606,7 +612,7 @@ bool Awareness::avoidObstacles(long avatarEntityId,
|
|||
const WFMath::Point<2>& position,
|
||||
const WFMath::Vector<2>& desiredVelocity,
|
||||
WFMath::Vector<2>& newVelocity,
|
||||
double currentTimestamp,
|
||||
std::chrono::milliseconds currentTimestamp,
|
||||
const WFMath::Point<2>* nextWayPoint) const
|
||||
{
|
||||
struct EntityCollisionEntry
|
||||
|
|
@ -644,7 +650,7 @@ bool Awareness::avoidObstacles(long avatarEntityId,
|
|||
// Update location
|
||||
auto pos = entry->pos.data;
|
||||
if (entry->velocity.data.isValid()) {
|
||||
double time_diff = currentTimestamp - entry->velocity.timestamp;
|
||||
auto time_diff = to_seconds(currentTimestamp - entry->velocity.timestamp);
|
||||
pos += (entry->velocity.data * time_diff);
|
||||
}
|
||||
|
||||
|
|
@ -898,7 +904,7 @@ int Awareness::findPath(const WFMath::Point<3>& start, const WFMath::Point<3>& e
|
|||
return nVertCount - 1;
|
||||
}
|
||||
|
||||
bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, double currentServerTimestamp) const
|
||||
bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, std::chrono::milliseconds currentServerTimestamp) const
|
||||
{
|
||||
auto entityI = mObservedEntities.find(entityId);
|
||||
if (entityI != mObservedEntities.end()) {
|
||||
|
|
@ -906,14 +912,14 @@ bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, double cur
|
|||
pos = entityEntry->pos.data;
|
||||
auto& velocity = entityEntry->velocity.data;
|
||||
if (velocity.isValid() && velocity != WFMath::Vector<3>::ZERO()) {
|
||||
pos += (velocity * (currentServerTimestamp - entityEntry->pos.timestamp));
|
||||
pos += (velocity * to_seconds(currentServerTimestamp - entityEntry->pos.timestamp));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
WFMath::Point<3> Awareness::projectPosition(long entityId, double currentServerTimestamp) const
|
||||
WFMath::Point<3> Awareness::projectPosition(long entityId, std::chrono::milliseconds currentServerTimestamp) const
|
||||
{
|
||||
auto entityI = mObservedEntities.find(entityId);
|
||||
if (entityI != mObservedEntities.end()) {
|
||||
|
|
@ -921,7 +927,7 @@ WFMath::Point<3> Awareness::projectPosition(long entityId, double currentServerT
|
|||
auto pos = entityEntry->pos.data;
|
||||
auto& velocity = entityEntry->velocity.data;
|
||||
if (velocity.isValid() && velocity != WFMath::Vector<3>::ZERO()) {
|
||||
pos += (velocity * (currentServerTimestamp - entityEntry->pos.timestamp));
|
||||
pos += (velocity * to_seconds(currentServerTimestamp - entityEntry->pos.timestamp));
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ template<typename T>
|
|||
struct TimestampedProperty
|
||||
{
|
||||
T data;
|
||||
double timestamp = -1.0;
|
||||
std::chrono::milliseconds timestamp = std::chrono::milliseconds {-1};
|
||||
};
|
||||
|
||||
struct EntityEntry
|
||||
|
|
@ -247,7 +247,7 @@ class Awareness
|
|||
const WFMath::Point<2>& position,
|
||||
const WFMath::Vector<2>& desiredVelocity,
|
||||
WFMath::Vector<2>& newVelocity,
|
||||
double currentTimestamp,
|
||||
std::chrono::milliseconds currentTimestamp,
|
||||
const WFMath::Point<2>* nextWayPoint) const;
|
||||
|
||||
/**
|
||||
|
|
@ -342,9 +342,9 @@ class Awareness
|
|||
* @param currentServerTimestamp The current server time stamp, to calculate new positions for moving entities.
|
||||
* @return True if entity could be found.
|
||||
*/
|
||||
bool projectPosition(long entityId, WFMath::Point<3>& pos, double currentServerTimestamp) const;
|
||||
bool projectPosition(long entityId, WFMath::Point<3>& pos, std::chrono::milliseconds currentServerTimestamp) const;
|
||||
|
||||
WFMath::Point<3> projectPosition(long entityId, double currentServerTimestamp) const;
|
||||
WFMath::Point<3> projectPosition(long entityId, std::chrono::milliseconds currentServerTimestamp) const;
|
||||
|
||||
const std::unordered_map<long, std::unique_ptr<EntityEntry>>& getObservedEntities() const;
|
||||
|
||||
|
|
@ -507,7 +507,7 @@ class Awareness
|
|||
* @param timestamp
|
||||
* @return True if any position or size changed.
|
||||
*/
|
||||
bool processEntityUpdate(EntityEntry& entry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, double timestamp);
|
||||
bool processEntityUpdate(EntityEntry& entry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, std::chrono::milliseconds timestamp);
|
||||
|
||||
/**
|
||||
* @brief Rebuild the tile at the specific index.
|
||||
|
|
|
|||
|
|
@ -35,47 +35,44 @@
|
|||
static const bool debug_flag = true;
|
||||
|
||||
Steering::Steering(MemEntity& avatar) :
|
||||
mAwareness(nullptr),
|
||||
mAvatar(avatar),
|
||||
mSteeringDestination{},
|
||||
mCurrentPathIndex(0),
|
||||
mSteeringEnabled(false),
|
||||
mUpdateNeeded(false),
|
||||
mPadding(16),
|
||||
mMaxSpeed(5),
|
||||
mDesiredSpeed(0.5),
|
||||
mExpectingServerMovement(false),
|
||||
mPathResult(0),
|
||||
mAvatarHorizRadius(0)
|
||||
{
|
||||
auto speedGroundProp = avatar.getPropertyType<double>("speed_ground");
|
||||
if (speedGroundProp) {
|
||||
mMaxSpeed = speedGroundProp->data();
|
||||
}
|
||||
mAwareness(nullptr),
|
||||
mAvatar(avatar),
|
||||
mSteeringDestination{},
|
||||
mCurrentPathIndex(0),
|
||||
mSteeringEnabled(false),
|
||||
mUpdateNeeded(false),
|
||||
mPadding(16),
|
||||
mMaxSpeed(5),
|
||||
mDesiredSpeed(0.5),
|
||||
mExpectingServerMovement(false),
|
||||
mPathResult(0),
|
||||
mAvatarHorizRadius(0) {
|
||||
auto speedGroundProp = avatar.getPropertyType<double>("speed_ground");
|
||||
if (speedGroundProp) {
|
||||
mMaxSpeed = speedGroundProp->data();
|
||||
}
|
||||
|
||||
|
||||
auto bbox = ScaleProperty::scaledBbox(mAvatar);
|
||||
if (bbox.isValid()) {
|
||||
mAvatarHorizRadius = std::sqrt(boxSquareHorizontalBoundingRadius(bbox));
|
||||
} else {
|
||||
spdlog::warn("Created Steering with avatar without any bounding box. This is unusual.");
|
||||
}
|
||||
auto bbox = ScaleProperty::scaledBbox(mAvatar);
|
||||
if (bbox.isValid()) {
|
||||
mAvatarHorizRadius = std::sqrt(boxSquareHorizontalBoundingRadius(bbox));
|
||||
} else {
|
||||
spdlog::warn("Created Steering with avatar without any bounding box. This is unusual.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Steering::setAwareness(Awareness* awareness)
|
||||
{
|
||||
mAwareness = awareness;
|
||||
mTileListenerConnection.disconnect();
|
||||
if (mAwareness) {
|
||||
mTileListenerConnection = mAwareness->EventTileUpdated.connect(sigc::mem_fun(*this, &Steering::Awareness_TileUpdated));
|
||||
//setAwarenessArea();
|
||||
}
|
||||
void Steering::setAwareness(Awareness* awareness) {
|
||||
mAwareness = awareness;
|
||||
mTileListenerConnection.disconnect();
|
||||
if (mAwareness) {
|
||||
mTileListenerConnection = mAwareness->EventTileUpdated.connect(sigc::mem_fun(*this, &Steering::Awareness_TileUpdated));
|
||||
//setAwarenessArea();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Steering::queryDestination(const EntityLocation& destination, double currentServerTimestamp)
|
||||
{
|
||||
int Steering::queryDestination(const EntityLocation& destination, std::chrono::milliseconds currentServerTimestamp) {
|
||||
// if (mAwareness) {
|
||||
//
|
||||
// auto currentAvatarPos = getCurrentAvatarPosition(currentServerTimestamp);
|
||||
|
|
@ -118,16 +115,15 @@ int Steering::queryDestination(const EntityLocation& destination, double current
|
|||
//// mAvatarPositionLastUpdate = currentAvatarPos;
|
||||
//// }
|
||||
// }
|
||||
return -10;
|
||||
return -10;
|
||||
}
|
||||
|
||||
void Steering::setDestination(SteeringDestination destination, double currentServerTimestamp)
|
||||
{
|
||||
if (destination.location.m_pos != mSteeringDestination.location.m_pos || destination.location.m_parent != mSteeringDestination.location.m_parent) {
|
||||
mSteeringDestination = std::move(destination);
|
||||
mUpdateNeeded = true;
|
||||
}
|
||||
setAwarenessArea(currentServerTimestamp);
|
||||
void Steering::setDestination(SteeringDestination destination, std::chrono::milliseconds currentServerTimestamp) {
|
||||
if (destination.location.m_pos != mSteeringDestination.location.m_pos || destination.location.m_parent != mSteeringDestination.location.m_parent) {
|
||||
mSteeringDestination = std::move(destination);
|
||||
mUpdateNeeded = true;
|
||||
}
|
||||
setAwarenessArea(currentServerTimestamp);
|
||||
// mSteeringDestination = std::move(destination);
|
||||
//
|
||||
// if (mAwareness) {
|
||||
|
|
@ -164,356 +160,334 @@ void Steering::setDestination(SteeringDestination destination, double currentSer
|
|||
}
|
||||
|
||||
|
||||
void Steering::setAwarenessArea(double currentServerTimestamp)
|
||||
{
|
||||
if (mAwareness) {
|
||||
auto resolvedPosition = resolvePosition(currentServerTimestamp, mSteeringDestination.location);
|
||||
void Steering::setAwarenessArea(std::chrono::milliseconds currentServerTimestamp) {
|
||||
if (mAwareness) {
|
||||
auto resolvedPosition = resolvePosition(currentServerTimestamp, mSteeringDestination.location);
|
||||
// resolvePosition()
|
||||
|
||||
|
||||
if (resolvedPosition.position.isValid()) {
|
||||
WFMath::Point<2> destination2d(resolvedPosition.position.x(), resolvedPosition.position.z());
|
||||
auto pos = PositionProperty::extractPosition(mAvatar);
|
||||
WFMath::Point<2> entityPosition2d(pos.x(), pos.z());
|
||||
if (resolvedPosition.position.isValid()) {
|
||||
WFMath::Point<2> destination2d(resolvedPosition.position.x(), resolvedPosition.position.z());
|
||||
auto pos = PositionProperty::extractPosition(mAvatar);
|
||||
WFMath::Point<2> entityPosition2d(pos.x(), pos.z());
|
||||
|
||||
WFMath::Vector<2> direction(destination2d - entityPosition2d);
|
||||
auto theta = std::atan2(direction.y(), direction.x()); // rotation about Y
|
||||
WFMath::RotMatrix<2> rm;
|
||||
rm.rotation(theta);
|
||||
WFMath::Vector<2> direction(destination2d - entityPosition2d);
|
||||
auto theta = std::atan2(direction.y(), direction.x()); // rotation about Y
|
||||
WFMath::RotMatrix<2> rm;
|
||||
rm.rotation(theta);
|
||||
|
||||
WFMath::Point<2> start = entityPosition2d;
|
||||
start -= WFMath::Vector<2>(mPadding, mPadding);
|
||||
WFMath::Point<2> start = entityPosition2d;
|
||||
start -= WFMath::Vector<2>(mPadding, mPadding);
|
||||
|
||||
WFMath::Vector<2> size(direction.mag() + (mPadding * 2), mPadding * 2);
|
||||
WFMath::Vector<2> size(direction.mag() + (mPadding * 2), mPadding * 2);
|
||||
|
||||
WFMath::RotBox<2> area;
|
||||
area.size() = size;
|
||||
area.corner0() = start;
|
||||
area.orientation() = WFMath::RotMatrix<2>().identity();
|
||||
area.rotatePoint(rm, entityPosition2d);
|
||||
WFMath::RotBox<2> area;
|
||||
area.size() = size;
|
||||
area.corner0() = start;
|
||||
area.orientation() = WFMath::RotMatrix<2>().identity();
|
||||
area.rotatePoint(rm, entityPosition2d);
|
||||
|
||||
mAwareness->setAwarenessArea(mAvatar.getId(), area, WFMath::Segment<2>(entityPosition2d, destination2d));
|
||||
}
|
||||
}
|
||||
mAwareness->setAwarenessArea(mAvatar.getId(), area, WFMath::Segment<2>(entityPosition2d, destination2d));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t Steering::unawareAreaCount() const
|
||||
{
|
||||
if (mAwareness) {
|
||||
return mAwareness->unawareTilesInArea(mAvatar.getId());
|
||||
}
|
||||
return 0;
|
||||
size_t Steering::unawareAreaCount() const {
|
||||
if (mAwareness) {
|
||||
return mAwareness->unawareTilesInArea(mAvatar.getId());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Steering::setDesiredSpeed(float desiredSpeed)
|
||||
{
|
||||
mDesiredSpeed = desiredSpeed;
|
||||
void Steering::setDesiredSpeed(float desiredSpeed) {
|
||||
mDesiredSpeed = desiredSpeed;
|
||||
}
|
||||
|
||||
int Steering::getPathResult() const
|
||||
{
|
||||
return mPathResult;
|
||||
int Steering::getPathResult() const {
|
||||
return mPathResult;
|
||||
}
|
||||
|
||||
int Steering::updatePath(double currentTimestamp, const WFMath::Point<3>& currentAvatarPosition)
|
||||
{
|
||||
rmt_ScopedCPUSample(Steering_updatePath, 0)
|
||||
mPath.clear();
|
||||
mCurrentPathIndex = 0;
|
||||
if (!mAwareness) {
|
||||
mPathResult = -7;
|
||||
return mPathResult;
|
||||
}
|
||||
auto resolvedPosition = resolvePosition(currentTimestamp, mSteeringDestination.location);
|
||||
if (!resolvedPosition.position.isValid()) {
|
||||
mPathResult = -8;
|
||||
return mPathResult;
|
||||
}
|
||||
mPathResult = mAwareness->findPath(currentAvatarPosition, resolvedPosition.position, mSteeringDestination.distance, mPath);
|
||||
if (mPathResult == -1) {
|
||||
mAwareness->markTilesAsDirty(WFMath::AxisBox<2>(
|
||||
{currentAvatarPosition.x() - 5, currentAvatarPosition.z() - 5},
|
||||
{currentAvatarPosition.x() + 5, currentAvatarPosition.z() + 5}));
|
||||
} else if (mPathResult == -2) {
|
||||
mAwareness->markTilesAsDirty(WFMath::AxisBox<2>(
|
||||
{resolvedPosition.position.x() - 5, resolvedPosition.position.z() - 5},
|
||||
{resolvedPosition.position.x() + 5, resolvedPosition.position.z() + 5}));
|
||||
}
|
||||
//cy_debug_print("Updating path, size of new path: " << result << ". Pos: " << currentAvatarPosition);
|
||||
EventPathUpdated();
|
||||
mUpdateNeeded = false;
|
||||
return mPathResult;
|
||||
int Steering::updatePath(std::chrono::milliseconds currentTimestamp, const WFMath::Point<3>& currentAvatarPosition) {
|
||||
rmt_ScopedCPUSample(Steering_updatePath, 0)
|
||||
mPath.clear();
|
||||
mCurrentPathIndex = 0;
|
||||
if (!mAwareness) {
|
||||
mPathResult = -7;
|
||||
return mPathResult;
|
||||
}
|
||||
auto resolvedPosition = resolvePosition(currentTimestamp, mSteeringDestination.location);
|
||||
if (!resolvedPosition.position.isValid()) {
|
||||
mPathResult = -8;
|
||||
return mPathResult;
|
||||
}
|
||||
mPathResult = mAwareness->findPath(currentAvatarPosition, resolvedPosition.position, (float) mSteeringDestination.distance, mPath);
|
||||
if (mPathResult == -1) {
|
||||
mAwareness->markTilesAsDirty(WFMath::AxisBox<2>(
|
||||
{currentAvatarPosition.x() - 5, currentAvatarPosition.z() - 5},
|
||||
{currentAvatarPosition.x() + 5, currentAvatarPosition.z() + 5}));
|
||||
} else if (mPathResult == -2) {
|
||||
mAwareness->markTilesAsDirty(WFMath::AxisBox<2>(
|
||||
{resolvedPosition.position.x() - 5, resolvedPosition.position.z() - 5},
|
||||
{resolvedPosition.position.x() + 5, resolvedPosition.position.z() + 5}));
|
||||
}
|
||||
//cy_debug_print("Updating path, size of new path: " << result << ". Pos: " << currentAvatarPosition);
|
||||
EventPathUpdated();
|
||||
mUpdateNeeded = false;
|
||||
return mPathResult;
|
||||
}
|
||||
|
||||
int Steering::updatePath(double currentTimestamp)
|
||||
{
|
||||
if (!mAwareness) {
|
||||
return -1;
|
||||
}
|
||||
auto currentEntityPos = mAwareness->projectPosition(mAvatar.getIntId(), currentTimestamp);
|
||||
int Steering::updatePath(std::chrono::milliseconds currentTimestamp) {
|
||||
if (!mAwareness) {
|
||||
return -1;
|
||||
}
|
||||
auto currentEntityPos = mAwareness->projectPosition(mAvatar.getIntId(), currentTimestamp);
|
||||
|
||||
return updatePath(currentTimestamp, currentEntityPos);
|
||||
return updatePath(currentTimestamp, currentEntityPos);
|
||||
}
|
||||
|
||||
void Steering::requestUpdate()
|
||||
{
|
||||
mUpdateNeeded = true;
|
||||
void Steering::requestUpdate() {
|
||||
mUpdateNeeded = true;
|
||||
}
|
||||
|
||||
void Steering::startSteering()
|
||||
{
|
||||
mSteeringEnabled = true;
|
||||
mExpectingServerMovement = false;
|
||||
void Steering::startSteering() {
|
||||
mSteeringEnabled = true;
|
||||
mExpectingServerMovement = false;
|
||||
}
|
||||
|
||||
void Steering::stopSteering()
|
||||
{
|
||||
if (!mSteeringEnabled) {
|
||||
return;
|
||||
}
|
||||
mSteeringEnabled = false;
|
||||
mExpectingServerMovement = false;
|
||||
mLastSentVelocity = WFMath::Vector<2>();
|
||||
void Steering::stopSteering() {
|
||||
if (!mSteeringEnabled) {
|
||||
return;
|
||||
}
|
||||
mSteeringEnabled = false;
|
||||
mExpectingServerMovement = false;
|
||||
mLastSentVelocity = WFMath::Vector<2>();
|
||||
|
||||
//reset path
|
||||
mPath.clear();
|
||||
mCurrentPathIndex = 0;
|
||||
mPathResult = 0;
|
||||
EventPathUpdated();
|
||||
//reset path
|
||||
mPath.clear();
|
||||
mCurrentPathIndex = 0;
|
||||
mPathResult = 0;
|
||||
EventPathUpdated();
|
||||
|
||||
}
|
||||
|
||||
bool Steering::isEnabled() const
|
||||
{
|
||||
return mSteeringEnabled;
|
||||
bool Steering::isEnabled() const {
|
||||
return mSteeringEnabled;
|
||||
}
|
||||
|
||||
const std::vector<WFMath::Point<3>>& Steering::getPath() const
|
||||
{
|
||||
return mPath;
|
||||
const std::vector<WFMath::Point<3>>& Steering::getPath() const {
|
||||
return mPath;
|
||||
}
|
||||
|
||||
size_t Steering::getCurrentPathIndex() const
|
||||
{
|
||||
return mCurrentPathIndex;
|
||||
size_t Steering::getCurrentPathIndex() const {
|
||||
return mCurrentPathIndex;
|
||||
}
|
||||
|
||||
WFMath::Point<3> Steering::getCurrentAvatarPosition(double currentTimestamp) const
|
||||
{
|
||||
return mAwareness ? mAwareness->projectPosition(mAvatar.getIntId(), currentTimestamp) : WFMath::Point<3>{};
|
||||
WFMath::Point<3> Steering::getCurrentAvatarPosition(std::chrono::milliseconds currentTimestamp) const {
|
||||
return mAwareness ? mAwareness->projectPosition(mAvatar.getIntId(), currentTimestamp) : WFMath::Point<3>{};
|
||||
}
|
||||
|
||||
WFMath::Vector<3> Steering::directionTo(double currentTimestamp, const EntityLocation& location) const
|
||||
{
|
||||
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
|
||||
auto resolvedDestination = resolvePosition(currentTimestamp, location);
|
||||
WFMath::Vector<3> Steering::directionTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const {
|
||||
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
|
||||
auto resolvedDestination = resolvePosition(currentTimestamp, location);
|
||||
|
||||
if (!currentEntityPos.isValid() || !resolvedDestination.position.isValid()) {
|
||||
return {};
|
||||
}
|
||||
if (!currentEntityPos.isValid() || !resolvedDestination.position.isValid()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return (resolvedDestination.position - currentEntityPos);
|
||||
return (resolvedDestination.position - currentEntityPos);
|
||||
}
|
||||
|
||||
std::optional<double> Steering::distanceTo(double currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const
|
||||
{
|
||||
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
|
||||
auto resolvedDestination = resolvePosition(currentTimestamp, location);
|
||||
std::optional<double> Steering::distanceTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const {
|
||||
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
|
||||
auto resolvedDestination = resolvePosition(currentTimestamp, location);
|
||||
|
||||
if (!currentEntityPos.isValid() || !resolvedDestination.position.isValid()) {
|
||||
return {};
|
||||
}
|
||||
if (!currentEntityPos.isValid() || !resolvedDestination.position.isValid()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto distance = WFMath::Distance(WFMath::Point<2>(currentEntityPos.x(), currentEntityPos.z()), WFMath::Point<2>(resolvedDestination.position.x(), resolvedDestination.position.z()));
|
||||
if (fromSelf == MeasureType::EDGE) {
|
||||
distance -= mAvatarHorizRadius;
|
||||
}
|
||||
if (toDestination == MeasureType::EDGE) {
|
||||
distance -= resolvedDestination.radius;
|
||||
auto distance = WFMath::Distance(WFMath::Point<2>(currentEntityPos.x(), currentEntityPos.z()), WFMath::Point<2>(resolvedDestination.position.x(), resolvedDestination.position.z()));
|
||||
if (fromSelf == MeasureType::EDGE) {
|
||||
distance -= mAvatarHorizRadius;
|
||||
}
|
||||
if (toDestination == MeasureType::EDGE) {
|
||||
distance -= resolvedDestination.radius;
|
||||
// if (resolvedDestination.location) {
|
||||
// auto& bbox = resolvedDestination.location->bBox();
|
||||
// if (bbox.isValid()) {
|
||||
// distance -= std::sqrt(boxSquareHorizontalBoundingRadius(bbox));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
return std::max(0.0, distance);
|
||||
}
|
||||
return std::max(0.0, distance);
|
||||
}
|
||||
|
||||
Steering::ResolvedPosition Steering::resolvePosition(double currentTimestamp, const EntityLocation& location) const
|
||||
{
|
||||
if (!mAwareness) {
|
||||
return {};
|
||||
}
|
||||
//If there's no parent at all we're operating within the same space as the avatar.
|
||||
if (!location.m_parent) {
|
||||
return {location.m_pos, 0};
|
||||
}
|
||||
//If the parent is the same we're just operating on position data without any volume.
|
||||
if (location.m_parent == mAvatar.m_parent) {
|
||||
//Just ignore any extra position supplied.
|
||||
return {location.pos(), 0};
|
||||
}
|
||||
//If the supplied destination doesn't belong to the current domain, walk upwards until we find the entity that does.
|
||||
//This entity will then determine the position.
|
||||
auto entity = location.m_parent;
|
||||
Steering::ResolvedPosition Steering::resolvePosition(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const {
|
||||
if (!mAwareness) {
|
||||
return {};
|
||||
}
|
||||
//If there's no parent at all we're operating within the same space as the avatar.
|
||||
if (!location.m_parent) {
|
||||
return {location.m_pos, 0};
|
||||
}
|
||||
//If the parent is the same we're just operating on position data without any volume.
|
||||
if (location.m_parent == mAvatar.m_parent) {
|
||||
//Just ignore any extra position supplied.
|
||||
return {location.pos(), 0};
|
||||
}
|
||||
//If the supplied destination doesn't belong to the current domain, walk upwards until we find the entity that does.
|
||||
//This entity will then determine the position.
|
||||
auto entity = location.m_parent;
|
||||
|
||||
while (entity->m_parent && entity->m_parent != mAvatar.m_parent) {
|
||||
entity = entity->m_parent;
|
||||
}
|
||||
while (entity->m_parent && entity->m_parent != mAvatar.m_parent) {
|
||||
entity = entity->m_parent;
|
||||
}
|
||||
|
||||
//Could not find the parent domain entity
|
||||
if (!entity) {
|
||||
return {};
|
||||
}
|
||||
//Could not find the parent domain entity
|
||||
if (!entity) {
|
||||
return {};
|
||||
}
|
||||
|
||||
double distance = 0;
|
||||
auto I = mAwareness->getObservedEntities().find(entity->getIntId());
|
||||
if (I != mAwareness->getObservedEntities().end()) {
|
||||
if (I->second->scaledBbox.isValid()) {
|
||||
distance = std::sqrt(boxSquareHorizontalBoundingRadius(I->second->scaledBbox));
|
||||
}
|
||||
}
|
||||
double distance = 0;
|
||||
auto I = mAwareness->getObservedEntities().find(entity->getIntId());
|
||||
if (I != mAwareness->getObservedEntities().end()) {
|
||||
if (I->second->scaledBbox.isValid()) {
|
||||
distance = std::sqrt(boxSquareHorizontalBoundingRadius(I->second->scaledBbox));
|
||||
}
|
||||
}
|
||||
|
||||
return {mAwareness->projectPosition(entity->getIntId(), currentTimestamp), distance};
|
||||
return {mAwareness->projectPosition(entity->getIntId(), currentTimestamp), distance};
|
||||
}
|
||||
|
||||
bool Steering::isAtDestination(double currentTimestamp, const SteeringDestination& destination) const
|
||||
{
|
||||
auto distance = distanceTo(currentTimestamp, destination.location, destination.measureFromAvatar, destination.measureToDestination);
|
||||
if (distance) {
|
||||
return *distance <= destination.distance;
|
||||
}
|
||||
return false;
|
||||
bool Steering::isAtDestination(std::chrono::milliseconds currentTimestamp, const SteeringDestination& destination) const {
|
||||
auto distance = distanceTo(currentTimestamp, destination.location, destination.measureFromAvatar, destination.measureToDestination);
|
||||
if (distance) {
|
||||
return *distance <= destination.distance;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Steering::isAtCurrentDestination(double currentTimestamp) const
|
||||
{
|
||||
return isAtDestination(currentTimestamp, mSteeringDestination);
|
||||
bool Steering::isAtCurrentDestination(std::chrono::milliseconds currentTimestamp) const {
|
||||
return isAtDestination(currentTimestamp, mSteeringDestination);
|
||||
}
|
||||
|
||||
|
||||
SteeringResult Steering::update(double currentTimestamp)
|
||||
{
|
||||
rmt_ScopedCPUSample(Steering_update, 0)
|
||||
SteeringResult result{};
|
||||
if (!mSteeringEnabled) {
|
||||
auto propelProperty = mAvatar.getPropertyClass<Vector3Property>("_propel");
|
||||
if (propelProperty && propelProperty->data().isValid() && propelProperty->data() != WFMath::Vector<3>::ZERO()) {
|
||||
result.direction = WFMath::Vector<3>::ZERO();
|
||||
}
|
||||
} else if (mAwareness) {
|
||||
SteeringResult Steering::update(std::chrono::milliseconds currentTimestamp) {
|
||||
rmt_ScopedCPUSample(Steering_update, 0)
|
||||
SteeringResult result{};
|
||||
if (!mSteeringEnabled) {
|
||||
auto propelProperty = mAvatar.getPropertyClass<Vector3Property>("_propel");
|
||||
if (propelProperty && propelProperty->data().isValid() && propelProperty->data() != WFMath::Vector<3>::ZERO()) {
|
||||
result.direction = WFMath::Vector<3>::ZERO();
|
||||
}
|
||||
} else if (mAwareness) {
|
||||
|
||||
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
|
||||
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
|
||||
|
||||
if (mUpdateNeeded) {
|
||||
updatePath(currentTimestamp, currentEntityPos);
|
||||
}
|
||||
if (!mPath.empty()) {
|
||||
//First check if we've arrived at our actual destination.
|
||||
if (isAtCurrentDestination(currentTimestamp)) {
|
||||
//We've arrived at our destination. If we're moving we should stop.
|
||||
if (mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
|
||||
result.direction = WFMath::Vector<3>::ZERO();
|
||||
mLastSentVelocity = WFMath::Vector<2>::ZERO();
|
||||
mExpectingServerMovement = true;
|
||||
}
|
||||
stopSteering();
|
||||
} else {
|
||||
//We should send a move op if we're either not moving, or we've reached a waypoint, or we need to divert a lot.
|
||||
const WFMath::Point<2> entityPosition(currentEntityPos.x(), currentEntityPos.z());
|
||||
if (mUpdateNeeded) {
|
||||
updatePath(currentTimestamp, currentEntityPos);
|
||||
}
|
||||
if (!mPath.empty()) {
|
||||
//First check if we've arrived at our actual destination.
|
||||
if (isAtCurrentDestination(currentTimestamp)) {
|
||||
//We've arrived at our destination. If we're moving we should stop.
|
||||
if (mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
|
||||
result.direction = WFMath::Vector<3>::ZERO();
|
||||
mLastSentVelocity = WFMath::Vector<2>::ZERO();
|
||||
mExpectingServerMovement = true;
|
||||
}
|
||||
stopSteering();
|
||||
} else {
|
||||
//We should send a move op if we're either not moving, or we've reached a waypoint, or we need to divert a lot.
|
||||
const WFMath::Point<2> entityPosition(currentEntityPos.x(), currentEntityPos.z());
|
||||
|
||||
WFMath::Point<2> nextWaypoint(mPath[mCurrentPathIndex].x(), mPath[mCurrentPathIndex].z());
|
||||
while (WFMath::Distance(nextWaypoint, entityPosition) < mAvatarHorizRadius && mCurrentPathIndex < mPath.size() - 1) {
|
||||
mCurrentPathIndex++;
|
||||
nextWaypoint = WFMath::Point<2>(mPath[mCurrentPathIndex].x(), mPath[mCurrentPathIndex].z());
|
||||
}
|
||||
WFMath::Point<2> nextWaypoint(mPath[mCurrentPathIndex].x(), mPath[mCurrentPathIndex].z());
|
||||
while (WFMath::Distance(nextWaypoint, entityPosition) < mAvatarHorizRadius && mCurrentPathIndex < mPath.size() - 1) {
|
||||
mCurrentPathIndex++;
|
||||
nextWaypoint = WFMath::Point<2>(mPath[mCurrentPathIndex].x(), mPath[mCurrentPathIndex].z());
|
||||
}
|
||||
|
||||
WFMath::Vector<2> distance = nextWaypoint - entityPosition;
|
||||
WFMath::Vector<2> velocityNorm = distance; //The velocity, normalized
|
||||
velocityNorm = velocityNorm.normalize() * mDesiredSpeed;
|
||||
WFMath::Point<2> destination;
|
||||
WFMath::Vector<2> distance = nextWaypoint - entityPosition;
|
||||
WFMath::Vector<2> velocityNorm = distance; //The velocity, normalized, as meter per second
|
||||
velocityNorm = velocityNorm.normalize() * mDesiredSpeed;
|
||||
WFMath::Point<2> destination;
|
||||
|
||||
result.timeToNextWaypoint = distance.mag() / velocityNorm.mag();
|
||||
result.timeToNextWaypoint = std::chrono::milliseconds((std::int64_t) ((distance.mag() / velocityNorm.mag()) * 1000));
|
||||
|
||||
if (mCurrentPathIndex == mPath.size() - 1) {
|
||||
//if the next waypoint is the destination we should send a "move to position" update to the server, to make sure that we stop when we've arrived.
|
||||
//otherwise, if there's too much lag, we might end up overshooting our destination and will have to double back
|
||||
destination = nextWaypoint;
|
||||
}
|
||||
if (mCurrentPathIndex == mPath.size() - 1) {
|
||||
//if the next waypoint is the destination we should send a "move to position" update to the server, to make sure that we stop when we've arrived.
|
||||
//otherwise, if there's too much lag, we might end up overshooting our destination and will have to double back
|
||||
destination = nextWaypoint;
|
||||
}
|
||||
|
||||
//Check if we need to divert in order to avoid colliding.
|
||||
WFMath::Vector<2> newVelocity; //The new velocity after avoiding, not normalized.
|
||||
bool shouldSend = false;
|
||||
bool avoiding = mAwareness->avoidObstacles(mAvatar.getIntId(), entityPosition, velocityNorm * mMaxSpeed, newVelocity, currentTimestamp, &nextWaypoint);
|
||||
if (avoiding) {
|
||||
//spdlog::info("Avoiding.");
|
||||
velocityNorm = newVelocity / mMaxSpeed;
|
||||
//Check if we need to divert in order to avoid colliding.
|
||||
WFMath::Vector<2> newVelocity; //The new velocity after avoiding, not normalized.
|
||||
bool shouldSend = false;
|
||||
bool avoiding = mAwareness->avoidObstacles(mAvatar.getIntId(), entityPosition, velocityNorm * mMaxSpeed, newVelocity, currentTimestamp, &nextWaypoint);
|
||||
if (avoiding) {
|
||||
//spdlog::info("Avoiding.");
|
||||
velocityNorm = newVelocity / mMaxSpeed;
|
||||
|
||||
//Schedule a new steering op very soon
|
||||
result.timeToNextWaypoint = std::min(*result.timeToNextWaypoint, 0.1);
|
||||
mUpdateNeeded = true;
|
||||
shouldSend = true;
|
||||
}
|
||||
//Schedule a new steering op very soon
|
||||
result.timeToNextWaypoint = std::min(*result.timeToNextWaypoint, std::chrono::milliseconds(100));
|
||||
mUpdateNeeded = true;
|
||||
shouldSend = true;
|
||||
}
|
||||
|
||||
if (velocityNorm.isValid()) {
|
||||
if (mLastSentVelocity.isValid()) {
|
||||
auto velocityProp = mAvatar.getPropertyClassFixed<VelocityProperty>();
|
||||
//If the entity has stopped, and we're not waiting for confirmation to a movement request we've made, we need to start moving.
|
||||
if (velocityProp && velocityProp->data() == WFMath::Vector<3>::ZERO() && !mExpectingServerMovement) {
|
||||
shouldSend = true;
|
||||
} else {
|
||||
auto currentTheta = std::atan2(mLastSentVelocity.y(), mLastSentVelocity.x());
|
||||
auto newTheta = std::atan2(velocityNorm.y(), velocityNorm.x());
|
||||
if (velocityNorm.isValid()) {
|
||||
if (mLastSentVelocity.isValid()) {
|
||||
auto velocityProp = mAvatar.getPropertyClassFixed<VelocityProperty>();
|
||||
//If the entity has stopped, and we're not waiting for confirmation to a movement request we've made, we need to start moving.
|
||||
if (velocityProp && velocityProp->data() == WFMath::Vector<3>::ZERO() && !mExpectingServerMovement) {
|
||||
shouldSend = true;
|
||||
} else {
|
||||
auto currentTheta = std::atan2(mLastSentVelocity.y(), mLastSentVelocity.x());
|
||||
auto newTheta = std::atan2(velocityNorm.y(), velocityNorm.x());
|
||||
|
||||
//If we divert too much from where we need to go we must adjust.
|
||||
if (std::abs(currentTheta - newTheta) > WFMath::numeric_constants<double>::pi() / 20) {
|
||||
shouldSend = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//If we've never sent a movement update before we should do that now.
|
||||
shouldSend = true;
|
||||
}
|
||||
}
|
||||
if (shouldSend) {
|
||||
//If we're moving to a certain destination and aren't avoiding anything we should tell the server to move to the destination.
|
||||
if (destination.isValid() && !avoiding) {
|
||||
auto posProp = mAvatar.getPropertyClassFixed<PositionProperty>();
|
||||
auto y = posProp ? posProp->data().y() : 0.0;
|
||||
result.destination = WFMath::Point<3>(destination.x(), y, destination.y());
|
||||
}
|
||||
result.direction = WFMath::Vector<3>(velocityNorm.x(), 0, velocityNorm.y());
|
||||
mLastSentVelocity = velocityNorm;
|
||||
mExpectingServerMovement = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//We are steering, but the path is empty, which means we can't find any path. If we're moving we should stop movement.
|
||||
//But we won't stop steering; perhaps we'll find a path later.
|
||||
if (mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
|
||||
result.direction = WFMath::Vector<3>::ZERO();
|
||||
mLastSentVelocity = WFMath::Vector<2>::ZERO();
|
||||
mExpectingServerMovement = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
//If we divert too much from where we need to go we must adjust.
|
||||
if (std::abs(currentTheta - newTheta) > WFMath::numeric_constants<double>::pi() / 20) {
|
||||
shouldSend = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//If we've never sent a movement update before we should do that now.
|
||||
shouldSend = true;
|
||||
}
|
||||
}
|
||||
if (shouldSend) {
|
||||
//If we're moving to a certain destination and aren't avoiding anything we should tell the server to move to the destination.
|
||||
if (destination.isValid() && !avoiding) {
|
||||
auto posProp = mAvatar.getPropertyClassFixed<PositionProperty>();
|
||||
auto y = posProp ? posProp->data().y() : 0.0;
|
||||
result.destination = WFMath::Point<3>(destination.x(), y, destination.y());
|
||||
}
|
||||
result.direction = WFMath::Vector<3>(velocityNorm.x(), 0, velocityNorm.y());
|
||||
mLastSentVelocity = velocityNorm;
|
||||
mExpectingServerMovement = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//We are steering, but the path is empty, which means we can't find any path. If we're moving we should stop movement.
|
||||
//But we won't stop steering; perhaps we'll find a path later.
|
||||
if (mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
|
||||
result.direction = WFMath::Vector<3>::ZERO();
|
||||
mLastSentVelocity = WFMath::Vector<2>::ZERO();
|
||||
mExpectingServerMovement = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Steering::Awareness_TileUpdated(int tx, int ty)
|
||||
{
|
||||
mUpdateNeeded = true;
|
||||
void Steering::Awareness_TileUpdated(int tx, int ty) {
|
||||
mUpdateNeeded = true;
|
||||
}
|
||||
|
||||
bool Steering::getIsExpectingServerMovement() const
|
||||
{
|
||||
return mExpectingServerMovement;
|
||||
bool Steering::getIsExpectingServerMovement() const {
|
||||
return mExpectingServerMovement;
|
||||
}
|
||||
|
||||
void Steering::setIsExpectingServerMovement(bool expected)
|
||||
{
|
||||
mExpectingServerMovement = expected;
|
||||
void Steering::setIsExpectingServerMovement(bool expected) {
|
||||
mExpectingServerMovement = expected;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ struct SteeringResult
|
|||
* Time until the next waypoint is reached.
|
||||
* This is used for scheduling the next update tick.
|
||||
*/
|
||||
std::optional<double> timeToNextWaypoint;
|
||||
std::optional<std::chrono::milliseconds > timeToNextWaypoint;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -155,22 +155,22 @@ class Steering : public virtual sigc::trackable
|
|||
|
||||
void setAwareness(Awareness* awareness);
|
||||
|
||||
int queryDestination(const EntityLocation& destination, double currentServerTimestamp);
|
||||
int queryDestination(const EntityLocation& destination, std::chrono::milliseconds currentServerTimestamp);
|
||||
|
||||
void setDestination(SteeringDestination destination, double currentServerTimestamp);
|
||||
void setDestination(SteeringDestination destination, std::chrono::milliseconds currentServerTimestamp);
|
||||
|
||||
/**
|
||||
* @brief Updates the path.
|
||||
* @param currentAvatarPosition The current position of the avatar entity.
|
||||
* @return If >= 0, a path was found. If <0 and >= -3 we couldn't find a path currently because we don't have all data yet. If <= -4 we couldn't find a path.
|
||||
*/
|
||||
int updatePath(double currentTimestamp, const WFMath::Point<3>& currentAvatarPosition);
|
||||
int updatePath(std::chrono::milliseconds currentTimestamp, const WFMath::Point<3>& currentAvatarPosition);
|
||||
|
||||
/**
|
||||
* @brief Updates the path.
|
||||
* @return If >= 0, a path was found. If <0 and >= -3 we couldn't find a path currently because we don't have all data yet. If <= -4 we couldn't find a path.
|
||||
*/
|
||||
int updatePath(double currentTimestamp);
|
||||
int updatePath(std::chrono::milliseconds currentTimestamp);
|
||||
|
||||
/**
|
||||
* @brief Requests an update of the path.
|
||||
|
|
@ -229,23 +229,23 @@ class Steering : public virtual sigc::trackable
|
|||
*
|
||||
* Call this often when steering is enabled.
|
||||
*/
|
||||
SteeringResult update(double currentTimestamp);
|
||||
SteeringResult update(std::chrono::milliseconds currentTimestamp);
|
||||
|
||||
WFMath::Point<3> getCurrentAvatarPosition(double currentTimestamp) const;
|
||||
WFMath::Point<3> getCurrentAvatarPosition(std::chrono::milliseconds currentTimestamp) const;
|
||||
|
||||
size_t unawareAreaCount() const;
|
||||
|
||||
int getPathResult() const;
|
||||
|
||||
bool isAtDestination(double currentTimestamp, const SteeringDestination& destination) const;
|
||||
bool isAtDestination(std::chrono::milliseconds currentTimestamp, const SteeringDestination& destination) const;
|
||||
|
||||
bool isAtCurrentDestination(double currentTimestamp) const;
|
||||
bool isAtCurrentDestination(std::chrono::milliseconds currentTimestamp) const;
|
||||
|
||||
std::optional<double> distanceTo(double currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const;
|
||||
std::optional<double> distanceTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const;
|
||||
|
||||
WFMath::Vector<3> directionTo(double currentTimestamp, const EntityLocation& location) const;
|
||||
WFMath::Vector<3> directionTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const;
|
||||
|
||||
Steering::ResolvedPosition resolvePosition(double currentTimestamp, const EntityLocation& location) const;
|
||||
Steering::ResolvedPosition resolvePosition(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const;
|
||||
|
||||
/**
|
||||
* @brief Emitted when the path has been updated.
|
||||
|
|
@ -332,7 +332,7 @@ class Steering : public virtual sigc::trackable
|
|||
*
|
||||
* mPadding determines the width of the corridor.
|
||||
*/
|
||||
void setAwarenessArea(double currentServerTimestamp);
|
||||
void setAwarenessArea(std::chrono::milliseconds currentServerTimestamp);
|
||||
|
||||
/**
|
||||
* @brief Listen to tiles being updated, and request updates.
|
||||
|
|
@ -347,17 +347,17 @@ class Steering : public virtual sigc::trackable
|
|||
*/
|
||||
void moveInDirection(const WFMath::Vector<2>& direction);
|
||||
|
||||
/**
|
||||
* @brief Tells the server to move towards a certain point.
|
||||
*
|
||||
* The server will make sure to stop at the specified point, unless we collide with something.
|
||||
* This should therefore be used to reach our final destination.
|
||||
*
|
||||
* @param point The point to move towards.
|
||||
*/
|
||||
/**
|
||||
* @brief Tells the server to move towards a certain point.
|
||||
*
|
||||
* The server will make sure to stop at the specified point, unless we collide with something.
|
||||
* This should therefore be used to reach our final destination.
|
||||
*
|
||||
* @param point The point to move towards.
|
||||
*/
|
||||
void moveToPoint(const WFMath::Point<3>& point);
|
||||
|
||||
void updatePosition(double currentServerTimestamp, long entityId, WFMath::Point<3>& pos) const;
|
||||
void updatePosition(std::chrono::milliseconds currentServerTimestamp, long entityId, WFMath::Point<3>& pos) const;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ AwareMind::~AwareMind() {
|
|||
}
|
||||
}
|
||||
|
||||
double AwareMind::getCurrentServerTime() const {
|
||||
std::chrono::milliseconds AwareMind::getCurrentServerTime() const {
|
||||
return mServerTime;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
const std::shared_ptr<Awareness>& getAwareness() const;
|
||||
|
||||
double getCurrentServerTime() const;
|
||||
std::chrono::milliseconds getCurrentServerTime() const;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ void BaseMind::sightSetOperation(const Operation& op, OpVector& res) {
|
|||
spdlog::error("Got sight(set) of non-entity");
|
||||
return;
|
||||
}
|
||||
m_map.updateAdd(ent, op->getSeconds());
|
||||
m_map.updateAdd(ent, std::chrono::milliseconds(op->getStamp()));
|
||||
}
|
||||
|
||||
void BaseMind::SoundOperation(const Operation& op, OpVector& res) {
|
||||
|
|
@ -130,8 +130,8 @@ void BaseMind::SightOperation(const Operation& op, OpVector& res) {
|
|||
cy_debug_print("BaseMind::SightOperation(Sight)")
|
||||
// Deliver argument to sight things
|
||||
if (!isAwake()) { return; }
|
||||
if (op->isDefaultSeconds()) {
|
||||
spdlog::error("Sight operation had no seconds set, ignoring it.");
|
||||
if (op->isDefaultStamp()) {
|
||||
spdlog::error("Sight operation had no stamp set, ignoring it.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -147,10 +147,10 @@ void BaseMind::SightOperation(const Operation& op, OpVector& res) {
|
|||
std::string event_name("sight_");
|
||||
event_name += op2->getParent();
|
||||
|
||||
//Check that the argument had seconds set; if not the timestamp of the updates will be wrong.
|
||||
if (!op2->hasAttrFlag(Atlas::Objects::Operation::SECONDS_FLAG)) {
|
||||
//Check that the argument had stamp set; if not the timestamp of the updates will be wrong.
|
||||
if (!op2->hasAttrFlag(Atlas::Objects::STAMP_FLAG)) {
|
||||
//Copy from wrapping op to fix this.
|
||||
op2->setSeconds(op->getSeconds());
|
||||
op2->setStamp(op->getStamp());
|
||||
}
|
||||
|
||||
if (!m_script || m_script->operation(event_name, op2, res) != OPERATION_BLOCKED) {
|
||||
|
|
@ -163,7 +163,7 @@ void BaseMind::SightOperation(const Operation& op, OpVector& res) {
|
|||
return;
|
||||
}
|
||||
cy_debug_print(" arg is an entity!")
|
||||
auto me = m_map.updateAdd(ent, op->getSeconds());
|
||||
auto me = m_map.updateAdd(ent, std::chrono::milliseconds(op->getStamp()));
|
||||
if (me) {
|
||||
me->setVisible();
|
||||
}
|
||||
|
|
@ -224,7 +224,7 @@ void BaseMind::AppearanceOperation(const Operation& op, OpVector& res) {
|
|||
} else {
|
||||
spdlog::error("BaseMind: Appearance op does not have stamp");
|
||||
}
|
||||
entity->update(op->getSeconds());
|
||||
entity->update(std::chrono::milliseconds(op->getStamp()));
|
||||
entity->setVisible();
|
||||
}
|
||||
}
|
||||
|
|
@ -383,13 +383,13 @@ void BaseMind::addPropertyScriptCallback(std::string propertyName, std::string s
|
|||
}
|
||||
|
||||
void BaseMind::updateServerTimeFromOperation(const Atlas::Objects::Operation::RootOperationData& op) {
|
||||
//It's ok if the server sends an op without 'seconds' set.
|
||||
if (!op.isDefaultSeconds()) {
|
||||
//It's ok if the server sends an op without 'stamp' set.
|
||||
if (!op.isDefaultStamp()) {
|
||||
//Alert if there's a too large difference in time.
|
||||
if (op.getSeconds() - mServerTime < -30) {
|
||||
spdlog::warn("Operation '{}' has seconds set ({}) earlier than already recorded seconds ({}).", op.getParent(), op.getSeconds(), mServerTime);
|
||||
if (std::chrono::milliseconds(op.getStamp()) - mServerTime < std::chrono::seconds(-30)) {
|
||||
spdlog::warn("Operation '{}' has stamp set ({}) earlier than already recorded stamp ({}).", op.getParent(), op.getStamp(), mServerTime.count());
|
||||
}
|
||||
mServerTime = op.getSeconds();
|
||||
mServerTime = std::chrono::milliseconds(op.getStamp());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -496,7 +496,7 @@ void BaseMind::processTick(OpVector& res) {
|
|||
//Start by scheduling the next tick op.
|
||||
Atlas::Objects::Operation::Tick tick;
|
||||
//Do one tick every 10ms. (to be revisited)
|
||||
tick->setFutureSeconds(0.01);
|
||||
tick->setFutureMilliseconds(10);
|
||||
tick->setTo(getId());
|
||||
tick->setFrom(getId());
|
||||
res.emplace_back(std::move(tick));
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ protected:
|
|||
/// \brief Memory map of world entities this mind knows about
|
||||
MemMap m_map;
|
||||
/// \brief World time as far as this mind is aware
|
||||
double mServerTime;
|
||||
std::chrono::milliseconds mServerTime;
|
||||
|
||||
std::map<std::string, std::vector<Operation>> m_pendingEntitiesOperations;
|
||||
std::deque<Operation> m_pendingOperations;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include <rules/BBoxProperty.h>
|
||||
#include <rules/ScaleProperty.h>
|
||||
|
||||
#include <utility>
|
||||
#include "MemEntity.h"
|
||||
#include "rules/SolidProperty.h"
|
||||
#include "common/TypeNode.h"
|
||||
|
|
@ -26,8 +28,8 @@
|
|||
static const bool debug_flag = false;
|
||||
|
||||
MemEntity::MemEntity(RouterId id) :
|
||||
LocatedEntity(id),
|
||||
m_lastSeen(0.),
|
||||
LocatedEntity(std::move(id)),
|
||||
m_lastSeen(0),
|
||||
m_lastUpdated(0) {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
/// be cleaned up.
|
||||
class MemEntity : public LocatedEntity {
|
||||
protected:
|
||||
double m_lastSeen;
|
||||
std::chrono::milliseconds m_lastSeen;
|
||||
|
||||
std::unique_ptr<PropertyBase> createProperty(const std::string& propertyName) const override;
|
||||
|
||||
|
|
@ -46,11 +46,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
const double& lastSeen() const {
|
||||
std::chrono::milliseconds lastSeen() const {
|
||||
return m_lastSeen;
|
||||
}
|
||||
|
||||
void update(const double& d) {
|
||||
void update(std::chrono::milliseconds d) {
|
||||
if (d >= m_lastSeen) {
|
||||
m_lastSeen = d;
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ public:
|
|||
// TransformData m_transform;
|
||||
// MovementData m_movement;
|
||||
//WFMath::AxisBox<3> m_bbox;
|
||||
double m_lastUpdated;
|
||||
std::chrono::milliseconds m_lastUpdated;
|
||||
//Location m_location;
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,9 +26,7 @@
|
|||
#include "common/id.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/TypeNode.h"
|
||||
#include "common/Inheritance.h"
|
||||
|
||||
#include <Atlas/Objects/Operation.h>
|
||||
#include <Atlas/Objects/Anonymous.h>
|
||||
#include "rules/AtlasProperties.h"
|
||||
#include "rules/PhysicalProperties.h"
|
||||
|
|
@ -55,7 +53,7 @@ void MemMap::addEntity(const Ref<MemEntity>& entity) {
|
|||
m_checkIterator = m_entities.find(next);
|
||||
}
|
||||
|
||||
void MemMap::readEntity(const Ref<MemEntity>& entity, const RootEntity& ent, double timestamp)
|
||||
void MemMap::readEntity(const Ref<MemEntity>& entity, const RootEntity& ent, std::chrono::milliseconds timestamp)
|
||||
// Read the contents of an Atlas message into an entity
|
||||
{
|
||||
entity->m_lastUpdated = timestamp;
|
||||
|
|
@ -129,7 +127,7 @@ void MemMap::applyTypePropertiesToEntity(const Ref<MemEntity>& entity) {
|
|||
}
|
||||
}
|
||||
|
||||
void MemMap::updateEntity(const Ref<MemEntity>& entity, const RootEntity& ent, double timestamp)
|
||||
void MemMap::updateEntity(const Ref<MemEntity>& entity, const RootEntity& ent, std::chrono::milliseconds timestamp)
|
||||
// Update contents of entity an Atlas message.
|
||||
{
|
||||
assert(entity != nullptr);
|
||||
|
|
@ -148,8 +146,8 @@ void MemMap::updateEntity(const Ref<MemEntity>& entity, const RootEntity& ent, d
|
|||
|
||||
}
|
||||
|
||||
Ref<MemEntity> MemMap::newEntity(RouterId id,
|
||||
const RootEntity& ent, double timestamp)
|
||||
Ref<MemEntity> MemMap::newEntity(const RouterId& id,
|
||||
const RootEntity& ent, std::chrono::milliseconds timestamp)
|
||||
// Create a new entity from an Atlas message.
|
||||
{
|
||||
assert(m_entities.find(id.m_intId) == m_entities.end());
|
||||
|
|
@ -190,7 +188,7 @@ void MemMap::sendLook(OpVector& res) {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<MemEntity> MemMap::addId(RouterId id)
|
||||
Ref<MemEntity> MemMap::addId(const RouterId& id)
|
||||
// Queue the ID of an entity we are interested in
|
||||
{
|
||||
assert(!id.m_id.empty());
|
||||
|
|
@ -297,7 +295,7 @@ void MemMap::addContents(const RootEntity& ent)
|
|||
}
|
||||
}
|
||||
|
||||
Ref<MemEntity> MemMap::updateAdd(const RootEntity& ent, const double& d)
|
||||
Ref<MemEntity> MemMap::updateAdd(const RootEntity& ent, std::chrono::milliseconds d)
|
||||
// Update an entity in our memory, from an Atlas message
|
||||
// The mind code relies on this function never sending a Sight to
|
||||
// be sure that seeing something created does not imply that the created
|
||||
|
|
@ -394,7 +392,7 @@ EntityVector MemMap::findByType(const std::string& what)
|
|||
|
||||
EntityVector MemMap::findByLocation(const EntityLocation& loc,
|
||||
WFMath::CoordType radius,
|
||||
const std::string& what) {
|
||||
const std::string& what) const {
|
||||
//TODO: move to awareness
|
||||
EntityVector res;
|
||||
auto place = loc.m_parent;
|
||||
|
|
@ -438,14 +436,14 @@ EntityVector MemMap::findByLocation(const EntityLocation& loc,
|
|||
return res;
|
||||
}
|
||||
|
||||
void MemMap::check(const double& time) {
|
||||
void MemMap::check(std::chrono::milliseconds time) {
|
||||
//Check if the entity hasn't been seen the last 600 seconds, and if so removes it.
|
||||
if (m_checkIterator == m_entities.end()) {
|
||||
m_checkIterator = m_entities.begin();
|
||||
} else {
|
||||
auto me = m_checkIterator->second;
|
||||
assert(me);
|
||||
if (me->getType() && !me->isVisible() && (time - me->lastSeen()) > 600 &&
|
||||
if (me->getType() && !me->isVisible() && (time - me->lastSeen()) > std::chrono::seconds(600) &&
|
||||
(me->m_contains == nullptr || me->m_contains->empty())) {
|
||||
m_checkIterator = m_entities.erase(m_checkIterator);
|
||||
|
||||
|
|
|
|||
|
|
@ -83,18 +83,18 @@ protected:
|
|||
|
||||
std::deque<Operation> m_typeResolverOps;
|
||||
|
||||
void readEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, double timestamp);
|
||||
void readEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp);
|
||||
|
||||
void updateEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, double timestamp);
|
||||
void updateEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp);
|
||||
|
||||
Ref<MemEntity> newEntity(RouterId,
|
||||
const Atlas::Objects::Entity::RootEntity&, double timestamp);
|
||||
Ref<MemEntity> newEntity(const RouterId&,
|
||||
const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp);
|
||||
|
||||
void addContents(const Atlas::Objects::Entity::RootEntity&);
|
||||
|
||||
Ref<MemEntity> addId(RouterId id);
|
||||
Ref<MemEntity> addId(const RouterId& id);
|
||||
|
||||
void applyTypePropertiesToEntity(const Ref<MemEntity>& entity);
|
||||
static void applyTypePropertiesToEntity(const Ref<MemEntity>& entity);
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ public:
|
|||
|
||||
Ref<MemEntity> getAdd(const std::string& id);
|
||||
|
||||
Ref<MemEntity> updateAdd(const Atlas::Objects::Entity::RootEntity&, const double&);
|
||||
Ref<MemEntity> updateAdd(const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds);
|
||||
|
||||
///\brief Add an entity-related memory or update it if it already exists
|
||||
///@param id - the id of entity to which we relate the memory
|
||||
|
|
@ -152,9 +152,9 @@ public:
|
|||
|
||||
EntityVector findByLocation(const EntityLocation& where,
|
||||
WFMath::CoordType radius,
|
||||
const std::string& what);
|
||||
const std::string& what) const;
|
||||
|
||||
void check(const double&);
|
||||
void check(std::chrono::milliseconds t);
|
||||
|
||||
void flush();
|
||||
|
||||
|
|
|
|||
|
|
@ -108,14 +108,14 @@ Py::Object CyPy_MemMap::find_by_type(const Py::Tuple& args) {
|
|||
Py::Object CyPy_MemMap::updateAdd(const Py::Tuple& args) {
|
||||
args.verify_length(2);
|
||||
|
||||
double time = verifyNumeric(args[1]);
|
||||
std::chrono::milliseconds time(verifyLong(args[1]));
|
||||
if (args[0].isDict()) {
|
||||
auto element = CyPy_Element::dictAsElement(Py::Dict(args[0]));
|
||||
try {
|
||||
|
||||
Root obj = m_value->getTypeStore().getFactories().createObject(element);
|
||||
|
||||
RootEntity ent = Atlas::Objects::smart_dynamic_cast<RootEntity>(obj);
|
||||
auto ent = Atlas::Objects::smart_dynamic_cast<RootEntity>(obj);
|
||||
if (!ent.isValid()) {
|
||||
throw Py::TypeError("arg is a Message that does not represent an entity");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,8 +99,9 @@ void CyPy_Operation::init_type() {
|
|||
PYCXX_ADD_VARARGS_METHOD(set_refno, setRefno, PYCXX_SIG_DOC("set_refno(long)", "Sets the reference number."));
|
||||
PYCXX_ADD_VARARGS_METHOD(set_from, setFrom, PYCXX_SIG_DOC("set_from(string)", "Sets from which entity the operation is from."));
|
||||
PYCXX_ADD_VARARGS_METHOD(set_to, setTo, PYCXX_SIG_DOC("set_to(string)", "Sets to which entity the operation is directed."));
|
||||
PYCXX_ADD_VARARGS_METHOD(set_seconds, setSeconds, "");
|
||||
PYCXX_ADD_VARARGS_METHOD(set_stamp, setStamp, "");
|
||||
PYCXX_ADD_VARARGS_METHOD(set_future_seconds, setFutureSeconds, "");
|
||||
PYCXX_ADD_VARARGS_METHOD(set_future_milliseconds, setFutureMilliseconds, "");
|
||||
PYCXX_ADD_VARARGS_METHOD(set_name, setName, "");
|
||||
PYCXX_ADD_VARARGS_METHOD(set_args, setArgs, PYCXX_SIG_DOC("set_args(sequence)", "Sets the argument list. The supplied sequence could be any of Operation|ElementMap|RootEntity|Python Dict."));
|
||||
PYCXX_ADD_NOARGS_METHOD(get_serialno, getSerialno, "");
|
||||
|
|
@ -108,8 +109,9 @@ void CyPy_Operation::init_type() {
|
|||
PYCXX_ADD_NOARGS_METHOD(get_refno, getRefno, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(get_from, getFrom, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(get_to, getTo, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(get_seconds, getSeconds, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(get_stamp, getStamp, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(get_future_seconds, getFutureSeconds, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(get_future_milliseconds, getFutureMilliseconds, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(get_args, getArgs, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(get_name, get_name, "");
|
||||
PYCXX_ADD_NOARGS_METHOD(copy, copy, "Copies the operation into a new instance.");
|
||||
|
|
@ -169,15 +171,21 @@ Py::Object CyPy_Operation::setTo(const Py::Tuple& args) {
|
|||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object CyPy_Operation::setSeconds(const Py::Tuple& args) {
|
||||
Py::Object CyPy_Operation::setStamp(const Py::Tuple& args) {
|
||||
args.verify_length(1);
|
||||
m_value->setSeconds(verifyFloat(args.front()));
|
||||
m_value->setStamp(verifyLong(args.front()));
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object CyPy_Operation::setFutureSeconds(const Py::Tuple& args) {
|
||||
args.verify_length(1);
|
||||
m_value->setFutureSeconds(verifyFloat(args.front()));
|
||||
m_value->setFutureMilliseconds(verifyNumeric(args.front()) * 1000.0);
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object CyPy_Operation::setFutureMilliseconds(const Py::Tuple& args) {
|
||||
args.verify_length(1);
|
||||
m_value->setFutureMilliseconds(verifyLong(args.front()));
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
|
|
@ -234,12 +242,16 @@ Py::Object CyPy_Operation::getTo() {
|
|||
return Py::String(m_value->getTo());
|
||||
}
|
||||
|
||||
Py::Object CyPy_Operation::getSeconds() {
|
||||
return Py::Float(m_value->getSeconds());
|
||||
Py::Object CyPy_Operation::getStamp() {
|
||||
return Py::Long(m_value->getStamp());
|
||||
}
|
||||
|
||||
Py::Object CyPy_Operation::getFutureSeconds() {
|
||||
return Py::Float(m_value->getFutureSeconds());
|
||||
return Py::Float(m_value->getFutureMilliseconds() / 1000.0);
|
||||
}
|
||||
|
||||
Py::Object CyPy_Operation::getFutureMilliseconds() {
|
||||
return Py::Long(m_value->getFutureMilliseconds());
|
||||
}
|
||||
|
||||
Py::Object CyPy_Operation::getName() {
|
||||
|
|
@ -322,7 +334,9 @@ Py::Object CyPy_Operation::getattro(const Py::String& name) {
|
|||
if (nameStr == "parent") {
|
||||
return Py::String(m_value->getParent());
|
||||
}
|
||||
|
||||
if (nameStr == "future_milliseconds") {
|
||||
return getFutureMilliseconds();
|
||||
}
|
||||
if (nameStr == "future_seconds") {
|
||||
return getFutureSeconds();
|
||||
}
|
||||
|
|
@ -385,7 +399,11 @@ int CyPy_Operation::setattro(const Py::String& name, const Py::Object& attr) {
|
|||
|
||||
}
|
||||
if (nameStr == "future_seconds") {
|
||||
m_value->setFutureSeconds(verifyFloat(attr));
|
||||
m_value->setFutureMilliseconds(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<float>(verifyNumeric(attr))).count());
|
||||
return 0;
|
||||
}
|
||||
if (nameStr == "future_milliseconds") {
|
||||
m_value->setFutureMilliseconds(verifyLong(attr));
|
||||
return 0;
|
||||
}
|
||||
if (nameStr == "name") {
|
||||
|
|
|
|||
|
|
@ -71,14 +71,18 @@ protected:
|
|||
|
||||
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setTo);
|
||||
|
||||
Py::Object setSeconds(const Py::Tuple& args);
|
||||
Py::Object setStamp(const Py::Tuple& args);
|
||||
|
||||
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setSeconds);
|
||||
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setStamp);
|
||||
|
||||
Py::Object setFutureSeconds(const Py::Tuple& args);
|
||||
|
||||
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setFutureSeconds);
|
||||
|
||||
Py::Object setFutureMilliseconds(const Py::Tuple& args);
|
||||
|
||||
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setFutureMilliseconds);
|
||||
|
||||
Py::Object setName(const Py::Tuple& args);
|
||||
|
||||
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setName);
|
||||
|
|
@ -107,14 +111,18 @@ protected:
|
|||
|
||||
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getTo);
|
||||
|
||||
Py::Object getSeconds();
|
||||
Py::Object getStamp();
|
||||
|
||||
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getSeconds);
|
||||
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getStamp);
|
||||
|
||||
Py::Object getFutureSeconds();
|
||||
|
||||
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getFutureSeconds);
|
||||
|
||||
Py::Object getFutureMilliseconds();
|
||||
|
||||
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getFutureMilliseconds);
|
||||
|
||||
Py::Object getName();
|
||||
|
||||
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getName);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ HandlerResult ActionsProperty::TickOperation(LocatedEntity& owner, const Operati
|
|||
m_tickOutstanding = {};
|
||||
|
||||
//Remove any actions that are at end_time.
|
||||
auto now = op->getSeconds();
|
||||
auto now = std::chrono::milliseconds(op->getStamp());
|
||||
bool hadChanges = false;
|
||||
|
||||
for (auto I = m_data.begin(); I != m_data.end();) {
|
||||
|
|
@ -80,7 +80,7 @@ HandlerResult ActionsProperty::operation(LocatedEntity& entity, const Operation&
|
|||
}
|
||||
|
||||
void ActionsProperty::enqueueTickOp(const LocatedEntity& entity, OpVector& res) {
|
||||
std::optional<double> nearestExpiry;
|
||||
std::optional<std::chrono::milliseconds> nearestExpiry;
|
||||
for (auto& entry: m_data) {
|
||||
if (entry.second.endTime) {
|
||||
if (!nearestExpiry || *nearestExpiry > *entry.second.endTime) {
|
||||
|
|
@ -98,7 +98,7 @@ void ActionsProperty::enqueueTickOp(const LocatedEntity& entity, OpVector& res)
|
|||
tick->setArgs1(std::move(anon));
|
||||
tick->setTo(entity.getId());
|
||||
tick->setFrom(entity.getId());
|
||||
tick->setSeconds(*nearestExpiry);
|
||||
tick->setStamp(nearestExpiry->count());
|
||||
res.emplace_back(std::move(tick));
|
||||
|
||||
m_tickOutstanding = nearestExpiry;
|
||||
|
|
@ -115,9 +115,9 @@ ActionsProperty* ActionsProperty::copy() const {
|
|||
int ActionsProperty::get(Atlas::Message::Element& val) const {
|
||||
Atlas::Message::MapType map;
|
||||
for (auto& entry: m_data) {
|
||||
Atlas::Message::MapType mapEntry{{"start_time", entry.second.startTime}};
|
||||
Atlas::Message::MapType mapEntry{{"start_time", entry.second.startTime.count()}};
|
||||
if (entry.second.endTime) {
|
||||
mapEntry.emplace("end_time", *entry.second.endTime);
|
||||
mapEntry.emplace("end_time", entry.second.endTime->count());
|
||||
}
|
||||
|
||||
map.emplace(entry.first, std::move(mapEntry));
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "common/Property.h"
|
||||
#include "modules/Ref.h"
|
||||
#include <optional>
|
||||
#include <chrono>
|
||||
|
||||
class ActionsProperty : public PropertyBase {
|
||||
public:
|
||||
|
|
@ -31,8 +32,8 @@ public:
|
|||
|
||||
|
||||
struct Action {
|
||||
double startTime;
|
||||
std::optional<double> endTime;
|
||||
std::chrono::milliseconds startTime;
|
||||
std::optional<std::chrono::milliseconds> endTime;
|
||||
};
|
||||
|
||||
ActionsProperty();
|
||||
|
|
@ -59,7 +60,7 @@ protected:
|
|||
|
||||
std::map<std::string, Action> m_data;
|
||||
|
||||
std::optional<double> m_tickOutstanding;
|
||||
std::optional<std::chrono::milliseconds> m_tickOutstanding;
|
||||
|
||||
ActionsProperty(const ActionsProperty& rhs) = default;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ void AdminMind::externalOperation(const Operation& op, Link& link) {
|
|||
if (op->isDefaultTo()) {
|
||||
cy_debug_print("AdminMind handling op normally");
|
||||
ExternalMind::externalOperation(op, link);
|
||||
} else if (op->getTo() == getId() && op->isDefaultFutureSeconds()) {
|
||||
} else if (op->getTo() == getId() && op->isDefaultFutureMilliseconds()) {
|
||||
//Send directly to the entity, bypassing any normal Thought filtering
|
||||
cy_debug_print("Creator handling op ");
|
||||
OpVector lres;
|
||||
|
|
|
|||
|
|
@ -128,6 +128,10 @@ std::chrono::steady_clock::duration BaseWorld::getTime() const {
|
|||
return m_timeProviderFn();
|
||||
// return (std::chrono::steady_clock::now() - m_initTime);
|
||||
}
|
||||
std::chrono::milliseconds BaseWorld::getTimeAsMilliseconds() const {
|
||||
return duration_cast<std::chrono::milliseconds>(m_timeProviderFn());
|
||||
// return (std::chrono::steady_clock::now() - m_initTime);
|
||||
}
|
||||
|
||||
float BaseWorld::getTimeAsSeconds() const {
|
||||
return std::chrono::duration_cast<std::chrono::duration<float>>(getTime()).count();
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ public:
|
|||
/// \brief Read only accessor for the in-game time.
|
||||
std::chrono::steady_clock::duration getTime() const;
|
||||
|
||||
std::chrono::milliseconds getTimeAsMilliseconds() const;
|
||||
|
||||
float getTimeAsSeconds() const;
|
||||
|
||||
/// \brief Get the time the world has been running since the server started.
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ void ExternalMind::operation(const Operation& op, OpVector& res) {
|
|||
} else {
|
||||
//Only sent ops that inherit from "Info" to the client.
|
||||
if (op->instanceOf(Atlas::Objects::Operation::INFO_NO)) {
|
||||
op->setSeconds(BaseWorld::instance().getTimeAsSeconds());
|
||||
op->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
|
||||
m_link->send(op);
|
||||
}
|
||||
}
|
||||
|
|
@ -222,7 +222,7 @@ void ExternalMind::RelayOperation(const Operation& op, OpVector& res) {
|
|||
pruneOp->setFrom(m_entity->getId());
|
||||
pruneOp->setRefno(serialNo);
|
||||
//5 seconds should be more than enough.
|
||||
pruneOp->setFutureSeconds(5);
|
||||
pruneOp->setFutureMilliseconds(5'000);
|
||||
//Set id to direct it to this mind
|
||||
pruneOp->setId(getId());
|
||||
|
||||
|
|
|
|||
|
|
@ -639,9 +639,9 @@ void MindsProperty::mind2body(LocatedEntity& ent, const Operation& op, OpVector&
|
|||
spdlog::error("Operation \"{}\" from mind with TO set. {}", op->getParent(), ent.describeEntity());
|
||||
return;
|
||||
}
|
||||
if (!op->isDefaultFutureSeconds() && op->getClassNo() != Atlas::Objects::Operation::TICK_NO) {
|
||||
if (!op->isDefaultFutureMilliseconds() && op->getClassNo() != Atlas::Objects::Operation::TICK_NO) {
|
||||
spdlog::error("Operation \"{}\" from mind with "
|
||||
"FUTURE_SECONDS set. {}", op->getParent(), ent.describeEntity());
|
||||
"FUTURE_MILLISECONDS set. {}", op->getParent(), ent.describeEntity());
|
||||
}
|
||||
auto op_no = op->getClassNo();
|
||||
switch (op_no) {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ void ModeProperty::apply(LocatedEntity& entity) {
|
|||
|
||||
Atlas::Objects::Operation::Move moveOp;
|
||||
moveOp->setTo(entity.getId());
|
||||
moveOp->setSeconds(BaseWorld::instance().getTimeAsSeconds());
|
||||
moveOp->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
|
||||
moveOp->setArgs1(move_arg);
|
||||
entity.sendWorld(moveOp);
|
||||
}
|
||||
|
|
@ -106,7 +106,7 @@ void ModeProperty::apply(LocatedEntity& entity) {
|
|||
|
||||
Atlas::Objects::Operation::Move moveOp;
|
||||
moveOp->setTo(entity.getId());
|
||||
moveOp->setSeconds(BaseWorld::instance().getTimeAsSeconds());
|
||||
moveOp->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
|
||||
moveOp->setArgs1(move_arg);
|
||||
entity.sendWorld(moveOp);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@
|
|||
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
#include <fmt/format.h>
|
||||
|
|
@ -76,9 +75,12 @@ using Atlas::Objects::Operation::Disappearance;
|
|||
using Atlas::Objects::Operation::Move;
|
||||
|
||||
using Atlas::Objects::smart_dynamic_cast;
|
||||
|
||||
namespace {
|
||||
|
||||
float to_seconds(std::chrono::milliseconds duration) {
|
||||
return std::chrono::duration_cast<std::chrono::duration<float>>(duration).count();
|
||||
}
|
||||
|
||||
std::unique_ptr<btAxisSweep3> createVisibilityBroadphase(const LocatedEntity& entity, float scalingFactor) {
|
||||
auto bbox = ScaleProperty::scaledBbox(entity);
|
||||
if (!bbox.isValid()) {
|
||||
|
|
@ -199,7 +201,7 @@ const std::array<double, 10> VISIBILITY_DISTANCE_THRESHOLDS = {10.0, 20, 30, 50,
|
|||
* The amount of time between each tick, in seconds.
|
||||
* The simulation will happen at 60hz, but the tick size determines how often entities are processed and operations are sent.
|
||||
*/
|
||||
const double TICK_SIZE = 1.0 / 15.0;
|
||||
const std::chrono::milliseconds TICK_SIZE(66);
|
||||
|
||||
/**
|
||||
* The base size of the view sphere for a perceptive entity. Everything within this radius will be visible.
|
||||
|
|
@ -664,17 +666,17 @@ HandlerResult PhysicalDomain::operation(LocatedEntity& entity, const Operation&
|
|||
|
||||
HandlerResult PhysicalDomain::tick_handler(LocatedEntity& entity, const Operation& op, OpVector& res) {
|
||||
if (!op->getArgs().empty() && !op->getArgs().front()->isDefaultName() && op->getArgs().front()->getName() == "domain") {
|
||||
double timeNow = op->getSeconds();
|
||||
double tickSize = TICK_SIZE;
|
||||
auto timeNow = std::chrono::milliseconds(op->getStamp());
|
||||
auto tickSize = TICK_SIZE;
|
||||
Atlas::Message::Element elem;
|
||||
if (op->copyAttr("lastTick", elem) == 0 && elem.isFloat()) {
|
||||
tickSize = timeNow - elem.Float();
|
||||
if (op->copyAttr("lastTick", elem) == 0 && elem.isInt()) {
|
||||
tickSize = timeNow - std::chrono::milliseconds(elem.Int());
|
||||
}
|
||||
|
||||
tick(tickSize, res);
|
||||
auto tickOp = scheduleTick(entity);
|
||||
tickOp->setSeconds(timeNow + TICK_SIZE);
|
||||
tickOp->setAttr("lastTick", timeNow);
|
||||
tickOp->setStamp((timeNow + TICK_SIZE).count());
|
||||
tickOp->setAttr("lastTick", timeNow.count());
|
||||
res.emplace_back(std::move(tickOp));
|
||||
|
||||
return OPERATION_BLOCKED;
|
||||
|
|
@ -2175,7 +2177,7 @@ void PhysicalDomain::applyNewPositionForEntity(BulletEntry& entry, const WFMath:
|
|||
|
||||
}
|
||||
|
||||
void PhysicalDomain::applyDestination(double tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp) {
|
||||
void PhysicalDomain::applyDestination(std::chrono::milliseconds tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp) {
|
||||
bool hasDestination = destinationProp.data().isValid();
|
||||
bool hasPropel = propelProp && propelProp->data().isValid() && propelProp->data() != WFMath::Vector<3>::ZERO();
|
||||
|
||||
|
|
@ -2203,10 +2205,11 @@ void PhysicalDomain::applyDestination(double tickSize, BulletEntry& entry, const
|
|||
if (hasPropel) {
|
||||
propelSpeed = propelProp->data().mag();
|
||||
}
|
||||
auto ticksAsSeconds = to_seconds(tickSize);
|
||||
|
||||
//Check if we should lower our speed to arrive within the next tick.
|
||||
if (propelSpeed * speed * tickSize > distance) {
|
||||
propelSpeed = speed / (distance * tickSize);
|
||||
if (propelSpeed * speed * ticksAsSeconds > distance) {
|
||||
propelSpeed = speed / (distance * ticksAsSeconds);
|
||||
}
|
||||
|
||||
auto direction = btDestination - currentPos;
|
||||
|
|
@ -2454,7 +2457,7 @@ void PhysicalDomain::applyTransformInternal(BulletEntry& entry,
|
|||
rigidBody->activate();
|
||||
}
|
||||
}
|
||||
processMovedEntity(entry, 0);
|
||||
processMovedEntity(entry, std::chrono::milliseconds{0});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2613,15 +2616,15 @@ void PhysicalDomain::sendMoveSight(BulletEntry& entry, bool posChange, bool velo
|
|||
setOp->setArgs1(move_arg);
|
||||
setOp->setFrom(entity.getId());
|
||||
setOp->setTo(entity.getId());
|
||||
double seconds = BaseWorld::instance().getTimeAsSeconds();
|
||||
setOp->setSeconds(seconds);
|
||||
auto now = BaseWorld::instance().getTimeAsMilliseconds();
|
||||
setOp->setStamp(now.count());
|
||||
|
||||
for (BulletEntry* observer: entry.observingThis) {
|
||||
Sight s;
|
||||
s->setArgs1(setOp);
|
||||
s->setTo(observer->entity.getId());
|
||||
s->setFrom(entity.getId());
|
||||
s->setSeconds(seconds);
|
||||
s->setStamp(now.count());
|
||||
|
||||
entity.sendWorld(s);
|
||||
}
|
||||
|
|
@ -2629,7 +2632,7 @@ void PhysicalDomain::sendMoveSight(BulletEntry& entry, bool posChange, bool velo
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, double timeSinceLastUpdate) {
|
||||
void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, std::chrono::milliseconds timeSinceLastUpdate) {
|
||||
auto& pos = bulletEntry.positionProperty.data();
|
||||
auto& orientation = bulletEntry.orientationProperty.data();
|
||||
auto& velocity = bulletEntry.velocityProperty.data();
|
||||
|
|
@ -2651,7 +2654,7 @@ void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, double timeSin
|
|||
posChange = true;
|
||||
} else {
|
||||
if (lastSentLocation.velocity.isValid()) {
|
||||
auto projectedPosition = lastSentLocation.pos + (lastSentLocation.velocity * timeSinceLastUpdate);
|
||||
auto projectedPosition = lastSentLocation.pos + (lastSentLocation.velocity * to_seconds(timeSinceLastUpdate));
|
||||
if (WFMath::Distance(pos, projectedPosition) > 0.5) {
|
||||
posChange = true;
|
||||
}
|
||||
|
|
@ -2746,11 +2749,12 @@ void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, double timeSin
|
|||
updateTerrainMod(bulletEntry);
|
||||
}
|
||||
|
||||
void PhysicalDomain::tick(double tickSize, OpVector& res) {
|
||||
void PhysicalDomain::tick(std::chrono::milliseconds tickSize, OpVector& res) {
|
||||
// CProfileManager::Reset();
|
||||
// CProfileManager::Increment_Frame_Counter();
|
||||
rmt_ScopedCPUSample(PhysicalDomain_tick, 0)
|
||||
|
||||
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
/**
|
||||
* An entry of a projectile hitting another entry.
|
||||
|
|
@ -2788,6 +2792,7 @@ void PhysicalDomain::tick(double tickSize, OpVector& res) {
|
|||
if (simulationSpeedProp) {
|
||||
tickSize *= simulationSpeedProp->data();
|
||||
}
|
||||
auto tickSizeInSeconds = to_seconds(tickSize);
|
||||
|
||||
projectileCollisions.clear();
|
||||
|
||||
|
|
@ -2842,7 +2847,7 @@ void PhysicalDomain::tick(double tickSize, OpVector& res) {
|
|||
|
||||
|
||||
//Step simulations with 60 hz.
|
||||
m_dynamicsWorld->stepSimulation((float) tickSize, static_cast<int>(60 * tickSize));
|
||||
m_dynamicsWorld->stepSimulation(tickSizeInSeconds, static_cast<int>(60 * tickSizeInSeconds));
|
||||
auto interim = std::chrono::steady_clock::now() - start;
|
||||
|
||||
//CProfileManager::dumpAll();
|
||||
|
|
@ -2949,20 +2954,20 @@ void PhysicalDomain::tick(double tickSize, OpVector& res) {
|
|||
processDirtyTerrainAreas();
|
||||
|
||||
auto duration = std::chrono::steady_clock::now() - start;
|
||||
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
|
||||
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(duration);
|
||||
if (debug_flag) {
|
||||
spdlog::log(microseconds > 3000 ? spdlog::level::warn : spdlog::level::info,
|
||||
spdlog::log(microseconds.count() > 3000 ? spdlog::level::warn : spdlog::level::info,
|
||||
"Physics took {} μs (just stepSimulation {} μs, visibility {} μs, tick size {} μs, visibility queue: {}, postTick: {} μs, moving count: {}).",
|
||||
microseconds,
|
||||
microseconds.count(),
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(interim).count(),
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(visDuration).count(),
|
||||
static_cast<long>(tickSize * 1000000),
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(tickSize).count(),
|
||||
m_visibilityRecalculateQueue.size(),
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(postDuration).count(),
|
||||
movingSize
|
||||
);
|
||||
}
|
||||
s_processTimeUs += microseconds;
|
||||
s_processTimeUs += microseconds.count();
|
||||
}
|
||||
|
||||
void PhysicalDomain::processWaterBodies() {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <array>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <chrono>
|
||||
|
||||
namespace Mercator {
|
||||
class Segment;
|
||||
|
|
@ -104,7 +105,7 @@ public:
|
|||
|
||||
HandlerResult operation(LocatedEntity& e, const Operation& op, OpVector& res) override;
|
||||
|
||||
void tick(double t, OpVector& res);
|
||||
void tick(std::chrono::milliseconds t, OpVector& res);
|
||||
|
||||
std::vector<CollisionEntry> queryCollision(const WFMath::Ball<3>& sphere) const override;
|
||||
|
||||
|
|
@ -451,7 +452,7 @@ protected:
|
|||
|
||||
void sendMoveSight(BulletEntry& bulletEntry, bool posChange, bool velocityChange, bool orientationChange, bool angularChange, bool modeChanged);
|
||||
|
||||
void processMovedEntity(BulletEntry& bulletEntry, double timeSinceLastUpdate);
|
||||
void processMovedEntity(BulletEntry& bulletEntry, std::chrono::milliseconds timeSinceLastUpdate);
|
||||
|
||||
void updateVisibilityOfDirtyEntities(OpVector& res);
|
||||
|
||||
|
|
@ -467,7 +468,7 @@ protected:
|
|||
|
||||
void processDirtyTerrainAreas();
|
||||
|
||||
void applyDestination(double tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp);
|
||||
void applyDestination(std::chrono::milliseconds tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp);
|
||||
|
||||
void applyPropel(BulletEntry& entry, btVector3 propel);
|
||||
|
||||
|
|
@ -479,8 +480,9 @@ protected:
|
|||
void processWaterBodies();
|
||||
|
||||
std::shared_ptr<btCollisionShape> createCollisionShapeForEntry(LocatedEntity& entity,
|
||||
const WFMath::AxisBox<3>& bbox, float mass,
|
||||
btVector3& centerOfMassOffse);
|
||||
const WFMath::AxisBox<3>& bbox,
|
||||
float mass,
|
||||
btVector3& centerOfMassOffset);
|
||||
|
||||
/**
|
||||
* Transform any entities that are resting on the supplied entity.
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ Task::Task(UsageInstance usageInstance, Py::Object script) :
|
|||
m_rate(-1),
|
||||
m_start_time(-1),
|
||||
m_script(std::move(script)),
|
||||
m_tick_interval(1.0),
|
||||
m_tick_interval(1'000),
|
||||
m_usageInstance(std::move(usageInstance)) {
|
||||
}
|
||||
|
||||
|
|
@ -80,18 +80,18 @@ Operation Task::nextTick(const std::string& id, const Operation& op) {
|
|||
tick->setArgs1(tick_arg);
|
||||
tick->setTo(m_usageInstance.actor->getId());
|
||||
//Default to once per second.
|
||||
double futureSeconds = 1.0;
|
||||
std::chrono::milliseconds futureMilliseconds{1'000};
|
||||
if (m_tick_interval) {
|
||||
futureSeconds = *m_tick_interval;
|
||||
futureMilliseconds = *m_tick_interval;
|
||||
} else if (m_duration) {
|
||||
futureSeconds = *m_duration;
|
||||
futureMilliseconds = *m_duration;
|
||||
}
|
||||
|
||||
//If there's a duration, adjust the tick interval so it matches the duration end
|
||||
if (m_duration) {
|
||||
futureSeconds = std::min(futureSeconds, *m_duration - (op->getSeconds() - m_start_time));
|
||||
futureMilliseconds = std::min(futureMilliseconds, *m_duration - (std::chrono::milliseconds(op->getStamp()) - m_start_time));
|
||||
}
|
||||
tick->setFutureSeconds(futureSeconds);
|
||||
tick->setFutureMilliseconds(futureMilliseconds.count());
|
||||
|
||||
return tick;
|
||||
}
|
||||
|
|
@ -114,7 +114,7 @@ void Task::setAttr(const std::string& attr,
|
|||
}
|
||||
|
||||
void Task::initTask(const std::string& id, OpVector& res) {
|
||||
m_start_time = m_usageInstance.op->getSeconds();
|
||||
m_start_time = std::chrono::milliseconds{m_usageInstance.op->getStamp()};
|
||||
if (m_script.isNull()) {
|
||||
spdlog::warn("Task script failed");
|
||||
irrelevant();
|
||||
|
|
@ -132,8 +132,8 @@ void Task::initTask(const std::string& id, OpVector& res) {
|
|||
bool Task::tick(const std::string& id, const Operation& op, OpVector& res) {
|
||||
bool hadChange = false;
|
||||
if (m_duration) {
|
||||
auto elapsed = (op->getSeconds() - m_start_time);
|
||||
auto newProgress = std::min(1.0, elapsed / *m_duration);
|
||||
auto elapsed = (std::chrono::milliseconds(op->getStamp()) - m_start_time);
|
||||
auto newProgress = std::min(1.0, (double) elapsed.count() / (double) m_duration->count());
|
||||
if (newProgress != m_progress) {
|
||||
m_progress = newProgress;
|
||||
hadChange = true;
|
||||
|
|
@ -201,7 +201,7 @@ void Task::startAction(std::string actionName, OpVector& res) {
|
|||
}
|
||||
m_action = actionName;
|
||||
auto& actionsProp = m_usageInstance.actor->requirePropertyClassFixed<ActionsProperty>();
|
||||
actionsProp.addAction(*m_usageInstance.actor, res, actionName, {BaseWorld::instance().getTimeAsSeconds()});
|
||||
actionsProp.addAction(*m_usageInstance.actor, res, actionName, {BaseWorld::instance().getTimeAsMilliseconds()});
|
||||
}
|
||||
|
||||
void Task::stopAction(OpVector& res) {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ protected:
|
|||
/// \brief Rate of progress towards task completion
|
||||
double m_rate;
|
||||
|
||||
double m_start_time;
|
||||
std::chrono::milliseconds m_start_time;
|
||||
|
||||
/// \brief Additional task attributes
|
||||
Atlas::Message::MapType m_attr;
|
||||
|
|
@ -83,9 +83,9 @@ public:
|
|||
|
||||
static std::function<Py::Object(const std::map<std::string, std::vector<UsageParameter::UsageArg>>& args)> argsCreator;
|
||||
|
||||
std::optional<double> m_duration;
|
||||
std::optional<std::chrono::milliseconds> m_duration;
|
||||
|
||||
std::optional<double> m_tick_interval;
|
||||
std::optional<std::chrono::milliseconds> m_tick_interval;
|
||||
|
||||
UsageInstance m_usageInstance;
|
||||
|
||||
|
|
@ -94,9 +94,13 @@ public:
|
|||
|
||||
~Task() override;
|
||||
|
||||
void callUsageScriptFunction(const std::string& function, const std::map<std::string, std::vector<UsageParameter::UsageArg>>& args, OpVector& res);
|
||||
void callUsageScriptFunction(const std::string& function,
|
||||
const std::map<std::string, std::vector<UsageParameter::UsageArg>>& args,
|
||||
OpVector& res);
|
||||
|
||||
void callScriptFunction(const std::string& function, const Py::Tuple& args, OpVector& res);
|
||||
void callScriptFunction(const std::string& function,
|
||||
const Py::Tuple& args,
|
||||
OpVector& res);
|
||||
|
||||
/// \brief Flag this task as obsolete
|
||||
void irrelevant();
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ int TasksProperty::get(Atlas::Message::Element& val) const {
|
|||
taskMap.emplace("progress", progress);
|
||||
}
|
||||
if (task->m_duration) {
|
||||
taskMap.emplace("rate", 1.0f / *task->m_duration);
|
||||
taskMap.emplace("rate", 1.0f / std::chrono::duration_cast<std::chrono::duration<float>>(*task->m_duration).count());
|
||||
}
|
||||
if (!task->usages().empty()) {
|
||||
ListType usagesList;
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ void Thing::MoveOperation(const Operation& op, OpVector& res) {
|
|||
error(op, "Move has no argument", res, getId());
|
||||
return;
|
||||
}
|
||||
RootEntity ent = smart_dynamic_cast<RootEntity>(args.front());
|
||||
auto ent = smart_dynamic_cast<RootEntity>(args.front());
|
||||
if (!ent.isValid() || ent->isDefaultId()) {
|
||||
error(op, "Move op arg is malformed", res, getId());
|
||||
return;
|
||||
|
|
@ -354,7 +354,7 @@ void Thing::updateProperties(const Operation& op, OpVector& res) {
|
|||
Set set;
|
||||
set->setTo(getId());
|
||||
set->setFrom(getId());
|
||||
set->setSeconds(op->getSeconds());
|
||||
set->setStamp(op->getStamp());
|
||||
set->setArgs1(set_arg);
|
||||
|
||||
Sight sight;
|
||||
|
|
@ -368,7 +368,7 @@ void Thing::updateProperties(const Operation& op, OpVector& res) {
|
|||
Set set;
|
||||
set->setTo(getId());
|
||||
set->setFrom(getId());
|
||||
set->setSeconds(op->getSeconds());
|
||||
set->setStamp(op->getStamp());
|
||||
set->setArgs1(set_arg_protected);
|
||||
|
||||
Sight sight;
|
||||
|
|
@ -382,7 +382,7 @@ void Thing::updateProperties(const Operation& op, OpVector& res) {
|
|||
Set set;
|
||||
set->setTo(getId());
|
||||
set->setFrom(getId());
|
||||
set->setSeconds(op->getSeconds());
|
||||
set->setStamp(op->getStamp());
|
||||
set->setArgs1(set_arg_private);
|
||||
|
||||
Sight sight;
|
||||
|
|
@ -606,7 +606,7 @@ void Thing::moveOurselves(const Operation& op, const RootEntity& ent, OpVector&
|
|||
setAttrValue("_propel", attr_propel);
|
||||
}
|
||||
|
||||
double current_time = BaseWorld::instance().getTimeAsSeconds();
|
||||
auto current_time = BaseWorld::instance().getTimeAsMilliseconds();
|
||||
|
||||
//We can only move if there's a domain
|
||||
Domain* domain = nullptr;
|
||||
|
|
@ -616,7 +616,7 @@ void Thing::moveOurselves(const Operation& op, const RootEntity& ent, OpVector&
|
|||
|
||||
//Send a Sight of the Move to any current observers. Do this before we might alter location.
|
||||
Operation m = op.copy();
|
||||
RootEntity marg = smart_dynamic_cast<RootEntity>(m->getArgs().front());
|
||||
auto marg = smart_dynamic_cast<RootEntity>(m->getArgs().front());
|
||||
assert(marg.isValid());
|
||||
// m_location.addToEntity(marg);
|
||||
// {
|
||||
|
|
@ -631,8 +631,8 @@ void Thing::moveOurselves(const Operation& op, const RootEntity& ent, OpVector&
|
|||
// }
|
||||
// }
|
||||
|
||||
if (!m->hasAttrFlag(Atlas::Objects::Operation::SECONDS_FLAG)) {
|
||||
m->setSeconds(current_time);
|
||||
if (!m->hasAttrFlag(Atlas::Objects::STAMP_FLAG)) {
|
||||
m->setStamp(current_time.count());
|
||||
}
|
||||
|
||||
Sight s;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ void TransientProperty::apply(LocatedEntity& ent) {
|
|||
|
||||
Delete deleteOp;
|
||||
deleteOp->setTo(ent.getId());
|
||||
deleteOp->setFutureSeconds(m_data);
|
||||
deleteOp->setFutureMilliseconds(static_cast<std::int64_t >(m_data * 1'000.0));
|
||||
|
||||
Anonymous entity_arg;
|
||||
entity_arg->setId(ent.getId());
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ HandlerResult UsagesProperty::use_handler(LocatedEntity& e,
|
|||
}
|
||||
rop->setFrom(actor->getId());
|
||||
rop->setTo(e.getId());
|
||||
rop->setSeconds(op->getSeconds());
|
||||
rop->setStamp(op->getStamp());
|
||||
|
||||
if (argOp->getArgs().empty()) {
|
||||
actor->error(op, "Use arg op has no arguments; one expected.", res, actor->getId());
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ void World::sendRelayToEntity(const LocatedEntity& to, const Operation& op, sigc
|
|||
pruneOp->setTo(getId());
|
||||
pruneOp->setFrom(getId());
|
||||
pruneOp->setRefno(serialNo);
|
||||
pruneOp->setFutureSeconds(5);
|
||||
pruneOp->setFutureMilliseconds(5'000);
|
||||
sendWorld(pruneOp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -182,12 +182,14 @@ void WorldRouter::resumeWorld() {
|
|||
}
|
||||
|
||||
void WorldRouter::resolveDispatchTimeForOp(Atlas::Objects::Operation::RootOperationData& op) {
|
||||
if (!op.isDefaultFutureSeconds()) {
|
||||
double t = getTimeAsSeconds() + (op.getFutureSeconds() * consts::time_multiplier);
|
||||
op.setSeconds(t);
|
||||
op.removeAttrFlag(Atlas::Objects::Operation::FUTURE_SECONDS_FLAG);
|
||||
} else if (op.isDefaultSeconds()) {
|
||||
op.setSeconds(getTimeAsSeconds());
|
||||
if (!op.isDefaultFutureMilliseconds()) {
|
||||
std::chrono::milliseconds future((int64_t) ((double) op.getFutureMilliseconds() * consts::time_multiplier));
|
||||
|
||||
auto t = getTimeAsMilliseconds() + future;
|
||||
op.setStamp(t.count());
|
||||
op.removeAttrFlag(Atlas::Objects::Operation::FUTURE_MILLISECONDS_FLAG);
|
||||
} else if (op.isDefaultStamp()) {
|
||||
op.setStamp(getTimeAsMilliseconds().count());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -244,13 +246,13 @@ void WorldRouter::deliverTo(const Operation& op, Ref<LocatedEntity> ent) {
|
|||
//(to be resent when the world is resumed) and not process it now.
|
||||
if (m_isSuspended) {
|
||||
if (op->getClassNo() == Atlas::Objects::Operation::TICK_NO) {
|
||||
m_suspendedQueue.push(OpQueEntry<LocatedEntity>(op, std::move(ent), m_suspendedQueue.size()));
|
||||
m_suspendedQueue.emplace(op, std::move(ent), m_suspendedQueue.size());
|
||||
return;
|
||||
}
|
||||
}
|
||||
//Set the time of when this op is dispatched. That way, other components in the system can
|
||||
//always use the seconds set on the op to know the current time.
|
||||
op->setSeconds(std::chrono::duration_cast<std::chrono::duration<double>>(getTime()).count());
|
||||
op->setStamp(getTimeAsMilliseconds().count());
|
||||
|
||||
OpVector res;
|
||||
cy_debug_print("WorldRouter::deliverTo begin {"
|
||||
|
|
|
|||
|
|
@ -177,8 +177,9 @@ Py::Object CyPy_Entity::start_action(const Ref<Entity>& entity, const Py::Tuple&
|
|||
args.verify_length(2);
|
||||
|
||||
auto& actionsProp = entity->requirePropertyClassFixed<ActionsProperty>();
|
||||
auto duration = verifyFloat(args[1]);
|
||||
auto startTime = BaseWorld::instance().getTimeAsSeconds();
|
||||
//Use seconds in the Python code
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<float>(verifyFloat(args[1])));
|
||||
auto startTime = BaseWorld::instance().getTimeAsMilliseconds();
|
||||
actionsProp.addAction(*entity, res, verifyString(args[0]), {startTime, startTime + duration});
|
||||
|
||||
return CyPy_Oplist::wrap(std::move(res));
|
||||
|
|
|
|||
|
|
@ -173,13 +173,15 @@ Py::Object CyPy_Task::getattro(const Py::String& name) {
|
|||
if (!m_value->m_duration) {
|
||||
return Py::None();
|
||||
}
|
||||
return Py::Float(*m_value->m_duration);
|
||||
//Use seconds in the Python code
|
||||
return Py::Float(std::chrono::duration_cast<std::chrono::duration<float>>(*m_value->m_duration).count());
|
||||
}
|
||||
if (nameStr == "tick_interval") {
|
||||
if (!m_value->m_tick_interval) {
|
||||
return Py::None();
|
||||
}
|
||||
return Py::Float(*m_value->m_tick_interval);
|
||||
//Use seconds in the Python code
|
||||
return Py::Float(std::chrono::duration_cast<std::chrono::duration<float>>(*m_value->m_tick_interval).count());
|
||||
}
|
||||
if (nameStr == "name") {
|
||||
return Py::String(m_value->name());
|
||||
|
|
@ -249,11 +251,13 @@ int CyPy_Task::setattro(const Py::String& name, const Py::Object& attr) {
|
|||
return 0;
|
||||
}
|
||||
if (nameStr == "duration") {
|
||||
m_value->m_duration = verifyNumeric(attr);
|
||||
//Use seconds in the Python code
|
||||
m_value->m_duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<float>(verifyNumeric(attr)));
|
||||
return 0;
|
||||
}
|
||||
if (nameStr == "tick_interval") {
|
||||
m_value->m_tick_interval = verifyNumeric(attr);
|
||||
//Use seconds in the Python code
|
||||
m_value->m_tick_interval = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<float>(verifyNumeric(attr)));
|
||||
return 0;
|
||||
}
|
||||
if (nameStr == "name") {
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ void Account::sendUpdateToClient() {
|
|||
Anonymous sight_arg;
|
||||
addToEntity(sight_arg);
|
||||
s->setArgs1(sight_arg);
|
||||
s->setSeconds(BaseWorld::instance().getTimeAsSeconds());
|
||||
s->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
|
||||
m_connection->send(s);
|
||||
}
|
||||
}
|
||||
|
|
@ -222,7 +222,7 @@ void Account::LogoutOperation(const Operation& op, OpVector& res) {
|
|||
}
|
||||
info->setFrom(getId());
|
||||
info->setTo(getId());
|
||||
info->setSeconds(BaseWorld::instance().getTimeAsSeconds());
|
||||
info->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
|
||||
m_connection->send(info);
|
||||
|
||||
return;
|
||||
|
|
@ -238,7 +238,7 @@ void Account::LogoutOperation(const Operation& op, OpVector& res) {
|
|||
}
|
||||
info->setFrom(getId());
|
||||
info->setTo(getId());
|
||||
info->setSeconds(BaseWorld::instance().getTimeAsSeconds());
|
||||
info->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
|
||||
m_connection->send(info);
|
||||
m_connection->disconnect();
|
||||
}
|
||||
|
|
@ -350,7 +350,7 @@ void Account::externalOperation(const Operation& op, Link& link) {
|
|||
replyOp->setRefno(op->getSerialno());
|
||||
}
|
||||
}
|
||||
replyOp->setSeconds(BaseWorld::instance().getTimeAsSeconds());
|
||||
replyOp->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
|
||||
}
|
||||
m_connection->send(res);
|
||||
}
|
||||
|
|
@ -395,7 +395,7 @@ void Account::processExternalOperation(const Operation& op, OpVector& res) {
|
|||
|
||||
void Account::operation(const Operation& op, OpVector& res) {
|
||||
if (m_connection) {
|
||||
op->setSeconds(BaseWorld::instance().getTimeAsSeconds());
|
||||
op->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
|
||||
m_connection->send(op);
|
||||
}
|
||||
}
|
||||
|
|
@ -452,7 +452,7 @@ void Account::ImaginaryOperation(const Operation& op, OpVector& res) {
|
|||
if (!op->isDefaultSerialno()) {
|
||||
s->setRefno(op->getSerialno());
|
||||
}
|
||||
RootEntity arg = smart_dynamic_cast<RootEntity>(args.front());
|
||||
auto arg = smart_dynamic_cast<RootEntity>(args.front());
|
||||
|
||||
if (!arg.isValid()) {
|
||||
error(op, "Imaginary arg is malformed", res, getId());
|
||||
|
|
@ -476,7 +476,7 @@ void Account::TalkOperation(const Operation& op, OpVector& res) {
|
|||
return;
|
||||
}
|
||||
|
||||
RootEntity arg = smart_dynamic_cast<RootEntity>(args.front());
|
||||
auto arg = smart_dynamic_cast<RootEntity>(args.front());
|
||||
|
||||
if (!arg.isValid()) {
|
||||
error(op, "Talk arg is malformed", res, getId());
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
|
||||
#include <Atlas/Objects/Operation.h>
|
||||
#include <Atlas/Objects/Entity.h>
|
||||
#include "server/SystemAccount.h"
|
||||
#include "Connection.h"
|
||||
#include "ServerRouting.h"
|
||||
|
|
@ -33,7 +34,7 @@ SystemAccount::SystemAccount(Connection* conn,
|
|||
SystemAccount::~SystemAccount() = default;
|
||||
|
||||
const char* SystemAccount::getType() const {
|
||||
return "sys";
|
||||
return Atlas::Objects::Entity::SystemAccountData::default_parent;
|
||||
}
|
||||
|
||||
bool SystemAccount::isPersisted() const {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ std::unique_ptr<Account> TrustedConnection::newAccount(const std::string& type,
|
|||
const std::string& hash,
|
||||
RouterId id)
|
||||
{
|
||||
if (type == "sys") {
|
||||
if (type == "system_account") {
|
||||
return std::make_unique<SystemAccount>(this, username, hash, id);
|
||||
} else if (type == "admin") {
|
||||
return std::make_unique<Admin>(this, username, hash, id);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ void Flusher::operation(const Operation& op, OpVector& res) {
|
|||
res.push_back(d);
|
||||
|
||||
// Send a tick for a short time in the future so that
|
||||
// we can look again once this entity is definitly gone.
|
||||
// we can look again once this entity is definitely gone.
|
||||
Tick t;
|
||||
|
||||
Anonymous tick_arg;
|
||||
|
|
@ -127,7 +127,7 @@ void Flusher::operation(const Operation& op, OpVector& res) {
|
|||
|
||||
flush_context->setFromContext(t);
|
||||
t->setTo(t->getFrom());
|
||||
t->setFutureSeconds(0.1);
|
||||
t->setStamp(100);
|
||||
t->setArgs1(tick_arg);
|
||||
|
||||
res.push_back(t);
|
||||
|
|
|
|||
|
|
@ -480,7 +480,7 @@ int Interactive::select(bool rewrite_prompt) {
|
|||
|
||||
void Interactive::updatePrompt() {
|
||||
std::string designation(">");
|
||||
if (m_accountType == "admin" || m_accountType == "sys") {
|
||||
if (m_accountType == "admin" || m_accountType == "system_account") {
|
||||
designation = "#";
|
||||
} else {
|
||||
designation = "$";
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ int main(int argc, char** argv) {
|
|||
spdlog::debug("Attempting local connection");
|
||||
if (bridge.connectLocal(localSocket) == 0) {
|
||||
bridge.setup();
|
||||
if (bridge.create("sys",
|
||||
if (bridge.create("system_account",
|
||||
create_session_username(),
|
||||
fmt::format("{}{}", ::rand(), ::rand())) != 0) {
|
||||
bridge.getLogin();
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
std::cout << "Attempting local connection" << std::endl;
|
||||
if (bridge.connectLocal(localSocket) == 0) {
|
||||
if (bridge.create("sys", create_session_username(), fmt::format("{}{}", ::rand(), ::rand())) != 0) {
|
||||
if (bridge.create("system_account", create_session_username(), fmt::format("{}{}", ::rand(), ::rand())) != 0) {
|
||||
std::cerr << "Could not create sys account." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
spdlog::debug("Attempting local connection");
|
||||
if (bridge.connectLocal(localSocket) == 0) {
|
||||
if (bridge.create("sys", create_session_username(),
|
||||
if (bridge.create("system_account", create_session_username(),
|
||||
fmt::format("{}{}", ::rand(), ::rand())) != 0) {
|
||||
spdlog::error("Could not create sys account.");
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -68,19 +68,19 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(1.0);
|
||||
op->setStamp(1);
|
||||
op->setRefno(1);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(2.0);
|
||||
op->setStamp(2);
|
||||
op->setRefno(2);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(3.0);
|
||||
op->setStamp(3);
|
||||
op->setRefno(3);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
|
|
@ -95,19 +95,19 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
//Now try with same seconds set.
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(1.0);
|
||||
op->setStamp(1);
|
||||
op->setRefno(1);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(1.0);
|
||||
op->setStamp(1);
|
||||
op->setRefno(2);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(1.0);
|
||||
op->setStamp(1);
|
||||
op->setRefno(3);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
|
|
@ -123,17 +123,17 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
//Now try with same seconds set.
|
||||
{
|
||||
Atlas::Objects::Operation::Update op;
|
||||
op->setSeconds(1.0);
|
||||
op->setStamp(1);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Atlas::Objects::Operation::Appearance op;
|
||||
op->setSeconds(1.0);
|
||||
op->setStamp(1);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Atlas::Objects::Operation::Update op;
|
||||
op->setSeconds(1.0);
|
||||
op->setStamp(1);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
|
||||
|
|
@ -146,32 +146,32 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(2.0);
|
||||
op->setStamp(2);
|
||||
op->setRefno(2);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(3.0);
|
||||
op->setStamp(3);
|
||||
op->setRefno(3);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Operation op;
|
||||
op->setSeconds(1.0);
|
||||
op->setStamp(1);
|
||||
op->setRefno(1);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Operation op;
|
||||
op->setRefno(4);
|
||||
op->setSeconds(0);
|
||||
op->setStamp(0);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
{
|
||||
Operation op;
|
||||
op->setRefno(5);
|
||||
op->setSeconds(0);
|
||||
op->setStamp(0);
|
||||
dispatcher.addOperationToQueue(op, entity);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include "../TestBase.h"
|
||||
#include "../TestWorld.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace WFMath {
|
||||
template<int dim>
|
||||
auto format_as(const WFMath::Point<dim>& f) {
|
||||
|
|
@ -148,22 +150,22 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
|
||||
|
||||
//Test with both the location, as well as the entity itself.
|
||||
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0, {EntityLocation(otherEntity)}).position);
|
||||
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0ms, {EntityLocation(otherEntity)}).position);
|
||||
|
||||
//Location should be null if we only specify a point
|
||||
ASSERT_EQUAL(0, steering.resolvePosition(0, {EntityLocation{otherEntity}}).radius)
|
||||
ASSERT_EQUAL(0, steering.resolvePosition(0ms, {EntityLocation{otherEntity}}).radius)
|
||||
//Location should be set if we specify a new Location with a parent (even if it's with an invalid position).
|
||||
// ASSERT_EQUAL(otherEntity->m_location, *steering.resolvePosition(0, {EntityLocation(otherEntity)}).location);
|
||||
|
||||
// ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0, {otherChildEntity->m_location}).position);
|
||||
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0, {EntityLocation(otherChildEntity)}).position);
|
||||
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0ms, {EntityLocation(otherChildEntity)}).position);
|
||||
|
||||
//The resolved location of "otherChildEntity" should be it's parent's location.
|
||||
//ASSERT_EQUAL(otherEntity->m_location, *steering.resolvePosition(0, {otherChildEntity->m_location}).location);
|
||||
//ASSERT_EQUAL(otherEntity->m_location, *steering.resolvePosition(0, {EntityLocation(otherChildEntity)}).location);
|
||||
|
||||
// ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.resolvePosition(0, {avatarChildEntity->m_location}).position);
|
||||
ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.resolvePosition(0, {EntityLocation(avatarChildEntity)}).position);
|
||||
ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.resolvePosition(0ms, {EntityLocation(avatarChildEntity)}).position);
|
||||
|
||||
// ASSERT_EQUAL(avatarEntity->m_location, *steering.resolvePosition(0, {avatarChildEntity->m_location}).location);
|
||||
// ASSERT_EQUAL(avatarEntity->m_location, *steering.resolvePosition(0, {EntityLocation(avatarChildEntity)}
|
||||
|
|
@ -225,22 +227,22 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
awareness.addEntity(*avatarEntity, *otherEntity, true);
|
||||
|
||||
steering.startSteering();
|
||||
steering.setDestination({EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE, 0}, 0);
|
||||
steering.setDestination({EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE, 0}, 0ms);
|
||||
//Set to ten meters per second, so it should take one second to reach the other entity.
|
||||
steering.setDesiredSpeed(10);
|
||||
rebuildAllTilesFn();
|
||||
|
||||
auto result = steering.update(0);
|
||||
auto result = steering.update(0ms);
|
||||
//Since it's a straight line we can move directly to destination.
|
||||
ASSERT_TRUE(result.destination.isValid());
|
||||
ASSERT_EQUAL(result.destination, otherEntity->requirePropertyClassFixed<PositionProperty>().data());
|
||||
ASSERT_FUZZY_EQUAL(1.0, *result.timeToNextWaypoint, epsilon);
|
||||
ASSERT_EQUAL(1000, result.timeToNextWaypoint->count());
|
||||
ASSERT_EQUAL(WFMath::Vector<3>(10, 0, 0), result.direction);
|
||||
|
||||
//Set location so that the entity should arrive in one second
|
||||
avatarEntity->requirePropertyClassFixed<VelocityProperty>().data() = {10, 0, 0};
|
||||
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
|
||||
result = steering.update(1.0);
|
||||
result = steering.update(1000ms);
|
||||
ASSERT_FALSE(result.destination.isValid());
|
||||
ASSERT_FALSE(result.timeToNextWaypoint);
|
||||
ASSERT_TRUE(result.direction.isValid());
|
||||
|
|
@ -249,7 +251,7 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
//Add the obstacle entity and make sure that we now divert around it.
|
||||
awareness.addEntity(*avatarEntity, *obstacleEntity, false);
|
||||
rebuildAllTilesFn();
|
||||
result = steering.update(0);
|
||||
result = steering.update(0ms);
|
||||
//We can't move directly to destination this time
|
||||
ASSERT_FALSE(result.destination.isValid());
|
||||
|
||||
|
|
@ -311,37 +313,37 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
rebuildAllTilesFn();
|
||||
|
||||
|
||||
ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.getCurrentAvatarPosition(0));
|
||||
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.getCurrentAvatarPosition(1.0));
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.getCurrentAvatarPosition(0ms));
|
||||
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.getCurrentAvatarPosition(1000ms));
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1.0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1000ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER), epsilon);
|
||||
//Overshoot the target
|
||||
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(3.0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(3000ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(0, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1.0, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(3.0, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(0ms, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1000ms, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(3000ms, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
steering.setDestination(
|
||||
{EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, 0.5}, 0);
|
||||
{EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, 0.5}, 0ms);
|
||||
rebuildAllTilesFn();
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0));
|
||||
ASSERT_TRUE(steering.isAtCurrentDestination(1.0));
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms));
|
||||
ASSERT_TRUE(steering.isAtCurrentDestination(1000ms));
|
||||
|
||||
//Set velocity of the other entity too
|
||||
otherEntity->requirePropertyClassFixed<VelocityProperty>().data() = {10, 0, 0};
|
||||
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
|
||||
//This should be true, since we supplied a fixed destination
|
||||
ASSERT_TRUE(steering.isAtCurrentDestination(1.0));
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1.0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_TRUE(steering.isAtCurrentDestination(1000ms));
|
||||
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1000ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER), epsilon);
|
||||
|
||||
steering.setDestination({EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, 0.5}, 0);
|
||||
steering.setDestination({EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, 0.5}, 0ms);
|
||||
rebuildAllTilesFn();
|
||||
//This should be false since we're now tracking the other entity (and thus take velocity into account).
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(1.0));
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(1.0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(1000ms));
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(1000ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -374,50 +376,50 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
awareness.addEntity(*avatarEntity, *otherEntity, false);
|
||||
steering.setAwareness(&awareness);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER), epsilon);
|
||||
//Also test with setting the destination to the entity itself
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(10.0 - otherHorizontalRadius, *steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::EDGE), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(10.0 - otherHorizontalRadius, *steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::EDGE), epsilon);
|
||||
//If we specify the destination as a point the "EDGE" measurement on the destination won't have any effect.
|
||||
ASSERT_FUZZY_EQUAL(10.0 - avatarHorizontalRadius,
|
||||
*steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
*steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
Steering::MeasureType::EDGE), epsilon);
|
||||
//But if we specify the destination as the entity itself the "EDGE" measurement on the destination will have an effect.
|
||||
ASSERT_FUZZY_EQUAL(10.0 - otherHorizontalRadius - avatarHorizontalRadius,
|
||||
*steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
|
||||
*steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
|
||||
|
||||
|
||||
//Move other away
|
||||
otherEntity->requirePropertyClassFixed<PositionProperty>().data() = {20, 0, 0};
|
||||
otherEntity->m_lastUpdated++;
|
||||
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
|
||||
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
|
||||
//Also test with setting the destination to the entity itself
|
||||
ASSERT_FUZZY_EQUAL(20.0 - otherHorizontalRadius, *steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::EDGE), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(20.0 - otherHorizontalRadius, *steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::EDGE), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(20.0 - otherHorizontalRadius - avatarHorizontalRadius,
|
||||
*steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
|
||||
*steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
|
||||
//Move avatar closer
|
||||
avatarEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
|
||||
avatarEntity->m_lastUpdated++;
|
||||
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER), epsilon);
|
||||
|
||||
//Test invalid positions
|
||||
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER))
|
||||
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
Steering::MeasureType::CENTER))
|
||||
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
Steering::MeasureType::EDGE))
|
||||
|
||||
otherEntity->requirePropertyClassFixed<PositionProperty>().data() = {};
|
||||
otherEntity->m_lastUpdated++;
|
||||
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
|
||||
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER));
|
||||
otherEntity->requirePropertyClassFixed<PositionProperty>().data() = {20, 0, 0};
|
||||
otherEntity->m_lastUpdated++;
|
||||
|
|
@ -425,26 +427,29 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
avatarEntity->m_lastUpdated++;
|
||||
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
|
||||
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
|
||||
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER));
|
||||
avatarEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
|
||||
avatarEntity->m_lastUpdated++;
|
||||
|
||||
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
|
||||
//The distance to the avatar child entity should be 0.
|
||||
ASSERT_TRUE(steering.distanceTo(0, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
ASSERT_TRUE(steering.distanceTo(0ms, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER));
|
||||
ASSERT_FUZZY_EQUAL(0,
|
||||
*steering.distanceTo(0, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
|
||||
*steering.distanceTo(0ms, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()},
|
||||
Steering::MeasureType::CENTER,
|
||||
Steering::MeasureType::CENTER),
|
||||
epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0, *steering.distanceTo(0, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
Steering::MeasureType::CENTER),
|
||||
ASSERT_FUZZY_EQUAL(0,
|
||||
*steering.distanceTo(0ms, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
Steering::MeasureType::CENTER),
|
||||
epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0, *steering.distanceTo(0, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
Steering::MeasureType::EDGE),
|
||||
ASSERT_FUZZY_EQUAL(0,
|
||||
*steering.distanceTo(0ms, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
|
||||
Steering::MeasureType::EDGE),
|
||||
epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0, *steering.distanceTo(0, EntityLocation(avatarChildEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
|
||||
ASSERT_FUZZY_EQUAL(0, *steering.distanceTo(0ms, EntityLocation(avatarChildEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -511,52 +516,52 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
|
||||
double desiredDistance = 0.5;
|
||||
|
||||
steering.setDestination({{EntityLocation(otherEntity)}, Steering::MeasureType::EDGE, Steering::MeasureType::EDGE, desiredDistance}, 0);
|
||||
auto result = steering.updatePath(0);
|
||||
steering.setDestination({{EntityLocation(otherEntity)}, Steering::MeasureType::EDGE, Steering::MeasureType::EDGE, desiredDistance}, 0ms);
|
||||
auto result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(-1, result); //Could not find any poly since we haven't built any navmeshes.
|
||||
rebuildAllTilesFn();
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0));
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms));
|
||||
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
|
||||
ASSERT_EQUAL(to2D(otherEntity->requirePropertyClassFixed<PositionProperty>().data()), to2D(steering.getPath()[0]))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Move the avatar closer
|
||||
avatarEntity->requirePropertyClassFixed<PositionProperty>().data().x() = 5;
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
|
||||
ASSERT_EQUAL(to2D(otherEntity->requirePropertyClassFixed<PositionProperty>().data()), to2D(steering.getPath()[0]))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Move the destination entity away
|
||||
otherEntity->requirePropertyClassFixed<PositionProperty>().data().x() = 15;
|
||||
otherEntity->m_lastUpdated++;
|
||||
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
|
||||
steering.requestUpdate();
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
|
||||
ASSERT_EQUAL(to2D(otherEntity->requirePropertyClassFixed<PositionProperty>().data()), to2D(steering.getPath()[0]))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Move the avatar entity directly over the destination entity
|
||||
avatarEntity->requirePropertyClassFixed<PositionProperty>().data() = otherEntity->requirePropertyClassFixed<PositionProperty>().data();
|
||||
avatarEntity->m_lastUpdated++;
|
||||
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
|
||||
steering.requestUpdate();
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(0, result); //Should be no vert since we're exactly at destination
|
||||
ASSERT_TRUE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_TRUE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Move the avatar entity adjacent to the destination, but within required distance
|
||||
avatarEntity->requirePropertyClassFixed<PositionProperty>().data().x() -= 3.0;
|
||||
avatarEntity->m_lastUpdated++;
|
||||
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
|
||||
steering.requestUpdate();
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
|
||||
ASSERT_EQUAL(to2D(otherEntity->requirePropertyClassFixed<PositionProperty>().data()), to2D(steering.getPath()[0]))
|
||||
ASSERT_TRUE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_TRUE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Move the avatar to origo, place the obstacleEntity entity besides it, and plot a path "through" the obstacleEntity entity to a position beyond it.
|
||||
//The path should go around the other entity
|
||||
|
|
@ -565,15 +570,15 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
|
||||
obstacleEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
|
||||
awareness.addEntity(*avatarEntity, *obstacleEntity, false);
|
||||
steering.setDestination({{EntityLocation(worldEntity, {20, 0, 0})}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, desiredDistance}, 0);
|
||||
steering.setDestination({{EntityLocation(worldEntity, {20, 0, 0})}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, desiredDistance}, 0ms);
|
||||
rebuildAllTilesFn();
|
||||
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0));
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms));
|
||||
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(3, result); //Should be three verts since we need to divert twice
|
||||
ASSERT_EQUAL(WFMath::Point<2>(20, 0), to2D(steering.getPath()[2]))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Move the obstacle entity away, so that the path is straight again.
|
||||
obstacleEntity->requirePropertyClassFixed<PositionProperty>().data() = {-10, 0, 0};
|
||||
|
|
@ -581,10 +586,10 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
awareness.updateEntity(*avatarEntity, *obstacleEntity, nullptr);
|
||||
rebuildAllTilesFn();
|
||||
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
|
||||
ASSERT_EQUAL(WFMath::Point<2>(20, 0), to2D(steering.getPath()[0]))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Move it back again
|
||||
obstacleEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
|
||||
|
|
@ -592,27 +597,27 @@ struct SteeringIntegration : public Cyphesis::TestBase {
|
|||
awareness.updateEntity(*avatarEntity, *obstacleEntity, nullptr);
|
||||
rebuildAllTilesFn();
|
||||
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(3, result); //Should be three verts since we need to divert twice
|
||||
ASSERT_EQUAL(WFMath::Point<2>(20, 0), to2D(steering.getPath()[2]))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Remove obstacle entity from awareness
|
||||
awareness.removeEntity(*avatarEntity, *obstacleEntity);
|
||||
rebuildAllTilesFn();
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
|
||||
ASSERT_EQUAL(WFMath::Point<2>(20, 0), to2D(steering.getPath()[0]))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0))
|
||||
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
|
||||
|
||||
//Add the small obstacle entity between the avatar and the destination.
|
||||
// Since it can be stepped over/on it should not affect the path
|
||||
|
||||
smallObstacleEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
|
||||
awareness.addEntity(*avatarEntity, *smallObstacleEntity, false);
|
||||
steering.setDestination({{EntityLocation(worldEntity, {20, 0, 0})}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, desiredDistance}, 0);
|
||||
steering.setDestination({{EntityLocation(worldEntity, {20, 0, 0})}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, desiredDistance}, 0ms);
|
||||
rebuildAllTilesFn();
|
||||
result = steering.updatePath(0);
|
||||
result = steering.updatePath(0ms);
|
||||
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -643,7 +643,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext>
|
|||
arg1->setName("domain");
|
||||
tick->setArgs1(arg1);
|
||||
tick->setAttr("lastTick", 0.0f);
|
||||
tick->setSeconds(2.0f); // This should trigger a visibility.
|
||||
tick->setStamp(2000); // This should trigger a visibility.
|
||||
domainPhysical->getDomain()->operation(*domainPhysical, tick, res);
|
||||
return res;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -90,12 +90,12 @@ int main()
|
|||
expect_python_error("o.set_to(1)", PyExc_TypeError);
|
||||
run_python_string("o.set_from('2')");
|
||||
expect_python_error("o.set_from(2)", PyExc_TypeError);
|
||||
run_python_string("o.set_seconds(2)");
|
||||
run_python_string("o.set_seconds(2.0)");
|
||||
expect_python_error("o.set_seconds('2.0')", PyExc_TypeError);
|
||||
run_python_string("o.set_stamp(2)");
|
||||
expect_python_error("o.set_stamp('2.0')", PyExc_TypeError);
|
||||
run_python_string("o.set_future_seconds(2)");
|
||||
run_python_string("o.set_future_seconds(2.0)");
|
||||
expect_python_error("o.set_future_seconds('2.0')", PyExc_TypeError);
|
||||
run_python_string("o.set_future_milliseconds(2)");
|
||||
expect_python_error("o.set_future_milliseconds('2.0')", PyExc_TypeError);
|
||||
expect_python_error("o.set_args()", PyExc_IndexError);
|
||||
run_python_string("o.set_args([])");
|
||||
expect_python_error("o.set_args(1)", PyExc_TypeError);
|
||||
|
|
@ -109,8 +109,9 @@ int main()
|
|||
run_python_string("assert type(o.get_refno()) == int");
|
||||
run_python_string("assert type(o.get_to()) == str");
|
||||
run_python_string("assert type(o.get_from()) == str");
|
||||
run_python_string("assert type(o.get_seconds()) == float");
|
||||
run_python_string("assert type(o.get_stamp()) == int");
|
||||
run_python_string("assert type(o.get_future_seconds()) == float");
|
||||
run_python_string("assert type(o.get_future_milliseconds()) == int");
|
||||
run_python_string("assert type(o.get_args()) == list");
|
||||
run_python_string("assert type(o.get_name()) == str");
|
||||
run_python_string("assert len(o) == 1");
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ void BaseMindMapEntityintegration::test_MemMapreadEntity_noloc() {
|
|||
data->setLoc(tlve->getId());
|
||||
|
||||
// Read in entity data the sets the LOC of e3 to tlve
|
||||
m_mind->m_map.readEntity(e3, data, 0);
|
||||
m_mind->m_map.readEntity(e3, data, std::chrono::milliseconds{0});
|
||||
|
||||
ASSERT_EQUAL(e3->m_parent, tlve.get())
|
||||
ASSERT_TRUE(tlve->m_contains->find(e3) != tlve->m_contains->end());
|
||||
|
|
@ -239,7 +239,7 @@ void BaseMindMapEntityintegration::test_MemMapreadEntity_changeloc() {
|
|||
data->setLoc(tlve->getId());
|
||||
|
||||
// Read in entity data that changes the LOC of e3 from e2 to TLVE
|
||||
m_mind->m_map.readEntity(e3, data, 0);
|
||||
m_mind->m_map.readEntity(e3, data, std::chrono::milliseconds{0});
|
||||
|
||||
ASSERT_EQUAL(e3->m_parent, tlve.get())
|
||||
ASSERT_TRUE(e2->m_contains->find(e3) == e2->m_contains->end());
|
||||
|
|
@ -254,7 +254,7 @@ void BaseMindMapEntityintegration::test_MemMap_updateAdd_location_properties_hav
|
|||
Atlas::Objects::Entity::Anonymous args;
|
||||
location.addToEntity(args);
|
||||
args->setAttr("id", "1");
|
||||
m_mind->m_map.updateAdd(args, 1.0f);
|
||||
m_mind->m_map.updateAdd(args, std::chrono::milliseconds{1'000});
|
||||
}
|
||||
|
||||
auto ent = m_mind->m_map.get("1");
|
||||
|
|
@ -270,7 +270,7 @@ void BaseMindMapEntityintegration::test_MemMap_updateAdd_location_properties_hav
|
|||
args->setAttr("id", "1");
|
||||
args->setAttr("solid", 0);
|
||||
args->setAttr("simple", 0);
|
||||
m_mind->m_map.updateAdd(args, 2.0f);
|
||||
m_mind->m_map.updateAdd(args, std::chrono::milliseconds{2'000});
|
||||
}
|
||||
|
||||
ent = m_mind->m_map.get("1");
|
||||
|
|
@ -303,7 +303,7 @@ void BaseMindMapEntityintegration::test_MemMapcheck() {
|
|||
|
||||
m_mind->m_map.m_checkIterator = m_mind->m_map.m_entities.find(3);
|
||||
e3->setVisible(false);
|
||||
double time = e3->lastSeen() + 900;
|
||||
auto time = e3->lastSeen() + std::chrono::milliseconds{900'000};
|
||||
|
||||
// We have set up e3 so it is due to be purged from memory.
|
||||
m_mind->m_map.check(time);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ struct TestMemMap : public MemMap {
|
|||
return addId(id);
|
||||
}
|
||||
|
||||
void _readEntity(const Ref<MemEntity>& ent, const Atlas::Objects::Entity::RootEntity& rootEntity, double timestamp) {
|
||||
void _readEntity(const Ref<MemEntity>& ent, const Atlas::Objects::Entity::RootEntity& rootEntity, std::chrono::milliseconds timestamp) {
|
||||
readEntity(ent, rootEntity, timestamp);
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +235,7 @@ void MemMaptest::test_readEntity() {
|
|||
Ref<MemEntity> ent = new MemEntity(new_id);
|
||||
ent->setType(m_sampleType);
|
||||
|
||||
tested._readEntity(ent, data, 0);
|
||||
tested._readEntity(ent, data, std::chrono::milliseconds{0});
|
||||
}
|
||||
|
||||
void MemMaptest::test_readEntity_type() {
|
||||
|
|
@ -247,7 +247,7 @@ void MemMaptest::test_readEntity_type() {
|
|||
|
||||
Ref<MemEntity> ent = new MemEntity(new_id);
|
||||
|
||||
tested._readEntity(ent, data, 0);
|
||||
tested._readEntity(ent, data, std::chrono::milliseconds{0});
|
||||
|
||||
ASSERT_EQUAL(ent->getType(), m_sampleType);
|
||||
}
|
||||
|
|
@ -261,7 +261,7 @@ void MemMaptest::test_readEntity_type_nonexist() {
|
|||
|
||||
Ref<MemEntity> ent = new MemEntity(new_id);
|
||||
|
||||
tested._readEntity(ent, data, 0);
|
||||
tested._readEntity(ent, data, std::chrono::milliseconds{0});
|
||||
|
||||
ASSERT_NULL(ent->getType());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include <rules/simulation/VisibilityDistanceProperty.h>
|
||||
#include "../stubs/common/stubMonitors.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using Atlas::Message::Element;
|
||||
using Atlas::Message::ListType;
|
||||
using Atlas::Message::MapType;
|
||||
|
|
@ -161,8 +162,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
|
||||
void test_scaleBbox(TestContext& context) {
|
||||
double tickSize = 1.0 / 15.0;
|
||||
double time = 0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
std::chrono::milliseconds time(0);
|
||||
|
||||
OpVector res;
|
||||
|
||||
|
|
@ -203,7 +204,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
btCollisionWorld::ClosestRayResultCallback callback(from, to);
|
||||
domain->test_getPhysicalWorld()->rayTest(from, to, callback);
|
||||
domain->tick(1.0f, res);
|
||||
domain->tick(1000ms, res);
|
||||
|
||||
ASSERT_TRUE(callback.hasHit());
|
||||
ASSERT_FUZZY_EQUAL(1.0f, callback.m_hitPointWorld.y(), 0.1f);
|
||||
|
|
@ -220,7 +221,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->addEntity(freeEntity);
|
||||
|
||||
while (time < 5) {
|
||||
while (time < 5000ms) {
|
||||
time += tickSize;
|
||||
domain->tick(tickSize, res);
|
||||
}
|
||||
|
|
@ -234,7 +235,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->test_childEntityPropertyApplied("bbox", bBoxProperty, plantedEntity.getIntId());
|
||||
|
||||
domain->tick(1.0f, res);
|
||||
domain->tick(1000ms, res);
|
||||
|
||||
callback = btCollisionWorld::ClosestRayResultCallback(from, to);
|
||||
domain->test_getPhysicalWorld()->rayTest(from, to, callback);
|
||||
|
|
@ -249,8 +250,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->addEntity(freeEntity);
|
||||
|
||||
time = 0;
|
||||
while (time < 5) {
|
||||
time = 0ms;
|
||||
while (time < 5000ms) {
|
||||
time += tickSize;
|
||||
domain->tick(tickSize, res);
|
||||
}
|
||||
|
|
@ -288,7 +289,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->addEntity(planted1);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_EQUAL(rootEntity.getIntId(), *planted1.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
|
||||
|
||||
|
|
@ -301,7 +302,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->addEntity(planted2);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_EQUAL(planted1.getIntId(), *planted2.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
|
||||
ASSERT_FUZZY_EQUAL(1.0f, planted2.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
|
||||
|
|
@ -315,7 +316,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->addEntity(planted3);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_EQUAL(planted2.getIntId(), *planted3.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
|
||||
ASSERT_FUZZY_EQUAL(2.0f, planted3.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
|
||||
|
|
@ -329,7 +330,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->addEntity(planted4);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_EQUAL(planted3.getIntId(), *planted4.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
|
||||
ASSERT_FUZZY_EQUAL(3.0f, planted4.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
|
||||
|
|
@ -337,13 +338,13 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
//Now delete planted3, which should place planted4 on top of planted2
|
||||
|
||||
domain->removeEntity(planted3);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_EQUAL(planted2.getIntId(), *planted4.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
|
||||
ASSERT_FUZZY_EQUAL(2.0f, planted4.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
|
||||
|
||||
domain->removeEntity(planted1);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_EQUAL(rootEntity.getIntId(), *planted2.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
|
||||
ASSERT_FUZZY_EQUAL(0.0f, planted2.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
|
||||
|
|
@ -436,7 +437,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
domain->addEntity(fixed1);
|
||||
|
||||
OpVector res;
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_EQUAL(0, fixed1.requirePropertyClassFixed<PositionProperty>().data().y());
|
||||
|
||||
|
|
@ -450,7 +451,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->addEntity(planted1);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
Entity planted2(context.newId());
|
||||
planted2.requirePropertyClassFixed<PositionProperty>().data() = {0, 2, 1};
|
||||
|
|
@ -461,7 +462,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain->addEntity(planted2);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(2.0f, planted2.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
|
||||
|
||||
|
|
@ -475,7 +476,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
domain->addEntity(freeEntity);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(4.0f, freeEntity.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1);
|
||||
domain->tick(1, res);
|
||||
domain->tick(1000ms, res);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(4.0f, freeEntity.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1);
|
||||
|
||||
|
|
@ -489,7 +490,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
ASSERT_FUZZY_EQUAL(WFMath::Point<3>(10, 12, 11), planted2.requirePropertyClassFixed<PositionProperty>().data(), epsilon);
|
||||
ASSERT_TRUE(WFMath::Equal(WFMath::Point<3>(11, 14, 10), freeEntity.requirePropertyClassFixed<PositionProperty>().data(), 0.1));
|
||||
}
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
|
||||
//Only change orientation
|
||||
|
|
@ -502,7 +503,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
ASSERT_FUZZY_EQUAL(WFMath::Point<3>(11, 12, 10), planted2.requirePropertyClassFixed<PositionProperty>().data(), epsilon);
|
||||
ASSERT_TRUE(WFMath::Equal(WFMath::Point<3>(10, 14, 9), freeEntity.requirePropertyClassFixed<PositionProperty>().data(), 0.1));
|
||||
}
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
//Move it, and at the same time rotate it 90 degrees around the y axis.
|
||||
{
|
||||
|
|
@ -515,7 +516,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
ASSERT_FUZZY_EQUAL(WFMath::Point<3>(15, 17, 14), planted2.requirePropertyClassFixed<PositionProperty>().data(), epsilon);
|
||||
ASSERT_TRUE(WFMath::Equal(WFMath::Point<3>(14, 19, 15), freeEntity.requirePropertyClassFixed<PositionProperty>().data(), 0.1));
|
||||
}
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
//Move away the first planted entity, which should also move along the second planted and the free entity, and not affect the fixed entity.
|
||||
{
|
||||
|
|
@ -586,7 +587,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
domain.addEntity(planted1);
|
||||
|
||||
OpVector res;
|
||||
domain.tick(0, res);
|
||||
domain.tick(0ms, res);
|
||||
|
||||
ASSERT_TRUE(planted1.getPropertyClassFixed<ModeDataProperty>())
|
||||
ASSERT_TRUE(planted1.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
|
||||
|
|
@ -617,7 +618,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
domain.addEntity(planted2);
|
||||
|
||||
domain.tick(0, res);
|
||||
domain.tick(0ms, res);
|
||||
|
||||
ASSERT_TRUE(planted2.getPropertyClassFixed<ModeDataProperty>());
|
||||
ASSERT_TRUE(planted2.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId);
|
||||
|
|
@ -722,7 +723,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
OpVector res;
|
||||
std::set<LocatedEntity*> transformedEntities;
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
|
||||
ASSERT_FUZZY_EQUAL(terrain.get(10, 10), 10.0f, 0.1f);
|
||||
|
|
@ -740,7 +741,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
}
|
||||
domain->applyTransform(terrainModEntity, Domain::TransformData{WFMath::Quaternion(), WFMath::Point<3>(10, 10, 10), nullptr, {}}, transformedEntities);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(terrain.get(10, 10), 5.0f, 0.1f);
|
||||
ASSERT_TRUE(terrain.hasMod(terrainModEntity.getIntId()));
|
||||
|
|
@ -762,7 +763,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
modeProperty->apply(terrainModEntity);
|
||||
terrainModEntity.propertyApplied.emit("mode", *modeProperty);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(terrain.get(10, 10), 10.0f, 0.1f);
|
||||
ASSERT_FALSE(terrain.hasMod(terrainModEntity.getIntId()));
|
||||
|
|
@ -773,7 +774,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
modeProperty->apply(terrainModEntity);
|
||||
terrainModEntity.propertyApplied.emit("mode", *modeProperty);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(terrain.get(10, 10), 5.0f, 0.1f);
|
||||
ASSERT_TRUE(terrain.hasMod(terrainModEntity.getIntId()));
|
||||
|
|
@ -857,7 +858,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
domain->addEntity(floatingEntity);
|
||||
|
||||
OpVector res;
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Submerged);
|
||||
ASSERT_TRUE(freeEntity2.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
ASSERT_TRUE(floatingEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Planted);
|
||||
|
|
@ -879,8 +880,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
}
|
||||
};
|
||||
|
||||
double tickSize = 1.0 / 15.0;
|
||||
double time = 0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
std::chrono::milliseconds time(0);
|
||||
|
||||
TypeNode rockType("rock");
|
||||
TypeNode lakeType("lake");
|
||||
|
|
@ -939,8 +940,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
OpVector res;
|
||||
std::set<LocatedEntity*> transformedEntities;
|
||||
domain->tick(0, res);
|
||||
while (time < 5) {
|
||||
domain->tick(0ms, res);
|
||||
while (time < 5000ms) {
|
||||
time += tickSize;
|
||||
domain->tick(tickSize, res);
|
||||
}
|
||||
|
|
@ -956,13 +957,13 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
//Move outside
|
||||
domain->applyTransform(freeEntity, Domain::TransformData{WFMath::Quaternion::IDENTITY(), WFMath::Point<3>(20, 60, 0), nullptr, {}}, transformedEntities);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_GREATER(freeEntity.requirePropertyClassFixed<PositionProperty>().data().y(), 0);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
|
||||
//Move back in.
|
||||
domain->applyTransform(freeEntity, Domain::TransformData{WFMath::Quaternion::IDENTITY(), WFMath::Point<3>(20, -10, 0), nullptr, {}}, transformedEntities);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_LESS(freeEntity.requirePropertyClassFixed<PositionProperty>().data().y(), 0);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Submerged);
|
||||
ASSERT_TRUE(freeEntity3.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
|
|
@ -970,7 +971,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
//Move the lake to where freeEntity3 is
|
||||
domain->applyTransform(lake, Domain::TransformData{WFMath::Quaternion(), freeEntity3.requirePropertyClassFixed<PositionProperty>().data() + WFMath::Vector<3>(0, 5, 0), nullptr, {}},
|
||||
transformedEntities);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_TRUE(freeEntity3.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Submerged);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
|
||||
|
|
@ -990,12 +991,12 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
bBoxProperty.apply(lake);
|
||||
lake.test_propertyApplied().emit("bbox", bBoxProperty);
|
||||
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_TRUE(freeEntity3.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
|
||||
domain->removeEntity(lake);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
ASSERT_TRUE(freeEntity2.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
ASSERT_TRUE(freeEntity3.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
|
|
@ -1003,8 +1004,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
}
|
||||
|
||||
void test_ocean(TestContext& context) {
|
||||
double tickSize = 1.0 / 15.0;
|
||||
double time = 0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
std::chrono::milliseconds time(0);
|
||||
|
||||
TypeNode rockType("rock");
|
||||
TypeNode oceanType("ocean");
|
||||
|
|
@ -1055,8 +1056,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
OpVector res;
|
||||
std::set<LocatedEntity*> transformedEntities;
|
||||
domain->tick(0, res);
|
||||
while (time < 5) {
|
||||
domain->tick(0ms, res);
|
||||
while (time < 5000ms) {
|
||||
time += tickSize;
|
||||
domain->tick(tickSize, res);
|
||||
}
|
||||
|
|
@ -1069,18 +1070,18 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
//Move outside
|
||||
domain->applyTransform(freeEntity, Domain::TransformData{WFMath::Quaternion::IDENTITY(), WFMath::Point<3>(0, 60, 0), nullptr, {}}, transformedEntities);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_TRUE(freeEntity.requirePropertyClassFixed<PositionProperty>().data().y() > 0);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
|
||||
//Move back in.
|
||||
domain->applyTransform(freeEntity, Domain::TransformData{WFMath::Quaternion::IDENTITY(), WFMath::Point<3>(0, -10, 0), nullptr, {}}, transformedEntities);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_TRUE(freeEntity.requirePropertyClassFixed<PositionProperty>().data().y() < 0);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Submerged);
|
||||
|
||||
domain->removeEntity(ocean);
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
ASSERT_TRUE(freeEntity2.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
|
||||
}
|
||||
|
|
@ -1226,8 +1227,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
void test_fallToBottom(TestContext& context) {
|
||||
|
||||
double tickSize = 1.0 / 15.0;
|
||||
double time = 0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
std::chrono::milliseconds time(0);
|
||||
|
||||
Entity rootEntity(context.newId());
|
||||
rootEntity.incRef();
|
||||
|
|
@ -1262,12 +1263,12 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
OpVector res;
|
||||
|
||||
//First tick should not update anything
|
||||
domain->tick(0, res);
|
||||
domain->tick(0ms, res);
|
||||
ASSERT_EQUAL(freeEntity.requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>::ZERO());
|
||||
ASSERT_EQUAL(fixedEntity.requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>(10, 0, 10));
|
||||
|
||||
//Inject enough ticks to move rock to bottom
|
||||
while (time < 5) {
|
||||
while (time < 5000ms) {
|
||||
time += tickSize;
|
||||
domain->tick(tickSize, res);
|
||||
}
|
||||
|
|
@ -1279,8 +1280,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
void test_standOnFixed(TestContext& context) {
|
||||
|
||||
double tickSize = 1.0 / 15.0;
|
||||
double time = 0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
std::chrono::milliseconds time(0);
|
||||
Entity rootEntity(context.newId());
|
||||
rootEntity.incRef();
|
||||
rootEntity.requirePropertyClassFixed<PositionProperty>().data() = WFMath::Point<3>::ZERO();
|
||||
|
|
@ -1314,7 +1315,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
OpVector res;
|
||||
|
||||
//Inject enough ticks to move rock to bottom
|
||||
while (time < 5) {
|
||||
while (time < 5000ms) {
|
||||
time += tickSize;
|
||||
domain->tick(tickSize, res);
|
||||
}
|
||||
|
|
@ -1323,8 +1324,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
void test_fallToTerrain(TestContext& context) {
|
||||
|
||||
double tickSize = 1.0 / 15.0;
|
||||
double time = 0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
std::chrono::milliseconds time(0);
|
||||
Entity rootEntity(context.newId());
|
||||
rootEntity.incRef();
|
||||
TerrainProperty terrainProperty{};
|
||||
|
|
@ -1370,7 +1371,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
OpVector res;
|
||||
|
||||
//Inject enough ticks to move rock to bottom
|
||||
while (time < 5) {
|
||||
while (time < 5000ms) {
|
||||
time += tickSize;
|
||||
domain->tick(tickSize, res);
|
||||
}
|
||||
|
|
@ -1391,7 +1392,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
|
||||
void test_collision(TestContext& context) {
|
||||
double tickSize = 1.0 / 15.0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
|
||||
Property<double> zeroFrictionProperty{};
|
||||
zeroFrictionProperty.data() = 0;
|
||||
|
|
@ -1460,7 +1461,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
ASSERT_FUZZY_EQUAL(freeEntity.requirePropertyClassFixed<PositionProperty>().data().z(), 10 + (2.0 / 15.0), 0.1f);
|
||||
|
||||
//Inject ticks for one second
|
||||
domain->tick(14.0 / 15.0, res);
|
||||
domain->tick(14 * tickSize, res);
|
||||
|
||||
//Should have moved 2 meters in y axis
|
||||
ASSERT_FUZZY_EQUAL(freeEntity.requirePropertyClassFixed<PositionProperty>().data().z(), 12, 0.1f);
|
||||
|
|
@ -1475,7 +1476,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
ASSERT_EQUAL(plantedEntity.requirePropertyClassFixed<PositionProperty>().data(), plantedPos);
|
||||
|
||||
domain->removeEntity(plantedEntity);
|
||||
domain->tick(1.0, res);
|
||||
domain->tick(1000ms, res);
|
||||
|
||||
//Should have moved two more meters as planted entity was removed.
|
||||
ASSERT_FUZZY_EQUAL(freeEntity.requirePropertyClassFixed<PositionProperty>().data().z(), 15, 0.1f);
|
||||
|
|
@ -1485,7 +1486,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
void test_mode(TestContext& context) {
|
||||
|
||||
double tickSize = 1.0 / 15.0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
|
||||
ModeProperty modePlantedProperty{};
|
||||
modePlantedProperty.set("planted");
|
||||
|
|
@ -1567,7 +1568,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
void test_determinism(TestContext& context) {
|
||||
|
||||
double tickSize = 1.0 / 15.0;
|
||||
std::chrono::milliseconds tickSize(1000 / 15);
|
||||
|
||||
TypeNode rockType("rock");
|
||||
|
||||
|
|
@ -1762,7 +1763,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
|
||||
OpVector res;
|
||||
std::set<LocatedEntity*> transformedEntities;
|
||||
domain->tick(0.1, res);
|
||||
domain->tick(100ms, res);
|
||||
|
||||
ASSERT_TRUE(domain->isEntityVisibleFor(observerEntity, observerEntity));
|
||||
|
||||
|
|
@ -1785,7 +1786,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
//Now move the observer to "small1"
|
||||
domain->applyTransform(observerEntity, Domain::TransformData{WFMath::Quaternion(), WFMath::Point<3>(30, 0, 30), nullptr, {}}, transformedEntities);
|
||||
//Force visibility updates
|
||||
domain->tick(2, res);
|
||||
domain->tick(2000ms, res);
|
||||
{
|
||||
ASSERT_TRUE(domain->isEntityVisibleFor(observerEntity, smallVisibleEntity));
|
||||
ASSERT_TRUE(domain->isEntityVisibleFor(observerEntity, smallEntity1));
|
||||
|
|
@ -1869,7 +1870,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
domain->addEntity(*human);
|
||||
|
||||
OpVector res;
|
||||
domain->tick(2, res);
|
||||
domain->tick(2000ms, res);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(-0.5f, human->requirePropertyClassFixed<PositionProperty>().data().z(), 0.1f);
|
||||
domain->removeEntity(*human);
|
||||
|
|
@ -1889,7 +1890,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
domain->addEntity(*human);
|
||||
|
||||
OpVector res;
|
||||
domain->tick(2, res);
|
||||
domain->tick(2000ms, res);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(0.5, human->requirePropertyClassFixed<PositionProperty>().data().z(), 0.3f);
|
||||
domain->removeEntity(*human);
|
||||
|
|
@ -1923,7 +1924,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
|
|||
domain->addEntity(*human);
|
||||
|
||||
OpVector res;
|
||||
domain->tick(2, res);
|
||||
domain->tick(2000ms, res);
|
||||
|
||||
ASSERT_FUZZY_EQUAL(0, human->requirePropertyClassFixed<PositionProperty>().data().y(), 0.01f);
|
||||
ASSERT_FUZZY_EQUAL(-0.4f, human->requirePropertyClassFixed<PositionProperty>().data().z(), 0.1f);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ void SystemAccounttest::teardown() {
|
|||
void SystemAccounttest::test_getType() {
|
||||
const char* type = m_account->getType();
|
||||
|
||||
ASSERT_EQUAL(std::string("sys"), type);
|
||||
ASSERT_EQUAL(std::string("system_account"), type);
|
||||
}
|
||||
|
||||
void SystemAccounttest::test_store() {
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ int main() {
|
|||
}
|
||||
|
||||
{
|
||||
auto ac = tc.test_newAccount("sys",
|
||||
auto ac = tc.test_newAccount("system_account",
|
||||
"bob",
|
||||
"unit_test_hash",
|
||||
1);
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ void WorldRouterintegration::test_sequence() {
|
|||
test_world.addEntity(ent2, base);
|
||||
|
||||
Tick tick;
|
||||
tick->setFutureSeconds(0);
|
||||
tick->setFutureMilliseconds(0);
|
||||
tick->setTo(ent2->getId());
|
||||
test_world.message(tick, *ent2);
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ void WorldRoutertest::test_addEntity_tick() {
|
|||
test_world->addEntity(ent2, m_rootEntity);
|
||||
|
||||
Tick tick;
|
||||
tick->setFutureSeconds(0);
|
||||
tick->setFutureMilliseconds(0);
|
||||
tick->setTo(ent2->getId());
|
||||
test_world->message(tick, *ent2);
|
||||
}
|
||||
|
|
@ -176,7 +176,7 @@ void WorldRoutertest::test_addEntity_tick_get() {
|
|||
test_world->addEntity(ent2, m_rootEntity);
|
||||
|
||||
Tick tick;
|
||||
tick->setFutureSeconds(0);
|
||||
tick->setFutureMilliseconds(0);
|
||||
tick->setTo(ent2->getId());
|
||||
test_world->message(tick, *ent2);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#ifndef STUB_CreatorClient_handleMakeResponse
|
||||
//#define STUB_CreatorClient_handleMakeResponse
|
||||
LocatedEntity* CreatorClient::handleMakeResponse(const Atlas::Objects::Operation::RootOperation&, double)
|
||||
LocatedEntity* CreatorClient::handleMakeResponse(const Atlas::Objects::Operation::RootOperation&, std::chrono::milliseconds)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
|
||||
#ifndef STUB_Awareness_avoidObstacles
|
||||
//#define STUB_Awareness_avoidObstacles
|
||||
bool Awareness::avoidObstacles(long avatarEntityId, const WFMath::Point<2>& position, const WFMath::Vector<2>& desiredVelocity, WFMath::Vector<2>& newVelocity, double currentTimestamp, const WFMath::Point<2>* nextWayPoint) const
|
||||
bool Awareness::avoidObstacles(long avatarEntityId, const WFMath::Point<2>& position, const WFMath::Vector<2>& desiredVelocity, WFMath::Vector<2>& newVelocity, std::chrono::milliseconds currentTimestamp, const WFMath::Point<2>* nextWayPoint) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -189,7 +189,7 @@
|
|||
|
||||
#ifndef STUB_Awareness_projectPosition
|
||||
//#define STUB_Awareness_projectPosition
|
||||
bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, double currentServerTimestamp) const
|
||||
bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, std::chrono::milliseconds currentServerTimestamp) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -197,7 +197,7 @@
|
|||
|
||||
#ifndef STUB_Awareness_projectPosition
|
||||
//#define STUB_Awareness_projectPosition
|
||||
WFMath::Point<3> Awareness::projectPosition(long entityId, double currentServerTimestamp) const
|
||||
WFMath::Point<3> Awareness::projectPosition(long entityId, std::chrono::milliseconds currentServerTimestamp) const
|
||||
{
|
||||
return *static_cast<WFMath::Point<3>*>(nullptr);
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@
|
|||
|
||||
#ifndef STUB_Awareness_processEntityUpdate
|
||||
//#define STUB_Awareness_processEntityUpdate
|
||||
bool Awareness::processEntityUpdate(EntityEntry& entry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, double timestamp)
|
||||
bool Awareness::processEntityUpdate(EntityEntry& entry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, std::chrono::milliseconds timestamp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#ifndef STUB_Steering_queryDestination
|
||||
//#define STUB_Steering_queryDestination
|
||||
int Steering::queryDestination(const EntityLocation& destination, double currentServerTimestamp)
|
||||
int Steering::queryDestination(const EntityLocation& destination, std::chrono::milliseconds currentServerTimestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#ifndef STUB_Steering_setDestination
|
||||
//#define STUB_Steering_setDestination
|
||||
void Steering::setDestination(SteeringDestination destination, double currentServerTimestamp)
|
||||
void Steering::setDestination(SteeringDestination destination, std::chrono::milliseconds currentServerTimestamp)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
#ifndef STUB_Steering_updatePath
|
||||
//#define STUB_Steering_updatePath
|
||||
int Steering::updatePath(double currentTimestamp, const WFMath::Point<3>& currentAvatarPosition)
|
||||
int Steering::updatePath(std::chrono::milliseconds currentTimestamp, const WFMath::Point<3>& currentAvatarPosition)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
#ifndef STUB_Steering_updatePath
|
||||
//#define STUB_Steering_updatePath
|
||||
int Steering::updatePath(double currentTimestamp)
|
||||
int Steering::updatePath(std::chrono::milliseconds currentTimestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
|
||||
#ifndef STUB_Steering_update
|
||||
//#define STUB_Steering_update
|
||||
SteeringResult Steering::update(double currentTimestamp)
|
||||
SteeringResult Steering::update(std::chrono::milliseconds currentTimestamp)
|
||||
{
|
||||
return *static_cast<SteeringResult*>(nullptr);
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@
|
|||
|
||||
#ifndef STUB_Steering_getCurrentAvatarPosition
|
||||
//#define STUB_Steering_getCurrentAvatarPosition
|
||||
WFMath::Point<3> Steering::getCurrentAvatarPosition(double currentTimestamp) const
|
||||
WFMath::Point<3> Steering::getCurrentAvatarPosition(std::chrono::milliseconds currentTimestamp) const
|
||||
{
|
||||
return *static_cast<WFMath::Point<3>*>(nullptr);
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@
|
|||
|
||||
#ifndef STUB_Steering_isAtDestination
|
||||
//#define STUB_Steering_isAtDestination
|
||||
bool Steering::isAtDestination(double currentTimestamp, const SteeringDestination& destination) const
|
||||
bool Steering::isAtDestination(std::chrono::milliseconds currentTimestamp, const SteeringDestination& destination) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -172,7 +172,7 @@
|
|||
|
||||
#ifndef STUB_Steering_isAtCurrentDestination
|
||||
//#define STUB_Steering_isAtCurrentDestination
|
||||
bool Steering::isAtCurrentDestination(double currentTimestamp) const
|
||||
bool Steering::isAtCurrentDestination(std::chrono::milliseconds currentTimestamp) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -180,7 +180,7 @@
|
|||
|
||||
#ifndef STUB_Steering_distanceTo
|
||||
//#define STUB_Steering_distanceTo
|
||||
std::optional<double> Steering::distanceTo(double currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const
|
||||
std::optional<double> Steering::distanceTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const
|
||||
{
|
||||
return *static_cast<std::optional<double>*>(nullptr);
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@
|
|||
|
||||
#ifndef STUB_Steering_directionTo
|
||||
//#define STUB_Steering_directionTo
|
||||
WFMath::Vector<3> Steering::directionTo(double currentTimestamp, const EntityLocation& location) const
|
||||
WFMath::Vector<3> Steering::directionTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const
|
||||
{
|
||||
return *static_cast<WFMath::Vector<3>*>(nullptr);
|
||||
}
|
||||
|
|
@ -196,7 +196,7 @@
|
|||
|
||||
#ifndef STUB_Steering_resolvePosition
|
||||
//#define STUB_Steering_resolvePosition
|
||||
Steering::ResolvedPosition Steering::resolvePosition(double currentTimestamp, const EntityLocation& location) const
|
||||
Steering::ResolvedPosition Steering::resolvePosition(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const
|
||||
{
|
||||
return *static_cast<Steering::ResolvedPosition*>(nullptr);
|
||||
}
|
||||
|
|
@ -204,7 +204,7 @@
|
|||
|
||||
#ifndef STUB_Steering_setAwarenessArea
|
||||
//#define STUB_Steering_setAwarenessArea
|
||||
void Steering::setAwarenessArea(double currentServerTimestamp)
|
||||
void Steering::setAwarenessArea(std::chrono::milliseconds currentServerTimestamp)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -236,7 +236,7 @@
|
|||
|
||||
#ifndef STUB_Steering_updatePosition
|
||||
//#define STUB_Steering_updatePosition
|
||||
void Steering::updatePosition(double currentServerTimestamp, long entityId, WFMath::Point<3>& pos) const
|
||||
void Steering::updatePosition(std::chrono::milliseconds currentServerTimestamp, long entityId, WFMath::Point<3>& pos) const
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@
|
|||
|
||||
#ifndef STUB_AwareMind_getCurrentServerTime
|
||||
//#define STUB_AwareMind_getCurrentServerTime
|
||||
double AwareMind::getCurrentServerTime() const
|
||||
std::chrono::milliseconds AwareMind::getCurrentServerTime() const
|
||||
{
|
||||
return 0;
|
||||
return *static_cast<std::chrono::milliseconds*>(nullptr);
|
||||
}
|
||||
#endif //STUB_AwareMind_getCurrentServerTime
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#ifndef STUB_MemMap_readEntity
|
||||
//#define STUB_MemMap_readEntity
|
||||
void MemMap::readEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, double timestamp)
|
||||
void MemMap::readEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#ifndef STUB_MemMap_updateEntity
|
||||
//#define STUB_MemMap_updateEntity
|
||||
void MemMap::updateEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, double timestamp)
|
||||
void MemMap::updateEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#ifndef STUB_MemMap_newEntity
|
||||
//#define STUB_MemMap_newEntity
|
||||
Ref<MemEntity> MemMap::newEntity(RouterId, const Atlas::Objects::Entity::RootEntity&, double timestamp)
|
||||
Ref<MemEntity> MemMap::newEntity(const RouterId&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp)
|
||||
{
|
||||
return *static_cast<Ref<MemEntity>*>(nullptr);
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
#ifndef STUB_MemMap_addId
|
||||
//#define STUB_MemMap_addId
|
||||
Ref<MemEntity> MemMap::addId(RouterId id)
|
||||
Ref<MemEntity> MemMap::addId(const RouterId& id)
|
||||
{
|
||||
return *static_cast<Ref<MemEntity>*>(nullptr);
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
#ifndef STUB_MemMap_applyTypePropertiesToEntity
|
||||
//#define STUB_MemMap_applyTypePropertiesToEntity
|
||||
void MemMap::applyTypePropertiesToEntity(const Ref<MemEntity>& entity)
|
||||
void MemMap::applyTypePropertiesToEntity(const Ref<MemEntity>& entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@
|
|||
|
||||
#ifndef STUB_MemMap_updateAdd
|
||||
//#define STUB_MemMap_updateAdd
|
||||
Ref<MemEntity> MemMap::updateAdd(const Atlas::Objects::Entity::RootEntity&, const double&)
|
||||
Ref<MemEntity> MemMap::updateAdd(const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds)
|
||||
{
|
||||
return *static_cast<Ref<MemEntity>*>(nullptr);
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@
|
|||
|
||||
#ifndef STUB_MemMap_findByLocation
|
||||
//#define STUB_MemMap_findByLocation
|
||||
EntityVector MemMap::findByLocation(const EntityLocation& where, WFMath::CoordType radius, const std::string& what)
|
||||
EntityVector MemMap::findByLocation(const EntityLocation& where, WFMath::CoordType radius, const std::string& what) const
|
||||
{
|
||||
return *static_cast<EntityVector*>(nullptr);
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@
|
|||
|
||||
#ifndef STUB_MemMap_check
|
||||
//#define STUB_MemMap_check
|
||||
void MemMap::check(const double&)
|
||||
void MemMap::check(std::chrono::milliseconds t)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,13 +129,13 @@
|
|||
}
|
||||
#endif //STUB_CyPy_Operation_setTo
|
||||
|
||||
#ifndef STUB_CyPy_Operation_setSeconds
|
||||
//#define STUB_CyPy_Operation_setSeconds
|
||||
Py::Object CyPy_Operation::setSeconds(const Py::Tuple& args)
|
||||
#ifndef STUB_CyPy_Operation_setStamp
|
||||
//#define STUB_CyPy_Operation_setStamp
|
||||
Py::Object CyPy_Operation::setStamp(const Py::Tuple& args)
|
||||
{
|
||||
return *static_cast<Py::Object*>(nullptr);
|
||||
}
|
||||
#endif //STUB_CyPy_Operation_setSeconds
|
||||
#endif //STUB_CyPy_Operation_setStamp
|
||||
|
||||
#ifndef STUB_CyPy_Operation_setFutureSeconds
|
||||
//#define STUB_CyPy_Operation_setFutureSeconds
|
||||
|
|
@ -145,6 +145,14 @@
|
|||
}
|
||||
#endif //STUB_CyPy_Operation_setFutureSeconds
|
||||
|
||||
#ifndef STUB_CyPy_Operation_setFutureMilliseconds
|
||||
//#define STUB_CyPy_Operation_setFutureMilliseconds
|
||||
Py::Object CyPy_Operation::setFutureMilliseconds(const Py::Tuple& args)
|
||||
{
|
||||
return *static_cast<Py::Object*>(nullptr);
|
||||
}
|
||||
#endif //STUB_CyPy_Operation_setFutureMilliseconds
|
||||
|
||||
#ifndef STUB_CyPy_Operation_setName
|
||||
//#define STUB_CyPy_Operation_setName
|
||||
Py::Object CyPy_Operation::setName(const Py::Tuple& args)
|
||||
|
|
@ -201,13 +209,13 @@
|
|||
}
|
||||
#endif //STUB_CyPy_Operation_getTo
|
||||
|
||||
#ifndef STUB_CyPy_Operation_getSeconds
|
||||
//#define STUB_CyPy_Operation_getSeconds
|
||||
Py::Object CyPy_Operation::getSeconds()
|
||||
#ifndef STUB_CyPy_Operation_getStamp
|
||||
//#define STUB_CyPy_Operation_getStamp
|
||||
Py::Object CyPy_Operation::getStamp()
|
||||
{
|
||||
return *static_cast<Py::Object*>(nullptr);
|
||||
}
|
||||
#endif //STUB_CyPy_Operation_getSeconds
|
||||
#endif //STUB_CyPy_Operation_getStamp
|
||||
|
||||
#ifndef STUB_CyPy_Operation_getFutureSeconds
|
||||
//#define STUB_CyPy_Operation_getFutureSeconds
|
||||
|
|
@ -217,6 +225,14 @@
|
|||
}
|
||||
#endif //STUB_CyPy_Operation_getFutureSeconds
|
||||
|
||||
#ifndef STUB_CyPy_Operation_getFutureMilliseconds
|
||||
//#define STUB_CyPy_Operation_getFutureMilliseconds
|
||||
Py::Object CyPy_Operation::getFutureMilliseconds()
|
||||
{
|
||||
return *static_cast<Py::Object*>(nullptr);
|
||||
}
|
||||
#endif //STUB_CyPy_Operation_getFutureMilliseconds
|
||||
|
||||
#ifndef STUB_CyPy_Operation_getName
|
||||
//#define STUB_CyPy_Operation_getName
|
||||
Py::Object CyPy_Operation::getName()
|
||||
|
|
|
|||
|
|
@ -80,6 +80,14 @@
|
|||
}
|
||||
#endif //STUB_BaseWorld_getTime
|
||||
|
||||
#ifndef STUB_BaseWorld_getTimeAsMilliseconds
|
||||
//#define STUB_BaseWorld_getTimeAsMilliseconds
|
||||
std::chrono::milliseconds BaseWorld::getTimeAsMilliseconds() const
|
||||
{
|
||||
return *static_cast<std::chrono::milliseconds*>(nullptr);
|
||||
}
|
||||
#endif //STUB_BaseWorld_getTimeAsMilliseconds
|
||||
|
||||
#ifndef STUB_BaseWorld_getTimeAsSeconds
|
||||
//#define STUB_BaseWorld_getTimeAsSeconds
|
||||
float BaseWorld::getTimeAsSeconds() const
|
||||
|
|
|
|||
|
|
@ -23,7 +23,15 @@ Ref<LocatedEntity> BaseWorld::getEntity(long id) const
|
|||
assert(I->second);
|
||||
return I->second;
|
||||
} else {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif //STUB_BaseWorld_getEntity
|
||||
|
||||
#ifndef STUB_BaseWorld_getTimeAsMilliseconds
|
||||
#define STUB_BaseWorld_getTimeAsMilliseconds
|
||||
std::chrono::milliseconds BaseWorld::getTimeAsMilliseconds() const
|
||||
{
|
||||
return std::chrono::milliseconds();
|
||||
}
|
||||
#endif //STUB_BaseWorld_getTimeAsMilliseconds
|
||||
|
|
@ -115,7 +115,7 @@
|
|||
|
||||
#ifndef STUB_PhysicalDomain_tick
|
||||
//#define STUB_PhysicalDomain_tick
|
||||
void PhysicalDomain::tick(double t, OpVector& res)
|
||||
void PhysicalDomain::tick(std::chrono::milliseconds t, OpVector& res)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -211,7 +211,7 @@
|
|||
|
||||
#ifndef STUB_PhysicalDomain_processMovedEntity
|
||||
//#define STUB_PhysicalDomain_processMovedEntity
|
||||
void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, double timeSinceLastUpdate)
|
||||
void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, std::chrono::milliseconds timeSinceLastUpdate)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -275,7 +275,7 @@
|
|||
|
||||
#ifndef STUB_PhysicalDomain_applyDestination
|
||||
//#define STUB_PhysicalDomain_applyDestination
|
||||
void PhysicalDomain::applyDestination(double tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp)
|
||||
void PhysicalDomain::applyDestination(std::chrono::milliseconds tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -307,7 +307,7 @@
|
|||
|
||||
#ifndef STUB_PhysicalDomain_createCollisionShapeForEntry
|
||||
//#define STUB_PhysicalDomain_createCollisionShapeForEntry
|
||||
std::shared_ptr<btCollisionShape> PhysicalDomain::createCollisionShapeForEntry(LocatedEntity& entity, const WFMath::AxisBox<3>& bbox, float mass, btVector3& centerOfMassOffse)
|
||||
std::shared_ptr<btCollisionShape> PhysicalDomain::createCollisionShapeForEntry(LocatedEntity& entity, const WFMath::AxisBox<3>& bbox, float mass, btVector3& centerOfMassOffset)
|
||||
{
|
||||
return *static_cast<std::shared_ptr<btCollisionShape>*>(nullptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -365,8 +365,8 @@ void ServerWidget::fillAllowedCharacterTypes(Eris::Account* account) {
|
|||
|
||||
auto& spawnPoints = account->getSpawnPoints();
|
||||
|
||||
//If the account inherits from "admin" we're an admin and can create a creator entity. This also applies if we're a "sys" account.
|
||||
if (account->getParent() == "admin" || account->getParent() == "sys") {
|
||||
//If the account inherits from "admin" we're an admin and can create a creator entity. This also applies if we're a "system_account" account.
|
||||
if (account->getParent() == "admin" || account->getParent() == "system_account") {
|
||||
mUseCreator->setVisible(true);
|
||||
mUseCreator->setEnabled(true);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -326,15 +326,15 @@ std::vector<ActionChange> EmberEntity::processActionsChange(const Atlas::Message
|
|||
if (!v.isMap()) {
|
||||
//Remove all existing actions
|
||||
for (auto& entry: mActionsData) {
|
||||
actionChanges.emplace_back(ActionChange::ChangeType::Removed, ActionEntry{entry.first, 0, 0});
|
||||
actionChanges.emplace_back(ActionChange::ChangeType::Removed, ActionEntry{entry.first, std::chrono::milliseconds(0), std::chrono::milliseconds(0)});
|
||||
}
|
||||
mActionsData.clear();
|
||||
} else if (mActionsData.empty()) {
|
||||
auto& newMap = v.Map();
|
||||
//All new actions
|
||||
for (auto& newEntry: newMap) {
|
||||
AtlasQuery::find<Atlas::Message::FloatType>(newEntry.second, "start_time", [&](const auto& startTime) {
|
||||
ActionEntry actionEntry{newEntry.first, startTime, 0};
|
||||
AtlasQuery::find<Atlas::Message::IntType>(newEntry.second, "start_time", [&](const auto& startTime) {
|
||||
ActionEntry actionEntry{newEntry.first, std::chrono::milliseconds(startTime), std::chrono::milliseconds(0)};
|
||||
actionChanges.emplace_back(ActionChange::ChangeType::Added, std::move(actionEntry));
|
||||
});
|
||||
}
|
||||
|
|
@ -345,20 +345,20 @@ std::vector<ActionChange> EmberEntity::processActionsChange(const Atlas::Message
|
|||
for (auto& newEntry: newMap) {
|
||||
auto existingI = existingMap.find(newEntry.first);
|
||||
if (existingI == existingMap.end()) {
|
||||
AtlasQuery::find<Atlas::Message::FloatType>(newEntry.second, "start_time", [&](const auto& startTime) {
|
||||
ActionEntry actionEntry{newEntry.first, startTime, 0};
|
||||
AtlasQuery::find<Atlas::Message::IntType>(newEntry.second, "start_time", [&](const auto& startTime) {
|
||||
ActionEntry actionEntry{newEntry.first, std::chrono::milliseconds(startTime), std::chrono::milliseconds(0)};
|
||||
actionChanges.emplace_back(ActionChange::ChangeType::Added, std::move(actionEntry));
|
||||
});
|
||||
} else {
|
||||
AtlasQuery::find<Atlas::Message::FloatType>(newEntry.second, "start_time", [&](const auto& startTime) {
|
||||
ActionEntry actionEntry{newEntry.first, startTime, 0};
|
||||
AtlasQuery::find<Atlas::Message::IntType>(newEntry.second, "start_time", [&](const auto& startTime) {
|
||||
ActionEntry actionEntry{newEntry.first, std::chrono::milliseconds(startTime), std::chrono::milliseconds(0)};
|
||||
actionChanges.emplace_back(ActionChange::ChangeType::Updated, std::move(actionEntry));
|
||||
});
|
||||
existingMap.erase(existingI);
|
||||
}
|
||||
}
|
||||
for (auto& entry: existingMap) {
|
||||
actionChanges.emplace_back(ActionChange::ChangeType::Removed, ActionEntry{entry.first, 0, 0});
|
||||
actionChanges.emplace_back(ActionChange::ChangeType::Removed, ActionEntry{entry.first, std::chrono::milliseconds(0), std::chrono::milliseconds(0)});
|
||||
}
|
||||
mActionsData = newMap;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,13 +45,13 @@ class EntityTalk;
|
|||
|
||||
struct ActionEntry {
|
||||
ActionEntry(std::string actionName_,
|
||||
double startTime_,
|
||||
std::optional<double> endTime_)
|
||||
std::chrono::milliseconds startTime_,
|
||||
std::optional<std::chrono::milliseconds> endTime_)
|
||||
: actionName(std::move(actionName_)), startTime(startTime_), endTime(endTime_) {}
|
||||
|
||||
std::string actionName;
|
||||
double startTime;
|
||||
std::optional<double> endTime;
|
||||
std::chrono::milliseconds startTime;
|
||||
std::optional<std::chrono::milliseconds> endTime;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@
|
|||
#include <Eris/Account.h>
|
||||
#include <Eris/Connection.h>
|
||||
#include <Eris/Response.h>
|
||||
#include <Eris/CustomEntities.h>
|
||||
#include <Eris/SpawnPoint.h>
|
||||
|
||||
#include <Atlas/Objects/Operation.h>
|
||||
#include <Atlas/Objects/Entity.h>
|
||||
|
||||
#include <wfmath/MersenneTwister.h>
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ LocalServerAdminCreator::LocalServerAdminCreator(ServerService& serverService) {
|
|||
}
|
||||
|
||||
void LocalServerAdminCreator::server_GotAccount(Eris::Account* account) {
|
||||
//When connecting to a local socket we should use a "sys" account.
|
||||
//When connecting to a local socket we should use a "system_account" account.
|
||||
//This works very much like an "admin" account, but is not persisted on the server.
|
||||
//Thus we will first create a new account on the server, with a random name and password.
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ void LocalServerAdminCreator::server_GotAccount(Eris::Account* account) {
|
|||
ss_username << rand.randInt(9);
|
||||
}
|
||||
|
||||
Atlas::Objects::Entity::Sys sysAccountOp;
|
||||
Atlas::Objects::Entity::SystemAccount sysAccountOp;
|
||||
|
||||
sysAccountOp->setAttr("username", ss_username.str());
|
||||
sysAccountOp->setAttr("password", ss_password.str());
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ protected:
|
|||
|
||||
/**
|
||||
* @author Erik Ogenvik
|
||||
* @brief Handles the flow of creating a "sys" account and logging in the user.
|
||||
* @brief Handles the flow of creating a "system_account" account and logging in the user.
|
||||
*
|
||||
* This is meant to be used when the connected to a local server through a socket
|
||||
* and the user wants to enter the world as a creator entity.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
Outline of changes in the next version:
|
||||
times change from float to int, and specced in milliseconds
|
||||
merge SECONDS and STAMP
|
||||
abolish STAMP_CONTAINS and FUTURE_SECONDS
|
||||
|
||||
- binary2
|
||||
- specify operations and their args semantically much more than currently is done:
|
||||
especially movement modes
|
||||
|
|
|
|||
|
|
@ -626,6 +626,11 @@ This gives one rotation angle in 2D, the three Euler angles in 3D, etc.
|
|||
parents:["seconds"],
|
||||
summary:"Time in seconds to add current time"
|
||||
},
|
||||
{
|
||||
id:"future_milliseconds",
|
||||
parents:["int"],
|
||||
summary:"Time in milliseconds to add current time"
|
||||
},
|
||||
{
|
||||
id:"time_string",
|
||||
parents:["string"],
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
pos:[0.0,0.0,0.0]
|
||||
velocity:[0.0,0.0,0.0]
|
||||
contains:[]
|
||||
stamp_contains:0.0
|
||||
|
||||
:map:
|
||||
id:"admin_entity"
|
||||
|
|
@ -34,6 +33,11 @@
|
|||
parent:"account"
|
||||
description:"Privileged accounts"
|
||||
|
||||
:map:
|
||||
id:"system_account"
|
||||
parent:"account"
|
||||
description:"Privileged accounts which aren't persisted on the server."
|
||||
|
||||
:map:
|
||||
id:"game"
|
||||
parent:"admin_entity"
|
||||
|
|
@ -45,3 +49,5 @@
|
|||
specification:"atlas_game"
|
||||
interface:"game_interface"
|
||||
description:"All In Game classes and objects"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,13 +8,11 @@
|
|||
description:"Base operation for all operators"
|
||||
long_description:"""This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'."""
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for."""
|
||||
from:""
|
||||
to:""
|
||||
seconds:0.0
|
||||
future_seconds:0.0
|
||||
future_milliseconds:0
|
||||
time_string:""
|
||||
args:[]
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
:map:
|
||||
id:"root"
|
||||
parent:""
|
||||
stamp:0.0
|
||||
stamp_inherit:0.0
|
||||
stamp:0
|
||||
objtype:"meta"
|
||||
interface:"base_interface"
|
||||
name:""
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ For more about URI see
|
|||
:map:
|
||||
id:"characters"
|
||||
parent:"contains"
|
||||
description:"List of characters account can control"
|
||||
description:"List of characters the account can control."
|
||||
|
||||
:map:
|
||||
id:"args"
|
||||
|
|
@ -170,33 +170,18 @@ For more about URI see
|
|||
:map:
|
||||
id:"operations"
|
||||
parent:"id_list"
|
||||
description:"List of alloved operations"
|
||||
description:"List of allowed operations"
|
||||
long_description:"Content ids can be either another interface or operation ids or both."
|
||||
|
||||
:map:
|
||||
id:"stamp"
|
||||
parent:"float"
|
||||
parent:"int"
|
||||
objtype:"type"
|
||||
description:"Last time this object was modified."
|
||||
long_description:"""Value should be reflect when something was
|
||||
changed in this object. Any scheme is ok as long as newer numbers
|
||||
are bigger than older stamps. For example, seconds since Jan 1st,
|
||||
1970 or total game cycles would both be valid."""
|
||||
|
||||
:map:
|
||||
id:"stamp_inherit"
|
||||
parent:"stamp"
|
||||
objtype:"type"
|
||||
description:"Last time any object that inherits from this has been modified"
|
||||
long_description:"Value should be reflect when something was changed in some object that inherits from this."
|
||||
|
||||
:map:
|
||||
id:"stamp_contains"
|
||||
parent:"stamp"
|
||||
objtype:"type"
|
||||
description:"Last time any object that uses this as reference recursively has been modified"
|
||||
long_description:"Value should be reflect when something was changed in some object that is contained by this object."
|
||||
|
||||
long_description:"""A timestamp in milliseconds for when this object was updated on the server. The time scale used
|
||||
doesn't necessarily need to be using any Epoch, it could instead be based on when the server was started. For
|
||||
Operations this would indicate when it was sent from the server, whereas for Entities it would indicate when
|
||||
properties were last updated."""
|
||||
|
||||
:map:
|
||||
id:"objtype"
|
||||
|
|
@ -206,11 +191,6 @@ For more about URI see
|
|||
description:"What kind of object this is."
|
||||
long_description:"""Examples of values: "op", "class", "type"."""
|
||||
|
||||
:map:
|
||||
id:"interface"
|
||||
parent:"id"
|
||||
description:"What kind of operations are legal for this object."
|
||||
|
||||
:map:
|
||||
id:"specification"
|
||||
parent:"string"
|
||||
|
|
@ -234,12 +214,6 @@ For more about URI see
|
|||
parent:"message"
|
||||
description:"What something has said."
|
||||
|
||||
:map:
|
||||
id:"html"
|
||||
parent:"string"
|
||||
objtype:"type"
|
||||
description:"String that is actually html."
|
||||
|
||||
:map:
|
||||
id:"username"
|
||||
parent:"string"
|
||||
|
|
@ -254,7 +228,7 @@ For more about URI see
|
|||
|
||||
:map:
|
||||
id:"description"
|
||||
parent:"html"
|
||||
parent:"string"
|
||||
description:"This gives short description of object."
|
||||
|
||||
:map:
|
||||
|
|
@ -299,22 +273,12 @@ For more about URI see
|
|||
character can only control directly it's body."""
|
||||
|
||||
:map:
|
||||
id:"seconds"
|
||||
parent:"float"
|
||||
objtype:"type"
|
||||
description:"Time in seconds"
|
||||
|
||||
:map:
|
||||
id:"future_seconds"
|
||||
parent:"seconds"
|
||||
description:"Time in seconds to add current time"
|
||||
|
||||
:map:
|
||||
id:"time_string"
|
||||
parent:"string"
|
||||
objtype:"type"
|
||||
description:"Time in string format: YYYY-MM-DD HH:MM:SS.ss"
|
||||
long_description:"There can be variation in length of different fields if using some weird calendar"
|
||||
id:"future_milliseconds"
|
||||
parent:"int"
|
||||
description:"Time in milliseconds to add current time."
|
||||
long_description:"""This is used when you need to schedule something to happen on
|
||||
the server some milliseconds from when the server receives the operation. If you want a more fixed time you can
|
||||
instead set the 'stamp' attribute."""
|
||||
|
||||
:map:
|
||||
id:"example"
|
||||
|
|
@ -322,33 +286,6 @@ For more about URI see
|
|||
objtype:"type"
|
||||
description:"Gives some examples usage"
|
||||
|
||||
#attributes for map
|
||||
:map:
|
||||
id:"width"
|
||||
parent:"float"
|
||||
objtype:"type"
|
||||
description:"width of something"
|
||||
|
||||
:map:
|
||||
id:"grid_data"
|
||||
parent:"list"
|
||||
objtype:"type"
|
||||
description:"grid data"
|
||||
|
||||
:map:
|
||||
id:"grid_size"
|
||||
parent:"int_list_length"
|
||||
objtype:"type"
|
||||
list_length:2
|
||||
description:"size of grid area: width and height (and for space depth too) in grid units"
|
||||
|
||||
:map:
|
||||
id:"cell_size"
|
||||
parent:"float_list_length"
|
||||
objtype:"type"
|
||||
list_length:2
|
||||
description:"cell size of grid area"
|
||||
|
||||
:map:
|
||||
id:"height"
|
||||
parent:"float"
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -55,8 +55,7 @@ void AnonymousData::fillDefaultObjectInstance(AnonymousData& data, std::map<std:
|
|||
data.attr_velocity.emplace_back(0.0);
|
||||
data.attr_velocity.emplace_back(0.0);
|
||||
data.attr_velocity.emplace_back(0.0);
|
||||
data.attr_stamp_contains = 0.0;
|
||||
data.attr_stamp = 0.0;
|
||||
data.attr_stamp = 0;
|
||||
}
|
||||
|
||||
} // namespace Atlas::Objects::Entity
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Later in hierarchy tree objtype changes to 'object' when actual game objects are
|
|||
class AnonymousData;
|
||||
typedef SmartPtr<AnonymousData> Anonymous;
|
||||
|
||||
static const int ANONYMOUS_NO = 42;
|
||||
static const int ANONYMOUS_NO = 43;
|
||||
|
||||
/// \brief Starting point for entity hierarchy.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ protected:
|
|||
std::string attr_username;
|
||||
/// Password for account usually
|
||||
std::string attr_password;
|
||||
/// List of characters account can control
|
||||
/// List of characters the account can control.
|
||||
std::vector<std::string> attr_characters;
|
||||
|
||||
/// Send the "username" attribute to an Atlas::Bridge.
|
||||
|
|
@ -203,7 +203,7 @@ extern const std::string CHARACTERS_ATTR;
|
|||
// Inlined member functions follow.
|
||||
//
|
||||
|
||||
const uint32_t USERNAME_FLAG = 1u << 11u;
|
||||
const uint32_t USERNAME_FLAG = 1u << 10u;
|
||||
|
||||
inline void AccountData::setUsername(std::string val)
|
||||
{
|
||||
|
|
@ -211,7 +211,7 @@ inline void AccountData::setUsername(std::string val)
|
|||
m_attrFlags |= USERNAME_FLAG;
|
||||
}
|
||||
|
||||
const uint32_t PASSWORD_FLAG = 1u << 12u;
|
||||
const uint32_t PASSWORD_FLAG = 1u << 11u;
|
||||
|
||||
inline void AccountData::setPassword(std::string val)
|
||||
{
|
||||
|
|
@ -219,7 +219,7 @@ inline void AccountData::setPassword(std::string val)
|
|||
m_attrFlags |= PASSWORD_FLAG;
|
||||
}
|
||||
|
||||
const uint32_t CHARACTERS_FLAG = 1u << 13u;
|
||||
const uint32_t CHARACTERS_FLAG = 1u << 12u;
|
||||
|
||||
inline void AccountData::setCharacters(std::vector<std::string> val)
|
||||
{
|
||||
|
|
@ -424,6 +424,63 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/** Privileged accounts which aren't persisted on the server.
|
||||
|
||||
Later in hierarchy tree objtype changes to 'object' when actual game objects are made.
|
||||
|
||||
*/
|
||||
|
||||
class SystemAccountData;
|
||||
typedef SmartPtr<SystemAccountData> SystemAccount;
|
||||
|
||||
static const int SYSTEM_ACCOUNT_NO = 7;
|
||||
|
||||
/// \brief Privileged accounts which aren't persisted on the server..
|
||||
///
|
||||
/** Later in hierarchy tree objtype changes to 'object' when actual game objects are made.
|
||||
*/
|
||||
class SystemAccountData : public AccountData
|
||||
{
|
||||
protected:
|
||||
/// Construct a SystemAccountData class definition.
|
||||
explicit SystemAccountData(SystemAccountData *defaults = nullptr) :
|
||||
AccountData((AccountData*)defaults)
|
||||
{
|
||||
m_class_no = SYSTEM_ACCOUNT_NO;
|
||||
}
|
||||
/// Default destructor.
|
||||
~SystemAccountData() override = default;
|
||||
|
||||
public:
|
||||
// The parent type for this object's superclass
|
||||
static constexpr const char* super_parent = "account";
|
||||
// The default parent type for this object
|
||||
static constexpr const char* default_parent = "system_account";
|
||||
// The default objtype for this object
|
||||
static constexpr const char* default_objtype = "obj";
|
||||
/// Copy this object.
|
||||
SystemAccountData * copy() const override;
|
||||
|
||||
/// Is this instance of some class?
|
||||
bool instanceOf(int classNo) const override;
|
||||
|
||||
|
||||
public:
|
||||
template <typename>
|
||||
friend class ::Atlas::Objects::Allocator;
|
||||
static Allocator<SystemAccountData> allocator;
|
||||
|
||||
protected:
|
||||
///Resets the object as it's returned to the pool.
|
||||
void reset() override;
|
||||
void free() override;
|
||||
|
||||
private:
|
||||
|
||||
static void fillDefaultObjectInstance(SystemAccountData& data, std::map<std::string, uint32_t>& attr_data);
|
||||
};
|
||||
|
||||
|
||||
/** Games this server hosts
|
||||
|
||||
Later in hierarchy tree objtype changes to 'object' when actual game objects are made.
|
||||
|
|
@ -433,7 +490,7 @@ Later in hierarchy tree objtype changes to 'object' when actual game objects are
|
|||
class GameData;
|
||||
typedef SmartPtr<GameData> Game;
|
||||
|
||||
static const int GAME_NO = 7;
|
||||
static const int GAME_NO = 8;
|
||||
|
||||
/// \brief Games this server hosts.
|
||||
///
|
||||
|
|
@ -490,7 +547,7 @@ Later in hierarchy tree objtype changes to 'object' when actual game objects are
|
|||
class GameEntityData;
|
||||
typedef SmartPtr<GameEntityData> GameEntity;
|
||||
|
||||
static const int GAME_ENTITY_NO = 8;
|
||||
static const int GAME_ENTITY_NO = 9;
|
||||
|
||||
/// \brief All In Game classes and objects.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace Atlas::Objects {
|
||||
|
||||
int Factories::enumMax = 44;
|
||||
int Factories::enumMax = 45;
|
||||
|
||||
void Factories::installStandardTypes()
|
||||
{
|
||||
|
|
@ -30,6 +30,8 @@ void Factories::installStandardTypes()
|
|||
|
||||
addFactory<Entity::AdminData>("admin", Entity::ADMIN_NO);
|
||||
|
||||
addFactory<Entity::SystemAccountData>("system_account", Entity::SYSTEM_ACCOUNT_NO);
|
||||
|
||||
addFactory<Entity::GameData>("game", Entity::GAME_NO);
|
||||
|
||||
addFactory<Entity::GameEntityData>("game_entity", Entity::GAME_ENTITY_NO);
|
||||
|
|
|
|||
|
|
@ -50,9 +50,8 @@ void GenericData::fillDefaultObjectInstance(GenericData& data, std::map<std::str
|
|||
data.attr_objtype = default_objtype;
|
||||
data.attr_serialno = 0;
|
||||
data.attr_refno = 0;
|
||||
data.attr_seconds = 0.0;
|
||||
data.attr_future_seconds = 0.0;
|
||||
data.attr_stamp = 0.0;
|
||||
data.attr_future_milliseconds = 0;
|
||||
data.attr_stamp = 0;
|
||||
}
|
||||
|
||||
} // namespace Atlas::Objects::Operation
|
||||
|
|
|
|||
|
|
@ -17,24 +17,22 @@ namespace Atlas::Objects::Operation {
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class GenericData;
|
||||
typedef SmartPtr<GenericData> Generic;
|
||||
|
||||
static const int GENERIC_NO = 43;
|
||||
static const int GENERIC_NO = 44;
|
||||
|
||||
/// \brief Base operation for all operators.
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class GenericData : public RootOperationData
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,6 +44,11 @@ namespace Entity {
|
|||
typedef SmartPtr<AdminData> Admin;
|
||||
}
|
||||
|
||||
namespace Entity {
|
||||
class SystemAccountData;
|
||||
typedef SmartPtr<SystemAccountData> SystemAccount;
|
||||
}
|
||||
|
||||
namespace Entity {
|
||||
class GameData;
|
||||
typedef SmartPtr<GameData> Game;
|
||||
|
|
|
|||
|
|
@ -18,24 +18,22 @@ namespace Atlas::Objects::Operation {
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class ActionData;
|
||||
typedef SmartPtr<ActionData> Action;
|
||||
|
||||
static const int ACTION_NO = 10;
|
||||
static const int ACTION_NO = 11;
|
||||
|
||||
/// \brief This is base operator for operations that might have effects..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class ActionData : public RootOperationData
|
||||
{
|
||||
|
|
@ -88,7 +86,7 @@ Map editor is main user for this in client side. Server uses this inside "info"
|
|||
class CreateData;
|
||||
typedef SmartPtr<CreateData> Create;
|
||||
|
||||
static const int CREATE_NO = 11;
|
||||
static const int CREATE_NO = 12;
|
||||
|
||||
/// \brief Create new things from nothing using this operator..
|
||||
///
|
||||
|
|
@ -140,24 +138,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class DeleteData;
|
||||
typedef SmartPtr<DeleteData> Delete;
|
||||
|
||||
static const int DELETE_NO = 12;
|
||||
static const int DELETE_NO = 13;
|
||||
|
||||
/// \brief Delete something..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class DeleteData : public ActionData
|
||||
{
|
||||
|
|
@ -205,24 +201,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class SetData;
|
||||
typedef SmartPtr<SetData> Set;
|
||||
|
||||
static const int SET_NO = 13;
|
||||
static const int SET_NO = 14;
|
||||
|
||||
/// \brief Sets attributes for existing entity..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class SetData : public ActionData
|
||||
{
|
||||
|
|
@ -270,24 +264,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class AffectData;
|
||||
typedef SmartPtr<AffectData> Affect;
|
||||
|
||||
static const int AFFECT_NO = 14;
|
||||
static const int AFFECT_NO = 15;
|
||||
|
||||
/// \brief Sets attributes for existing entity..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class AffectData : public SetData
|
||||
{
|
||||
|
|
@ -335,24 +327,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class HitData;
|
||||
typedef SmartPtr<HitData> Hit;
|
||||
|
||||
static const int HIT_NO = 15;
|
||||
static const int HIT_NO = 16;
|
||||
|
||||
/// \brief Operation for when one entity hits another..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class HitData : public AffectData
|
||||
{
|
||||
|
|
@ -405,7 +395,7 @@ More about <a href="move.html">movement here</a>
|
|||
class MoveData;
|
||||
typedef SmartPtr<MoveData> Move;
|
||||
|
||||
static const int MOVE_NO = 16;
|
||||
static const int MOVE_NO = 17;
|
||||
|
||||
/// \brief Change position.
|
||||
///
|
||||
|
|
@ -457,24 +447,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class WieldData;
|
||||
typedef SmartPtr<WieldData> Wield;
|
||||
|
||||
static const int WIELD_NO = 17;
|
||||
static const int WIELD_NO = 18;
|
||||
|
||||
/// \brief Attach a tool to the character entity at a pre-defined location so that the character can use it..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class WieldData : public SetData
|
||||
{
|
||||
|
|
@ -522,24 +510,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class GetData;
|
||||
typedef SmartPtr<GetData> Get;
|
||||
|
||||
static const int GET_NO = 18;
|
||||
static const int GET_NO = 19;
|
||||
|
||||
/// \brief Generic operation for getting info about things..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class GetData : public ActionData
|
||||
{
|
||||
|
|
@ -587,24 +573,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class PerceiveData;
|
||||
typedef SmartPtr<PerceiveData> Perceive;
|
||||
|
||||
static const int PERCEIVE_NO = 19;
|
||||
static const int PERCEIVE_NO = 20;
|
||||
|
||||
/// \brief Generic base operation for perceiving things by eyes, ears, etc....
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class PerceiveData : public GetData
|
||||
{
|
||||
|
|
@ -652,24 +636,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class LookData;
|
||||
typedef SmartPtr<LookData> Look;
|
||||
|
||||
static const int LOOK_NO = 20;
|
||||
static const int LOOK_NO = 21;
|
||||
|
||||
/// \brief Looking at something.
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class LookData : public PerceiveData
|
||||
{
|
||||
|
|
@ -717,24 +699,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class ListenData;
|
||||
typedef SmartPtr<ListenData> Listen;
|
||||
|
||||
static const int LISTEN_NO = 21;
|
||||
static const int LISTEN_NO = 22;
|
||||
|
||||
/// \brief Listen (something).
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class ListenData : public PerceiveData
|
||||
{
|
||||
|
|
@ -782,24 +762,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class SniffData;
|
||||
typedef SmartPtr<SniffData> Sniff;
|
||||
|
||||
static const int SNIFF_NO = 22;
|
||||
static const int SNIFF_NO = 23;
|
||||
|
||||
/// \brief Sniff something.
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class SniffData : public PerceiveData
|
||||
{
|
||||
|
|
@ -847,24 +825,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class TouchData;
|
||||
typedef SmartPtr<TouchData> Touch;
|
||||
|
||||
static const int TOUCH_NO = 23;
|
||||
static const int TOUCH_NO = 24;
|
||||
|
||||
/// \brief Touch something.
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class TouchData : public PerceiveData
|
||||
{
|
||||
|
|
@ -917,7 +893,7 @@ For more about <a href="login.html">out of game atlas here</a>
|
|||
class LoginData;
|
||||
typedef SmartPtr<LoginData> Login;
|
||||
|
||||
static const int LOGIN_NO = 24;
|
||||
static const int LOGIN_NO = 25;
|
||||
|
||||
/// \brief Operation for logging into server.
|
||||
///
|
||||
|
|
@ -974,7 +950,7 @@ For more about <a href="login.html">out of game atlas here</a>
|
|||
class LogoutData;
|
||||
typedef SmartPtr<LogoutData> Logout;
|
||||
|
||||
static const int LOGOUT_NO = 25;
|
||||
static const int LOGOUT_NO = 26;
|
||||
|
||||
/// \brief Operation for logging out.
|
||||
///
|
||||
|
|
@ -1026,24 +1002,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class CommunicateData;
|
||||
typedef SmartPtr<CommunicateData> Communicate;
|
||||
|
||||
static const int COMMUNICATE_NO = 26;
|
||||
static const int COMMUNICATE_NO = 27;
|
||||
|
||||
/// \brief Base operator for all kind of communication..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class CommunicateData : public ActionData
|
||||
{
|
||||
|
|
@ -1096,7 +1070,7 @@ need to relook at that 'Magic voice that steps on something crunchy and makes ma
|
|||
class TalkData;
|
||||
typedef SmartPtr<TalkData> Talk;
|
||||
|
||||
static const int TALK_NO = 27;
|
||||
static const int TALK_NO = 28;
|
||||
|
||||
/// \brief used for talking.
|
||||
///
|
||||
|
|
@ -1148,24 +1122,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class ImaginaryData;
|
||||
typedef SmartPtr<ImaginaryData> Imaginary;
|
||||
|
||||
static const int IMAGINARY_NO = 28;
|
||||
static const int IMAGINARY_NO = 29;
|
||||
|
||||
/// \brief When something is not yet implemented in server, then character can pretend to do something ;-).
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class ImaginaryData : public ActionData
|
||||
{
|
||||
|
|
@ -1213,24 +1185,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class UseData;
|
||||
typedef SmartPtr<UseData> Use;
|
||||
|
||||
static const int USE_NO = 29;
|
||||
static const int USE_NO = 30;
|
||||
|
||||
/// \brief Use a currently wielded tool..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class UseData : public ActionData
|
||||
{
|
||||
|
|
@ -1278,24 +1248,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class ActivityData;
|
||||
typedef SmartPtr<ActivityData> Activity;
|
||||
|
||||
static const int ACTIVITY_NO = 30;
|
||||
static const int ACTIVITY_NO = 31;
|
||||
|
||||
/// \brief Activities performed by entities. This is mainly meant for actions that should be communicated to other entities (like 'digging' or 'twirling').
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class ActivityData : public ActionData
|
||||
{
|
||||
|
|
@ -1343,24 +1311,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class InfoData;
|
||||
typedef SmartPtr<InfoData> Info;
|
||||
|
||||
static const int INFO_NO = 31;
|
||||
static const int INFO_NO = 32;
|
||||
|
||||
/// \brief This is base operator for operations that tell you info about objects or events..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class InfoData : public RootOperationData
|
||||
{
|
||||
|
|
@ -1413,7 +1379,7 @@ Base operator for all kind of perceptions
|
|||
class PerceptionData;
|
||||
typedef SmartPtr<PerceptionData> Perception;
|
||||
|
||||
static const int PERCEPTION_NO = 32;
|
||||
static const int PERCEPTION_NO = 33;
|
||||
|
||||
/// \brief Character perceives something..
|
||||
///
|
||||
|
|
@ -1470,7 +1436,7 @@ Base operator for all kind of perceptions
|
|||
class UnseenData;
|
||||
typedef SmartPtr<UnseenData> Unseen;
|
||||
|
||||
static const int UNSEEN_NO = 33;
|
||||
static const int UNSEEN_NO = 34;
|
||||
|
||||
/// \brief Character failed to interact with another entity because it does not exist..
|
||||
///
|
||||
|
|
@ -1527,7 +1493,7 @@ Base operator for all kind of perceptions
|
|||
class SightData;
|
||||
typedef SmartPtr<SightData> Sight;
|
||||
|
||||
static const int SIGHT_NO = 34;
|
||||
static const int SIGHT_NO = 35;
|
||||
|
||||
/// \brief Character sees something.
|
||||
///
|
||||
|
|
@ -1584,7 +1550,7 @@ Base operator for all kind of perceptions
|
|||
class AppearanceData;
|
||||
typedef SmartPtr<AppearanceData> Appearance;
|
||||
|
||||
static const int APPEARANCE_NO = 35;
|
||||
static const int APPEARANCE_NO = 36;
|
||||
|
||||
/// \brief Character sees something appearing: it literally appears or has it come in visible range.
|
||||
///
|
||||
|
|
@ -1641,7 +1607,7 @@ Base operator for all kind of perceptions
|
|||
class DisappearanceData;
|
||||
typedef SmartPtr<DisappearanceData> Disappearance;
|
||||
|
||||
static const int DISAPPEARANCE_NO = 36;
|
||||
static const int DISAPPEARANCE_NO = 37;
|
||||
|
||||
/// \brief Character sees something disappearing: it literally disappears or has it gone too far to be visible.
|
||||
///
|
||||
|
|
@ -1698,7 +1664,7 @@ Base operator for all kind of perceptions
|
|||
class SoundData;
|
||||
typedef SmartPtr<SoundData> Sound;
|
||||
|
||||
static const int SOUND_NO = 37;
|
||||
static const int SOUND_NO = 38;
|
||||
|
||||
/// \brief Character hears something.
|
||||
///
|
||||
|
|
@ -1755,7 +1721,7 @@ Base operator for all kind of perceptions
|
|||
class SmellData;
|
||||
typedef SmartPtr<SmellData> Smell;
|
||||
|
||||
static const int SMELL_NO = 38;
|
||||
static const int SMELL_NO = 39;
|
||||
|
||||
/// \brief Character smells something.
|
||||
///
|
||||
|
|
@ -1812,7 +1778,7 @@ Base operator for all kind of perceptions
|
|||
class FeelData;
|
||||
typedef SmartPtr<FeelData> Feel;
|
||||
|
||||
static const int FEEL_NO = 39;
|
||||
static const int FEEL_NO = 40;
|
||||
|
||||
/// \brief Character feels something (with fingers usually).
|
||||
///
|
||||
|
|
@ -1864,24 +1830,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class ErrorData;
|
||||
typedef SmartPtr<ErrorData> Error;
|
||||
|
||||
static const int ERROR_NO = 40;
|
||||
static const int ERROR_NO = 41;
|
||||
|
||||
/// \brief Something went wrong.
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class ErrorData : public InfoData
|
||||
{
|
||||
|
|
@ -1929,24 +1893,22 @@ private:
|
|||
|
||||
This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
|
||||
*/
|
||||
|
||||
class ChangeData;
|
||||
typedef SmartPtr<ChangeData> Change;
|
||||
|
||||
static const int CHANGE_NO = 41;
|
||||
static const int CHANGE_NO = 42;
|
||||
|
||||
/// \brief An operation used to signal to clients when things such as types have changed..
|
||||
///
|
||||
/** This is base operation for all other
|
||||
operations and defines basic attributes. You can use this as
|
||||
starting point for browsing whole operation hiearchy. refno refers
|
||||
to operation this is reply for. In examples all attributes that
|
||||
are just as examples (and thus world specific) are started with 'e_'.
|
||||
starting point for browsing whole operation hierarchy. refno refers
|
||||
to the operation that this is a reply for.
|
||||
*/
|
||||
class ChangeData : public InfoData
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ void RootData::setAttr(std::string name, Element attr, const Atlas::Objects::Fac
|
|||
{
|
||||
if (name == ID_ATTR) { setId(attr.moveString()); return; }
|
||||
if (name == PARENT_ATTR) { setParent(attr.moveString()); return; }
|
||||
if (name == STAMP_ATTR) { setStamp(attr.asFloat()); return; }
|
||||
if (name == STAMP_ATTR) { setStamp(attr.asInt()); return; }
|
||||
if (name == OBJTYPE_ATTR) { setObjtype(attr.moveString()); return; }
|
||||
if (name == NAME_ATTR) { setName(attr.moveString()); return; }
|
||||
BaseObjectData::setAttr(std::move(name), std::move(attr), factories);
|
||||
|
|
@ -88,7 +88,7 @@ inline void RootData::sendParent(Atlas::Bridge & b) const
|
|||
inline void RootData::sendStamp(Atlas::Bridge & b) const
|
||||
{
|
||||
if(m_attrFlags & STAMP_FLAG) {
|
||||
b.mapFloatItem(STAMP_ATTR, attr_stamp);
|
||||
b.mapIntItem(STAMP_ATTR, attr_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ bool RootData::instanceOf(int classNo) const
|
|||
|
||||
void RootData::fillDefaultObjectInstance(RootData& data, std::map<std::string, uint32_t>& attr_data)
|
||||
{
|
||||
data.attr_stamp = 0.0;
|
||||
data.attr_stamp = 0;
|
||||
data.attr_objtype = default_objtype;
|
||||
data.attr_parent = default_parent;
|
||||
attr_data[ID_ATTR] = ID_FLAG;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue