Main's model behaviors (every rotation, DoDamage, OnTimer, OnStartup, MoveBackToStart, moves along the model's
local axes), raw terrain reading with scene lookups and scene tools, property model and brick by brick fixes and the
chat server's player count fix, merged onto this branch's structures:
- game messages stay structs; the angular velocity messages join them and the handler sets a message's target
- strips own their speed again and the block names, moves and rotations stay in the shared action table
(PropertyBehaviorActions, which the dashboard's behavior player reads; it now lists rotations too)
- the zone keeps reading its file through ZoneFile and takes the boundaries from it, then loads the raw terrain as main
does; the old dNavigation terrain reader is gone
- the show all response stays a struct and logs a player count mismatch as main does
- the property management component tells models who sent a chat message
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat: raw terrain parsing for scene data
Replace old dNavigation/dTerrain raw parser with new Raw module in
dZoneManager. Parse heightmaps, color maps, and scene maps from .raw
files to determine which scene a position belongs to. Build scene
adjacency graph from terrain data and scene transitions.
Adds NiColor type, SceneColor lookup table, eSceneType enum, terrain
mesh generation with OBJ export, and debug slash commands for scene
visualization.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: deduplicate terrain grid lookup logic, remove unnecessary cast
Add IsValidForSceneLookup(), GetSceneIDAtGrid(), and GridToWorldPos()
to Raw::Chunk. Use them in GenerateTerrainMesh, GetSceneIDFromPosition,
SpawnScenePoints, and SpawnAllScenePoints instead of duplicated inline
math. Remove unnecessary static_cast in LoadSceneTransitionInfo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: add version < 32 support to raw terrain parser
The parser was only correct for v32 files. For v<32:
- colorMapResolution is width-1, not width
- Color map reads width*width*4 bytes (BGRA per-pixel), not colorMapRes^2*4
- No DDS lightmap
- No texture settings byte or blend DDS
- Scene map: v31 reads (colorMapRes+1)^2 cells with border skip,
v<31 skips 1 byte
- No mesh data
Verified against all 309 .raw files across multiple client versions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: log and reject legacy raw terrain format, clean up ReadRaw API
Log a clear message and throw if the zone uses a legacy raw format
(LUZ version < 30) since no known maps use it. Remove ReadLegacyRaw
and the mapVersion parameter from ReadRaw.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: revert v33 scene field renames to unknown1/unknown2
These fields are skipped by the client in every known build (ptr += 12
and ptr += 4). No client ever reads them into a struct. Keep the
original unknown1/unknown2 names from main.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: load the zone without scene lookups when its raw terrain is missing or unreadable
Log at debug when it parses; build the terrain mesh only for the OBJ export; read the zone name and description only for version 31 and later, as the client does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: look up the scene at a position as the client does, in constant time
Chunk bounds span (width - 1) * scale; the nearest scene map cell is used and the far edge is kept one cell inside. Chunks are indexed by grid cell when they form a grid. Skipping reads instead of seeking, so a cut-off file can't seek past the end. Terrain mesh indices follow the vertex order.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat: scene point commands take a step and use brick LOTs from the BrickIDTable
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: rename NiColor::ToXYZ to Luminance
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: raw terrain reading, scene lookup, scene graph and scene commands
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: close the OBJ file before removing it so the test passes on Windows
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: keep the zone boundary lines and read the luz scene count as the client does
Each boundary line's destination is read as a map ID and an instance ID into a LWOZONEID. The scene count is a byte before version 37 and a u32 from it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: name the fourth flair colour byte padding
The client never sets or reads it, so it holds leftover memory.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: keep the scene map of version 31 and older raws
These files have a (resolution + 1)^2 scene map, kept in sceneMapLegacy. Version 31 uses its first resolution rows and columns; older versions are all scene 0, as in the client.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor: simplify the raw heightmap size check
The dimensions are capped at kMaxResolution, so the product can't overflow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: remove the scene point spawn commands and send /getadjacentscenes as one message
The spawn commands were only for testing. /getscene and /getadjacentscenes stay.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
ZoneFileLog keeps the .luz, .lvl, .lutriggers, terrain .raw and navmesh a
world read while loading its zone: absolute path of the loose file (or
the name in the pack), size and an FNV-1a hash of the bytes read.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For a zone file older than version 30 the client reads the terrain in
an older format (OpenTerrain, 1.10.64: mapVersion < 30), and the game
client never reads that format's scene map (only the editor does), so
scene loading goes by the zone's scenes alone. The world now does the
same instead of reading the terrain file as the newer format.
Check in game: nothing to check (all live zones are version 36+).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Zone files before version 33 have no scene IDs. The client gives each
scene its index in the file as its ID, -1 past 255, with layer 0
(LuzReader::ReadScenes, 1.10.64, via the LWOSceneID from the loop
index); the reader left every such scene at ID 0, so a zone with several
scenes had them all collide on one ID.
The version 30 zones on disk have one scene each, so what they read is
unchanged.
Check in game: nothing to check on live worlds (all are version 36+).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Zone files older than version 30 were refused. The client reads them
(1.10.64):
- LuzFile::ReadLUZFile reads a version below 20 as 20;
- LuzReader::ReadScenes reads a scene of a version 20-29 file as a bare
u32 SceneTable ID, with no file name;
- ZoneLoader::ReadZoneFile takes those scenes in SceneTable ID order,
looks each one up in the CDClient SceneTable and, when there is a
row, makes it a scene with the next index (0, 1, ...; -1 past 255) as
its ID and the row's sceneName as its file; a scene with no row is
left out.
ZoneFile now reads these files (FileFormatVersion::Oldest = 20 for
anything older), keeps the SceneTable ID on ZoneScene::sceneTableID,
and ZoneFile::ResolveSceneTable does the lookup the client does; the
world looks the names up in the CDClient SceneTable.
The only such file on disk (version 20) now reads.
Check in game: nothing to check on live worlds (all are version 36+).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LWOSCENEID and LWOSCENEID_INVALID move from dCommonVars.h to
dZoneManager/LWOSCENEID.h; only the zone code uses them. The layer half
is the scene's layer, now the new eSceneType (dCommon/dEnums) instead of
a uint32_t: General (0), Audio (1, the *_audio.lvl scenes named
"Audio") and FX (2, Nexus Tower's *_fxs.lvl scenes named "FXs"), the
three layers the zone files of every client on disk use. ZoneScene's
sceneType is an eSceneType too, so a scene's LWOSCENEID is built from it
directly, and the dashboard compares against eSceneType::General instead
of 0. The zone checksum still hashes the layer's number.
Check in game: every world loads (the zone checksum the client checks is
unchanged), Nexus Tower included.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The client keeps the scene under the player loaded, the scenes the zone
file's transitions connect to it, and the global scene
(Zone::StreamScenesAroundPosition 0x0108a3f0, TerrainManager::GetSceneAtPos
0x01069010, the connected scenes at 0x01066500; transitions naming a
missing scene dropped as Zone::FixupInvalidTransitions 0x010842e0 does).
- ZoneScenes (dCommon): the terrain's scene map lookup and the scene graph,
shared by the world server and the dashboard.
- Objects remember the scene they were placed in (spawners pass theirs on).
- ghosting_scenes=1 (world config, off by default): players get the objects
of their loaded scenes instead of the ones within the ghosting distances;
objects from no scene go by the scene under them. Zones without a scene
map keep distance ghosting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The NexusDashboard-parity dashboard (dDashboardServer) and everything built on it on the experimental branch:
accounts, characters, properties and moderation tools, permissions shared with in-game slash commands, economy
reports, World 3D and property 3D views with client scenery, scheduled events (features, vanity changes, live
events, announcements, restarts), vanity files and events, the CDClient browser, the message inspector with saved
captures, chat filter tools, community challenges, live ops, the AI moderator helper, and the server-side changes
they need.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat: enemy npc pathing
they live 🎉
tested that enemies path all around the world should they have a path configured.
tested that the admiral in gf (at the first camp) paths now.
fixes#1546
* feedback
* change network settings from vector to LwoNameValue
* move settings on Entity to managed memory
* Migrate more members
* chore: remove pointer leakage from raw ldf pointers
* feedback
* fix ci
* add movement ai skeleton
Zone loading code is tested to load and read the correct values using logs. other ldf data is unaffected as I walked around crux and dragons/apes can still spawn and be killed.
* format
Speed is used in more waypoints than not so we may as well reduce repeated references.
tested that the data is still loaded as normal in avant gardens
Update Zone.cpp
Removes the singleton inheritance from dpWorld.
Tested that crux prime, nimbus station, avant gardens and nexus tower still use navmeshes and physics and that physics volumes are still collided with.
* Remove std::couts littered throughout the base
* working
End of optimizations for now
going faster
* Remove extraneous compare function
std::less<LWOSCENEID> already does this in a map.
* gaming
* Update Zone.cpp
* dlu is moving to bitbucket again
* Update Level.cpp
---------
Co-authored-by: Jettford <mrjettbradford@gmail.com>
* Logger: Rename logger to Logger from dLogger
* Logger: Add compile time filename
Fix include issues
Add writers
Add macros
Add macro to force compilation
* Logger: Replace calls with macros
Allows for filename and line number to be logged
* Logger: Add comments
and remove extra define
Logger: Replace with unique_ptr
also flush console at exit. regular file writer should be flushed on file close.
Logger: Remove constexpr on variable
* Logger: Simplify code
* Update Logger.cpp
* Add path height correction on world load
* Increase height because Nexus Tower is tall
* Update height checker
- Only go up and down, do not deviate from the point you are on
- As a backup, use the nearestPoint on the nearestPoly, should detour be able to find one.
- Add a debug assert to fail the program should toReturn differ from nearestPoint[1].
Update dNavMesh.cpp
Update dNavMesh.cpp
* Fix if condition to actually return the value...
---------
Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com>
* fix: Properly read in scene metadata
* Fix reading in rental time and period from property path
* remove useless name in var
change hex to decimal so it's readable
fix scene transistion loop logic
* fix typoe and remove whitespace
* CDClient cleanup and optimization
- Use static function to get table name
- Remove unused GetName function
- Replace above function with a static GetTableName function
- Remove verbose comments
- Remove verbose initializers
- Remove need to specify table name when getting a table by name
- Remove unused typedef for mac and linux
* Re-add unused table
Convert tables to singletons
- Convert all CDClient tables to singletons
- Move Singleton.h to dCommon
- Reduce header clutter in CDClientManager
* Split out LUTriggers into it's own component
* some cleanup
* fix debug log
* use emplace and tryParse
* slight refactor to make the work on startup
rather than at runtime
Also TODO's for getting targets via all the possible methods
* address feedback
* moving branch
* Add deleteinven slash command
* Change name of BRICKS_IN_BBB
* Use string_view instead of strcmp
* Clean up include tree
* Remove unneeded headers from PCH files
Removes unneeded headers from pre-compiled headers. This increases compile time, however reduces development time for most files.
* Update Entity.h
* Update EntityManager.h
* Update GameMessages.cpp
* There it compiles now
Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com>
* cleanup and define all unknowns in zone reading
fix for movement path config reading
* simplify reading and don't use intermediates
* fix spelling
* remove dup variable in struct
read to the proper name that relates to the enum
* First iteration of pack reader and interface
* Fix memory leak and remove logs
* Complete packed asset interface and begin on file loading replacement
* Implement proper BinaryIO error
* Improve AssetMemoryBuffer for reading and implement more reading
* Repair more file loading code and improve how navmeshes are loaded
* Missing checks implementation
* Revert addition of Manifest class and migration changes
* Resolved all feedback.