Decompile fn_21286 (CGameMode::MarkWorldOcclusion)

Batch #17240 by kyoshi: 0 byte-identical, 1 confirmed by peer review.

- fn_21286 CGameMode::MarkWorldOcclusion: logic confirmed by peer review

Peer-reviewed-by: Toshiro, cremane, bibinir
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
ragnarok-clanker 2026-11-11 17:00:10 +00:00
commit 9518cfdc5d
3 changed files with 24 additions and 32 deletions

View file

@ -401,6 +401,7 @@ public:
std::vector<char> BuildActorEntryPacket(CGameActor* actor, std::uint16_t packetType);
CGameActor* NewActor(int job);
void UpdateHoverNameBalloon();
void MarkWorldOcclusion();
void ShowHoverActorName(CGameActor* actor);
const char* DragItemName();
void AddPendingItemPickup(int value);

View file

@ -8712,7 +8712,6 @@ int CGameMode::ProcessGroundClick(int result) {
return result;
}
#include "Contents/World/WorldOcclusion.h"
#include "UI/Dialogs/UIMenuWnd.h"
#include "UI/Window/InputFocus.h"
@ -9016,13 +9015,7 @@ void CGameMode::ProcessInput() {
}
}
if (this->scene && this->scene->player && g_renderer) {
MarkScreenWorldOcclusion(
this->scene->player->render.screenX, this->scene->player->render.screenY, g_renderer->viewport.uiScaleY, this->camera->frame.eye,
this->camera->frame.inverse.values, this->scene->player->render.position.y, this->camera->camera.distance, this->scene->spatial, *this->scene->ground,
this->checkGroundAlpha != 0
);
}
this->MarkWorldOcclusion();
if (this->isPlayerDead == 0 && (this->isOnQuest == 0 || this->scene->player->actorWindows[3] != 0) && !blocker && g_windowMgr.itemStoreWnd == nullptr &&
!g_windowMgr.LookupWindow(WID_RUNESYSTEMWND)) {

View file

@ -1,20 +1,32 @@
#include "Contents/Ground/GroundGeometry.h"
#include "Contents/Models/ModelActor.h"
#include "Contents/World/WorldOcclusion.h"
#include "Client/Mode/CGameMode.h"
#include "Contents/Actors/Pc.h"
#include "Contents/World/World.h"
#include "Contents/Camera/Camera.h"
#include "Contents/World/WorldRayQuery.h"
#include "Contents/World/WorldSpatialTree.h"
#include "Render/Renderer.h"
#include "Utility/Math/ScalarConversion.h"
#include <cstring>
// INLINED
void MarkWorldOcclusionRay(const float* ray, float actorLimit, float groundLimit, WorldSpatialTree& root, GroundGeometry& ground, bool markGround) {
float actorRay[7];
std::memcpy(actorRay, ray, 6 * sizeof(float));
actorRay[6] = actorLimit;
// OFFSET: 0x00CD5AD0
// FUNCTION: fn_21286
void CGameMode::MarkWorldOcclusion() {
if (!this->scene || !this->scene->player || !g_renderer) {
return;
}
const int screenX = this->scene->player->render.screenX;
const int screenY = static_cast<int>(static_cast<float>(this->scene->player->render.screenY) - g_renderer->viewport.uiScaleY * 23.0f);
WorldRayQuery query;
query.Collect(ray, &root);
float ray[6]{};
g_renderer->viewport.Ray(screenX, screenY, this->camera->frame.eye, this->camera->frame.inverse.values, ray);
float actorRay[7];
std::memcpy(actorRay, ray, sizeof(ray));
actorRay[6] = (this->scene->player->render.position.y + this->camera->camera.distance) - 16.0f;
query.Collect(ray, &this->scene->spatial);
for (WorldSpatialTree* node : query.nodes) {
for (C3dActor* model : node->objects) {
@ -22,7 +34,7 @@ void MarkWorldOcclusionRay(const float* ray, float actorLimit, float groundLimit
}
}
if (markGround) {
if (this->checkGroundAlpha) {
for (WorldSpatialTree* node : query.nodes) {
int row = node->groundCells[1];
@ -30,7 +42,7 @@ void MarkWorldOcclusionRay(const float* ray, float actorLimit, float groundLimit
int column = node->groundCells[0];
while (column <= node->groundCells[2]) {
ground.MarkRay(ray, column, row, groundLimit);
node->ground->MarkRay(ray, column, row, actorRay[6]);
++column;
}
@ -39,17 +51,3 @@ void MarkWorldOcclusionRay(const float* ray, float actorLimit, float groundLimit
}
}
}
// OFFSET: 0x00CD5AD0
// FUNCTION: fn_21286
void MarkScreenWorldOcclusion(
int screenX, int screenY, float rendererScale, const float* origin, const float* cameraMatrix, float playerHeight,
float cameraHeight, WorldSpatialTree& root, GroundGeometry& ground, bool markGround
) {
const float shifted = static_cast<float>(screenY) - rendererScale * 23.0f;
const int y = TruncateToInt(shifted);
float ray[6]{};
g_renderer->viewport.Ray(screenX, y, origin, cameraMatrix, ray);
const float limit = (playerHeight + cameraHeight) - 16.0f;
MarkWorldOcclusionRay(ray, limit, limit, root, ground, markGround);
}