Another small general problem: the player is always standing exactly on the
bondary between 2 nodes e.g. Y=1.5 is exactly between nodes Y=1 and Y=2.
floatToInt() and myround() will round +/-n.5 always 'outwards' to +/-(n+1),
which means they behave differently depending on where you are: they round
upwards above sea level and downwards when underground. This inconsistency
comes from the way the coordinates are calculated, independent of the
specific C++ code.
The result is a tiny bit of lost performance when moving underground,
because 1 node level more than necessary is checked for collisions. This can
be amended by adding a tiny offset to minpos_f.Y, like @paramat suggested.
This is not an elegant solution, but still better than wasting CPU.
To determine the area (nodes) where a player movement took place
collisionMoveSimple() first took the old/new player coordinates and rounded
them to integers, then added the player character's collision box and
implicitely rounded the result. This has 2 problems:
Rounding the position and the box seperately, then adding the resulting
integers means you get twice the rounding error. And implicit rounding
always rounds towards 0.0, unlike floatToInt(), which rounds towards the
closest integer.
Previous (simplified) behavior: round(pos)+(int)box, for example player at
Y=0.9, body is 1.75m high: round(0.9)+(int)1.75 = 1+1 = 2.
==> A character's height of 1.75m always got rounded down to 1m, its width
of +/-0.3 even became 0.
Fixed by adding the floats first, then rounding properly: round(pos+box) =
round(0.9+1.75) = round(2.65) = 3.
* Environment code refactoring
* Cleanup includes & class declarations in client & server environment to improve build speed
* ServerEnvironment::m_gamedef is now a pointer to Server instead of IGameDef, permitting to cleanup many casts.
* Cleanup IGameDef
* Move ITextureSource* IGameDef::getTextureSource() to Client only.
* Also move ITextureSource *IGameDef::tsrc() helper
* drop getShaderSource, getSceneManager, getSoundManager & getCamera abstract call
* drop unused emerge() call
* cleanup server unused functions (mentionned before)
* Drop one unused parameter from ContentFeatures::updateTextures
* move checkLocalPrivilege to Client
* Remove some unnecessary casts
* create_formspec_menu: remove IWritableTextureSource pointer, as client already knows it
* Fix some comments
* Change required IGameDef to Server/Client pointers
* Previous change that game.cpp sometimes calls functions with Client + InventoryManager + IGameDef in same functions but it's the same objects
* Remove duplicate Client pointer in GUIFormSpecMenu::GUIFormSpecMenu
* drop ClientMap::sectorWasDrawn which is unused
* Create UnitSAO, a common part between PlayerSAO & LuaEntitySAO
* Move breath to PlayerSAO & LocalPlayer
* Migrate m_yaw from (Remote)Player & LuaEntitySAO to UnitSAO
* Migrate m_yaw from Player to LocalPlayer for client
* Move some functions outside of player class to PlayerSAO/RemotePlayer or LocalPlayer depending on which class needs it
* Move pitch to LocalPlayer & PlayerSAO
* Move m_position from Player to LocalPlayer
* Move camera_barely_in_ceiling to LocalPlayer as it's used only there
* use PlayerSAO::m_base_position for Server side positions
* remove a unused variable
* ServerActiveObject::setPos now uses const ref
* use ServerEnv::loadPlayer unconditionnaly as it creates RemotePlayer only if it's not already loaded
* Move hp from Player to LocalPlayer
* Move m_hp from LuaEntitySAO to UnitSAO
* Use m_hp from PlayerSAO/UnitSAO instead of RemotePlayer
It was caused by player not moving because fall was prevented, but their
velocity still increasing, causing fatal fall damage when world was
finally loaded. This commit fixes it by setting player velocity to zero
when the world around them is not loaded.
NDT_CONNECTED attempts to connect to any side of nodes that it can
connect to, which is troublesome for FACEDIR type nodes that generally
may only have one usable face, and can be rotated.
We introduce a node parameter `connect_sides` that is valid for
any node type. If specified, it lists faces of the node (in "top",
"bottom", "front", "left", "back", "right", form, as array) that
connecting nodeboxes can connect to. "front" corresponds to the south
facing side of a node with facedir = 0.
If the node is rotatable using *simple* FACEDIR, then the attached
face is properly rotated before checking. This allows e.g. a chest
to be attached to only from the rear side.
We introduce a new nodebox type "connected", and allow these nodes to
have optional nodeboxes that connect it to other connecting nodeboxes.
This is all done at scenedraw time in the client. The client will
inspect the surrounding nodes and if they are to be connected to,
it will draw the appropriate connecting nodeboxes to make those
connections.
In the node_box definition, we have to specify separate nodeboxes for
each valid connection. This allows us to make nodes that connect only
horizontally (the common case) by providing optional nodeboxes for +x,
-x, +z, -z directions. Or this allows us to make wires that can connect
up and down, by providing nodeboxes that connect it up and down (+y,
-y) as well.
The optional nodeboxes can be arrays. They are named "connect_top,
"connect_bottom", "connect_front", "connect_left", "connect_back" and
"connect_right". Here, "front" means the south facing side of the node
that has facedir = 0.
Additionally, a "fixed" nodebox list present will always be drawn,
so one can make a central post, for instance. This "fixed" nodebox
can be omitted, or it can be an array of nodeboxes.
Collision boxes are also updated in exactly the same fashion, which
allows you to walk over the upper extremities of the individual
node boxes, or stand really close to them. You can also walk up
node noxes that are small in height, all as expected, and unlike the
NDT_FENCELIKE nodes.
I've posted a screenshot demonstrating the flexibility at
http://i.imgur.com/zaJq8jo.png
In the screenshot, all connecting nodes are of this new subtype.
Transparent textures render incorrectly, Which I don't think is
related to this text, as other nodeboxes also have issues with this.
A protocol bump is performed in order to be able to send older clients
a nodeblock that is usable for them. In order to avoid abuse of users
we send older clients a "full-size" node, so that it's impossible for
them to try and walk through a fence or wall that's created in this
fashion. This was tested with a pre-bump client connected against a
server running the new protocol.
These nodes connect to other nodes, and you can select which ones
those are by specifying node names (or group names) in the
connects_to string array:
connects_to = { "group:fence", "default:wood" }
By default, nodes do not connect to anything, allowing you to create
nodes that always have to be paired in order to connect. lua_api.txt
is updated to reflect the extension to the node_box API.
Example lua code needed to generate these nodes can be found here:
https://gist.github.com/sofar/b381c8c192c8e53e6062
On world load the collision code can not see node boxes, since the
nodes have not been loaded. Thus it collided only at the next full
node. However, standing on a slab on world load leaded to sinking into
it until the world finished loading. Then one maybe fell further, if
the node below was not walkable.
Now, with this commit, when no node around the player has been loaded
it simply does not move the player.
Move debug streams to log.cpp|h
Move GUI-related globals to clientlauncher
Move g_settings and g_settings_path to settings.cpp|h
Move g_menuclouds to clouds.cpp|h
Move g_profiler to profiler.cpp|h