When a brick by brick save is split into models, each model was centred on
the middle of its bones' origins, on the lowest origin. A brick's origin is at
a corner of it, not its middle, so a single 2x2 came back offset by half a
brick, and the model's floor was taken from the origins rather than from the
bricks.
Now each model is placed as the live server placed it: at the bottom middle
of the box around its bricks. Each brick's own box comes from the client's
brickdb by its design ID and is turned and moved by its bone (all 8 corners),
and the model's box holds every brick's. Its x and z middle and its lowest y
are the new origin, still snapped to the 0.8 grid on x and z, and every bone
moves by that; rigids and rotations are untouched. A design the brickdb has no
box for counts its bones' origins, as before, so no brick is left out.
Lxfml::NormalizePosition and Split take the boxes by design ID, and the brick
by brick save passes the ones read from the client (read on the first save,
then kept).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lxfml::NormalizePosition moved only the first bone of each part, so after a
save a flexible part's other bones kept their world positions while the rest
of the model was moved to its own origin. Now every Bone moves by the same
amount, and the box that places the model holds every bone. Split maps every
bone of a part too, so a rigid system holding only a later bone keeps its
brick.
Only bones move, as the live server did: the Rigid transformations are sent
back as the client wrote them, and rotations are not touched.
Also:
- a model with no readable bone is kept as it is at the origin instead of
getting a center 10000 up
- the math is done in doubles and numbers are written as the shortest text
that reads back as the same float (-0.4, not -0.400002; 12.1678, not
12.1677)
- bricks and rigid systems come out in the file's order, so the same model
always splits into the same bytes
- parts over 5 MB are normalized like any other (the input is capped at
10 MB), and the loop's safety limit no longer drops every later model
The pivot is still snapped to the 0.8 grid (the bricks don't move in the
world; the model's position stays on the grid), which can put it half a
stud from the middle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lxfml::NormalizePosition moved only the first bone of each part, and never
the rigid systems, so after a save a flexible part's other bones and every
Rigid kept their world positions while the rest of the model was moved to
its own origin. Now every Bone and every Rigid moves by the same amount, and
the box that places the model holds every bone. Split maps every bone of a
part too, so a rigid system holding only a later bone keeps its brick.
Also:
- a model with no readable bone is kept as it is at the origin instead of
getting a center 10000 up
- the math is done in doubles and numbers are written as the shortest text
that reads back as the same float (-0.4, not -0.400002; 12.1678, not
12.1677)
- bricks and rigid systems come out in the file's order, so the same model
always splits into the same bytes
- parts over 5 MB are normalized like any other (the input is capped at
10 MB), and the loop's safety limit no longer drops every later model
The pivot is still snapped to the 0.8 grid (the bricks don't move in the
world; the model's position stays on the grid), which can put it half a
stud from the middle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The client asks for a model's metadata (name, owner, behaviors and its blueprint's
bricks and box) when it shows a brick built model item's tooltip, a model on a
property or an exhibit, and shows BBB_LOADING_BLUEPRINT until it gets it. The
world server never answered. It now does as live did: UG data for the model
(found among the player's items by subkey, else among placed models) and, for a
brick built model, the blueprint data from its ugc row and LXFML.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* LXFML SPLITTING
Included test file
* move base to global namespace
* wip need to test
* update last fixes
* update world sending bbb to be more efficient
* Address feedback form Emo in doscord
* Make LXFML class for robust and add more tests to edge cases and malformed data
* get rid of the string copy and make the deep clone have a recursive limit
* cleanup tests
* fix test file locations
* fix file path
* KISS
* add cmakelists
* fix typos
* NL @ EOF
* tabs and split out to func
* naming standard
Tested that models are migrated to the new format a-ok
Tested that the new logic works as expected.
Old code needs to be kept so that models in both states can be brought to modern standards
* Add utilities for formats
* Normalize model positions when placing in the world
Have tested that placing a small and very large model both place and are located at the correct position.
* add migration
* Update Logger.cpp
* add some notes and remove some logs
* change arguments and add eof check
Revert "fix: buff station cycling and dying too soon"
This reverts commit 1c6cb2921e10eb2000ac40007d0c2636ba2ac151.
fix: buff station cycling and dying too soon
Tested that the buff station now only cycles after it has been built and has been alive for 25 seconds.