Don't keep the time in field, updated only at poll requests. Instead
calculate it when it's needed.
This fixes an old bug where all client movements were slightly
incorrect. The time was only recalculated at WorldRouter::poll calls. However,
when polling for IO the process waited up to 100 milliseconds. That
meant that any client received operation would get an on average 50
milliseconds offset in it's registered time. The result of this was that
most Move operations would be slightly incorrect, resulting in jerky
movement.
The "respawning" property makes an entity respawn instead of being
deleted. It intercepts the Delete op and instead of deleting the entity
it moves it to the specified spawn point.
A typical use case of this is to place the property on any user
controlled entity, thus making sure that it's never deleted and istead
respawned when killed or defeated.
While in suspended state all "Tick" ops will be placed in a special queue
and not delivered until the world is resumed.
This is of most use for world authors who want to edit the world and
not worry about entities being altered.
All IG code should use the interface of LocatedEntity when dealing
with any entity, rather than sometimes requiring Entity. Add virtual
functions to the interface where required, and modify all other interfaces
to stop them using Entity. This makes the code way cleaner, and much better
de-coupled.
* common/Monitors.cpp, common/Monitors.h: Add dynamic variable
monitor functionality, allowing arbitrary variables to appear
in the monitors output.
* server/ServerRouting.cpp: Use the new monitor functionality for
variables prebviously pushed to monitors once.
* server/WorldRouter.cpp, server/WorldRouter.h: Add a count of
in-game entities. Expose it to the monitors.
* common/BaseWorld.h: Modify the addEntity() function so we no longer
need to specify whether it needs to be set up, as nowhere was ever
specifying.
* server/WorldRouter.cpp, server/WorldRouter.h: Implement the modified
BaseWorld API, and ensure all entities are sent Setup operations
for now.
* tests/TestWorld.h: Update test world so it implements the interface
correctly.
* client/CreatorClient.cpp, client/CreatorClient.h,
client/Py_CreatorClient.cpp, common/BaseWorld.h, common/types.h,
modules/Location.cpp, modules/Location.h,
rulesets/AtlasProperties.cpp, rulesets/AtlasProperties.h,
rulesets/BaseMind.cpp, rulesets/Character.cpp, rulesets/Character.h,
rulesets/Entity.cpp, rulesets/Entity.h,
rulesets/EntityProperties.cpp, rulesets/LocatedEntity.cpp,
rulesets/LocatedEntity.h, rulesets/MemEntity.cpp,
rulesets/MemEntity.h, rulesets/MemMap.cpp, rulesets/Motion.cpp,
rulesets/Motion.h, rulesets/Py_Location.h, rulesets/Py_Mind.cpp,
rulesets/Py_Thing.cpp, rulesets/Py_Thing.h,
rulesets/PythonMindScript.h, rulesets/PythonScript.h,
rulesets/PythonThingScript.cpp, rulesets/PythonThingScript.h,
rulesets/Python_API.cpp, rulesets/Script.cpp, rulesets/Script.h,
rulesets/Thing.cpp, rulesets/World.cpp, server/WorldRouter.cpp,
server/WorldRouter.h: Refactor all the entity code so there is now
a new base class for entities in the world simulation, and in the
mind which only contains things which are trully common to both.
This moves a lot of functionality which should not have been
present in mind entities away, and makes that code safer and more
efficient.
* tests/TestWorld.h: Update the test world API to match the base
class.
* server/WorldRouter.h, server/WorldRouter.cpp: Re-write the way
broadcasts are handled, so the code is cleaner, and non
perception operations are properlly broadcast without the
need to store an explicit list of all entities in the world.
* common/BaseWorld.h, rulesets/Creator.cpp, rulesets/World.cpp,
server/WorldRouter.cpp, server/WorldRouter.h, tests/TestWorld.h:
Pass perceptive entities to the world by pointer rather than
by ID, avoiding a lookup in the dictionary.
* common/BaseWorld.h, rulesets/Character.cpp,
server/EntityFactory.cpp, server/EntityFactory.h,
server/TaskFactory.h, server/WorldRouter.cpp,
server/WorldRouter.h: Specify the target base type that a given
task is valid for, and provide target type when activating a task.
* data/mason.xml: Add target base types to most task rules.
* rulesets/mason/world/tasks/Combat.py: Fix the copyright date.
* rulesets/mason/world/tasks/Sharpen.py: Proof of concept task
for turning logs into stakes.
* common/BaseWorld.h, server/WorldRouter.h, server/WorldRouter.cpp:
Add interface to allow world entities to activate tasks based on
tool use operations.
* server/EntityFactory.h, server/EntityFactory.cpp: Add method which
createa a new task in response to an activation request.
* rulesets/Character.cpp: When a character uses a tool, use the
tool type and operation to activate a task if one is available.
* common/BaseWorld.h: Add factory method for new tasks to the world
interface.
* rulesets/Character.cpp: Use world interface to create combat
task, rather than using EntityFactory directly.
* server/WorldRouter.h, server/WorldRouter.cpp: Implement the
new task method in the core world object.
* server/WorldRouter.h, server/WorldRouter.cpp: Add a second op
queue for ops which do not have a time specified, so it is
cheaper to add ops to the queue if they are to be dispatched
immediatly.
* common/BaseWorld.h, server/WorldRouter.cpp, server/WorldRouter.h:
Modify world interface so it takes a string mode when adjusting
the height of entities. Handle floating and swimming entities
accordingly.
* rulesets/Thing.cpp: Change the order in which mode is checked
so it is available when adjusting height.
* rulesets/mason/define_world.py: Randomise height of fish, so they
look more like they are swimming.
* common/BaseWorld.h, rulesets/Character.cpp, rulesets/Py_World.cpp,
rulesets/PythonThingScript.cpp, rulesets/Stackable.cpp,
rulesets/Thing.cpp, rulesets/World.cpp, server/Account.cpp,
server/Admin.cpp, server/Connection.cpp, server/EntityFactory.cpp,
server/Restoration.cpp, server/WorldRouter.cpp, server/WorldRouter.h:
Rename some functions in the World interface so they make more
sense.
* rulesets/Entity.cpp, rulesets/Entity.h: Add destroyed flag to
Entity so we can tell if its no longer in the world.
* server/WorldRouter.cpp: Cut down the special case handling of
delete ops as we can now broadcast ops from entities that
have been removed from the world.
* server/WorldRouter.h, server/WorldRouter.cpp: Change operation()
to take a reference to the entity the op is from. Re-work
main idle loop to pas the entity to operation, and handle
the op queue more efficiently.
* common/BaseWorld.h, rulesets/Entity.h, rulesets/MemMap.cpp,
server/Account.cpp, server/WorldRouter.cpp, server/WorldRouter.h:
Use reference count functions to handle deleting entities.
Modify main op queue to hold a reference to the entity the op
is from. Fix up arg naming conventions in WorldRouter.
* common/BaseWorld.h, server/CommServer.cpp, server/ServerRouting.cpp,
server/ServerRouting.h, server/ServerRouting_methods.h,
server/WorldRouter.cpp, server/WorldRouter.h: Clean up the way the
idle functions work, reducing the number of calls to time related
system calls.
* common/BaseEntity.cpp, common/BaseWorld.h, common/refno.h,
common/serialno.h, rulesets/Character.cpp, rulesets/Creator.cpp,
rulesets/World.h, server/Account.cpp, server/Admin.cpp,
server/Connection.cpp, server/Lobby.cpp, server/ServerRouting.h,
server/WorldRouter.cpp, server/WorldRouter.h, tests/Creatortest.cpp,
tests/Worldtest.cpp: Simplify the way operation refnos and serialnos
are handled, getting rid of some unnecessary virtual methods and
functions.