* 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>
* add rotation behavior logic (not working correctly for multiple axes)
* Fix FetchContent_Declare speed
* remove manual quaternion math
* feat: working rotations
* remove flag
* feat: make directional movements based on model rotation and not world axes
* poggers rotation on the strip
* Add OnStartup and OnTimer
* go home works
* Add DoDamage behavior and dont try and start the same node multiple times
* fix: pause bbb models
* interrupt rotations and save interrupt count across resets
* feat: logging structure improvements
tested that logs are sorted by the folder argument and that the directories are created recursively.
tested that crash dumps follow the same exact name (+Crash_...name..._pid.log) so you can match the crash dump to the corresponding log file much easier
* Potential fix for pull request finding 'Use parsed cloneID when constructing the log folder'
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* const
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* feat: Add cheat detection knowledge
tested that getting kicked correctly displays the reasons why and their corresponding values
tested that a user with developer permissions is not kicked for said funness
tested that logs are correct for those funness values which i could actually trigger
* fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
tested that aggro is reset correctly and enemies no longer infinitely path to players. Tether now properly calculates the time to tether instead of guessing
* feat: debugger additions
Add type field for links in flash
Add warning level for dangerous buttons
fix uninitialzied memory with jetpack variable
remove a bunch of duplicated position push code
tested that the ui is still functional and components with multiple physics components have all their details visible.
tested that jetpack is initialized now
* remove amf3 header
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fixes
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* refactor: update behavior slot determination to use equipLocation instead of itemType
* fix: improve skill management in InventoryComponent to ensure correct client updates
* feat: enhance possession mechanics with skill set integration and improved message handling
* fix: restore SetPossessor in Mount() and scope IsRacing to vehicles
SetPossessor was missing from Mount(), breaking direct possessions via
PossessableComponent::OnUse which bypasses HandlePossession. IsRacing
now only set/cleared when the mount has HavokVehiclePhysicsComponent,
preventing non-vehicle possessions from incorrectly affecting the
distance-driven statistic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: testmap improvements
fixes#1191
removed the force flag because it would only work to let you softlock your character.
tested that taking the lego club door now spawns you at the lego club/ns lego club doors always vs letting you spawn where ever.
tested that a testmap no longer spawns you where you last were in a zone and instead spawns you at the spawn point
inspect allows you to inspect zoneControl and localCharacter now
updated docs with the new info
* Update Entity.cpp
* feat: spawner weights
* remove ref
* default weights to 1
* fix: remove team member if they've logged out
tested that if i logout, after 20 seconds the team member is removed.
* fix: enemies snapping to the incorrect position if they had a path
tested that ags enemies no longer snap backwards a large amount
* fix: move the home point so we can aggro correctly
* fix: add range checks to npc combat skill behavior
tested that all enemies now cast skills smartly based on range to targets, and do not cast skills if they are out of range.
fixes an issue where the spider queen could attack you outside the normal range
fixes an issue where entering happy flower caused you to need to restart the client
fixes#965
* feedback
* feat: enemies now use weights on their attacks
tested that 8 times out of 10, in close range, spiders did a web attack instead of a melee attack, vs the prior behavior of always following a pattern
fixes#2002
* feedback
* 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
tested that the pipe now spawns a ROCK that you can build. This ROCK you build spawns the PIPE now.
new bug: if you start building the ROCK and stop, the pipe will spawn instead of the previous rock.
* fix: bugs in private instances causing master crashes
tested that creating a private instance and shutting down the server no longer crashes master
* Update InstanceManager.cpp
* feat: implement missing precondition types (20, 21, 23) and pet checks
Add DoesNotHaveFlag (23), NotFreeTrial (20), and MissionActive (21) to
PreconditionType and implement their checks. Also implement PetDeployed
and IsPetTaming using PetComponent static helpers, matching client
behavior — both are simple boolean checks with no LOT comparison.
LegoClubMember is set to always pass as DLU has no membership concept.
* fix: update TODO comments for team check and racing licence preconditions
* type
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: security vulnerabilities
Tested that all functions related to the touched files work
will test sqlite on a CI build
* fix failing test
* ai feedback
* add buffer size checking
* use c_str
* dont log session key
* Try this for a mac definition
* be quiet apple
* feat: enhance CI/CD workflows with Docker support and artifact management
* chore: update GitHub Actions workflows with version pinning and permission adjustments
* feat: update CI workflows to support new OS versions and improve artifact handling
* chore: remove macOS-specific installation of libssl and XCode switching
* fix: update artifact zipping logic to target build directories in canary and release workflows
* chore: update actions/checkout to version 6.0.2 in CI workflow
* fix: update continue-on-error condition in CI workflow and add macOS RelWithDebInfo build preset
* fix: rename step to accurately reflect Docker image signing process
* don't ignore pdb's
Does not save, only works for this world. Fixed an issue where the incorrect comparison was used to make players invisible again (the same check that makes then INvisible needs to make them visible.)
* fix: security fixes
dont print passwords for worlds
bound strings from clients
actually enable encryption between rakpeers
dont allow underflow when reading a string
Tested that packets are encrypted
tested that models can still be built
tested that combat still works
* add check
* use c++ nullptr instead of NULL
* initialize to 0
* globalize constant (should be in a namespace at least in the future)
* Update GameMessages.cpp
* check bounds
* fix: mission progression undefined behavior
defer the sub calls until after the loop has finished, that way no ub happens. tested that mission progression all the way up until joining a faction still works and meta missions still function.
* default initialize
* Update MissionComponent.h