Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89aafe2b43 | ||
|
|
2a3befd970 |
@@ -0,0 +1,54 @@
|
|||||||
|
name: V34 ExitFix Baseline
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- test/v34-exitfix-baseline
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: mlugg/setup-zig@v2
|
||||||
|
with:
|
||||||
|
version: '0.16.0'
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
zig build all-variants -Doptimize=ReleaseSmall \
|
||||||
|
-Dweirdperformance=false \
|
||||||
|
-Doutline=true \
|
||||||
|
-Dcustomassets=true \
|
||||||
|
-Dtransmogfix=true
|
||||||
|
|
||||||
|
- name: Package
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
rm -rf package dist
|
||||||
|
mkdir -p package/DLL package/Interface/AddOns/WeirdUtils_Outline dist
|
||||||
|
cp zig-out/variants/outline.dll package/DLL/outline.dll
|
||||||
|
cp src/outline/addon/Bindings.xml package/Interface/AddOns/WeirdUtils_Outline/
|
||||||
|
cp src/outline/addon/Outline.lua package/Interface/AddOns/WeirdUtils_Outline/
|
||||||
|
cp src/outline/addon/WeirdUtils_Outline.toc package/Interface/AddOns/WeirdUtils_Outline/
|
||||||
|
printf '%s\n' \
|
||||||
|
'V34 stable + process-exit safety only.' \
|
||||||
|
'Runtime Outline code is otherwise identical to stable/outline-v34-autofix.' \
|
||||||
|
'main is untouched.' \
|
||||||
|
'WeirdPerformance is disabled in this standalone build and not modified.' \
|
||||||
|
> package/README_TEST.txt
|
||||||
|
(cd package && sha256sum DLL/outline.dll > SHA256SUMS.txt && zip -r ../dist/WeirdUtils_V34_EXITFIX_BASELINE.zip DLL Interface README_TEST.txt SHA256SUMS.txt)
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: WeirdUtils-V34-EXITFIX-BASELINE
|
||||||
|
path: dist/WeirdUtils_V34_EXITFIX_BASELINE.zip
|
||||||
|
if-no-files-found: error
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
name: V40 Attached Model Outline Test
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- test/v40-attached-model-outline
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-v40:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout V40 branch
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install Zig
|
|
||||||
uses: mlugg/setup-zig@v2
|
|
||||||
with:
|
|
||||||
version: '0.16.0'
|
|
||||||
|
|
||||||
- name: Build standalone variants
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
zig build all-variants -Doptimize=ReleaseSmall \
|
|
||||||
-Dweirdperformance=false \
|
|
||||||
-Doutline=true \
|
|
||||||
-Dcustomassets=true \
|
|
||||||
-Dtransmogfix=true
|
|
||||||
|
|
||||||
- name: Assemble V40 outline-only test package
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
rm -rf package dist
|
|
||||||
mkdir -p package/DLL
|
|
||||||
mkdir -p package/Interface/AddOns/WeirdUtils_Outline
|
|
||||||
mkdir -p dist
|
|
||||||
|
|
||||||
cp zig-out/variants/outline.dll package/DLL/outline.dll
|
|
||||||
cp src/outline/addon/Bindings.xml package/Interface/AddOns/WeirdUtils_Outline/Bindings.xml
|
|
||||||
cp src/outline/addon/Outline.lua package/Interface/AddOns/WeirdUtils_Outline/Outline.lua
|
|
||||||
cp src/outline/addon/WeirdUtils_Outline.toc package/Interface/AddOns/WeirdUtils_Outline/WeirdUtils_Outline.toc
|
|
||||||
|
|
||||||
printf '%s\n' \
|
|
||||||
'WeirdUtils V40 Attached Model Outline' \
|
|
||||||
'Base: exact V38 Retail Polish + AutoTarget + AutoRehook + ExitFix.' \
|
|
||||||
'main is untouched.' \
|
|
||||||
'WeirdPerformance is disabled in this standalone build and not modified.' \
|
|
||||||
'Engine-proven WoW 1.12.1 attachment layout from 0x712F70:' \
|
|
||||||
'- child +0x1CC = parent/root CM2Model' \
|
|
||||||
'- child +0x1D0 = attachment id' \
|
|
||||||
'- root +0x1DC = child-list head' \
|
|
||||||
'- child +0x1E4 = next sibling' \
|
|
||||||
'V40 makes direct attached M2 models inherit the root target outline.' \
|
|
||||||
'No new hook, no linked-list traversal, no game-memory writes.' \
|
|
||||||
> package/README_TEST.txt
|
|
||||||
|
|
||||||
(
|
|
||||||
cd package
|
|
||||||
sha256sum DLL/outline.dll > SHA256SUMS.txt
|
|
||||||
zip -r ../dist/WeirdUtils_V40_ATTACHED_MODEL_OUTLINE.zip DLL Interface README_TEST.txt SHA256SUMS.txt
|
|
||||||
)
|
|
||||||
|
|
||||||
- name: Upload V40 package
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: WeirdUtils-V40-ATTACHED-MODEL-OUTLINE
|
|
||||||
path: dist/WeirdUtils_V40_ATTACHED_MODEL_OUTLINE.zip
|
|
||||||
if-no-files-found: error
|
|
||||||
+4
-4
@@ -1053,10 +1053,10 @@ pub export fn DllMain(
|
|||||||
switch (reason) {
|
switch (reason) {
|
||||||
1 => install(),
|
1 => install(),
|
||||||
0 => {
|
0 => {
|
||||||
// ExitFix: when lpReserved is non-null, Windows is terminating the
|
// Process-exit safety: when Windows is terminating the whole
|
||||||
// whole process. Do not call into D3D9/COM or other DLLs from
|
// process, do not call heavy cleanup from DLL_PROCESS_DETACH.
|
||||||
// DLL_PROCESS_DETACH during global teardown; the OS will reclaim
|
// Resources are reclaimed by the OS. Explicit FreeLibrary still
|
||||||
// those resources. Keep full uninstall for explicit FreeLibrary.
|
// performs the normal uninstall path.
|
||||||
if (reserved == null) uninstall();
|
if (reserved == null) uninstall();
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- Outline addon (embedded in DLL, loaded from memory)
|
-- Outline addon (embedded in DLL, loaded from memory)
|
||||||
-- Part of WeirdUtils - only loaded when outline module is compiled
|
-- Part of WeirdUtils - only loaded when outline module is compiled
|
||||||
|
|
||||||
OUTLINE_VERSION = 40
|
OUTLINE_VERSION = 1
|
||||||
|
|
||||||
BINDING_HEADER_OUTLINE = "Outline"
|
BINDING_HEADER_OUTLINE = "Outline"
|
||||||
|
|
||||||
|
|||||||
+21
-42
@@ -57,14 +57,6 @@ var orig_reset: usize = 0;
|
|||||||
var d3d9_vtable: ?[*]usize = null;
|
var d3d9_vtable: ?[*]usize = null;
|
||||||
var hooks_installed: bool = false;
|
var hooks_installed: bool = false;
|
||||||
|
|
||||||
/// ExitFix: once shutdown begins, no code path may reinstall D3D9 hooks.
|
|
||||||
var shutdown_started: bool = false;
|
|
||||||
|
|
||||||
pub fn beginShutdown() void {
|
|
||||||
shutdown_started = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Sticky diagnostics for the in-game OutlineDebug() command.
|
// Sticky diagnostics for the in-game OutlineDebug() command.
|
||||||
pub var debug_endscene_seen: bool = false;
|
pub var debug_endscene_seen: bool = false;
|
||||||
pub var debug_dip_seen: bool = false;
|
pub var debug_dip_seen: bool = false;
|
||||||
@@ -122,7 +114,6 @@ pub var debug_late_rehook_succeeded: bool = false;
|
|||||||
/// If the current entries are no longer ours, chain whatever is there now as
|
/// If the current entries are no longer ours, chain whatever is there now as
|
||||||
/// the new originals, then patch the three entries again.
|
/// the new originals, then patch the three entries again.
|
||||||
pub fn lateRehookIfLost() bool {
|
pub fn lateRehookIfLost() bool {
|
||||||
if (shutdown_started) return false;
|
|
||||||
debug_late_rehook_attempted = true;
|
debug_late_rehook_attempted = true;
|
||||||
|
|
||||||
const cur = getD3D9VTable() orelse return false;
|
const cur = getD3D9VTable() orelse return false;
|
||||||
@@ -741,45 +732,34 @@ const jfa_prop_src =
|
|||||||
"mov oC0.xy, r8.xy\n" ++
|
"mov oC0.xy, r8.xy\n" ++
|
||||||
"mov oC0.zw, c1.xx\n";
|
"mov oC0.zw, c1.xx\n";
|
||||||
|
|
||||||
/// V38 RETAIL-POLISH: keep the proven V34/V36/V37 JFA and refine only
|
/// V32 POLISH: hard 3px outline, no feather.
|
||||||
/// the final alpha profile. Still only two texture reads.
|
/// c0 = (screen_width, screen_height, radius_px=3, 0).
|
||||||
/// c0 = (screen_width, screen_height, core_radius_px, halo_radius_px).
|
/// The shader squares radius_px and emits a binary 0/1 edge alpha.
|
||||||
const jfa_decode_src =
|
const jfa_decode_src =
|
||||||
"ps_3_0\n" ++
|
"ps_3_0\n" ++
|
||||||
// c1 = zero, one, halo alpha, -interior threshold
|
"def c1, 0.0, 1.0, -0.002, 0.0\n" ++
|
||||||
"def c1, 0.0, 1.0, 0.17, -0.002\n" ++
|
|
||||||
// pale Retail-like yellow-green
|
|
||||||
"def c2, 1.0, 0.96, 0.62, 0.0\n" ++
|
|
||||||
// core alpha
|
|
||||||
"def c3, 0.84, 0.0, 0.0, 0.0\n" ++
|
|
||||||
"dcl_2d s0\n" ++
|
"dcl_2d s0\n" ++
|
||||||
"dcl_2d s1\n" ++
|
"dcl_2d s1\n" ++
|
||||||
"dcl_texcoord0 v0\n" ++
|
"dcl_texcoord0 v0\n" ++
|
||||||
// Nearest JFA seed and pixel-space squared distance.
|
// Nearest seed and pixel-space squared distance.
|
||||||
"texld r0, v0, s0\n" ++
|
"texld r0, v0, s0\n" ++
|
||||||
"sub r1.xy, v0.xy, r0.xy\n" ++
|
"sub r1.xy, v0.xy, r0.xy\n" ++
|
||||||
"mul r1.xy, r1.xy, c0.xy\n" ++
|
"mul r1.xy, r1.xy, c0.xy\n" ++
|
||||||
"dp2add r1.z, r1, r1, c1.x\n" ++
|
"dp2add r1.z, r1, r1, c0.w\n" ++
|
||||||
// Squared core and halo radii.
|
// Seed colour.
|
||||||
"mul r3.x, c0.z, c0.z\n" ++
|
"texld r2, r0, s1\n" ++
|
||||||
"mul r3.y, c0.w, c0.w\n" ++
|
// Hard radius test: dist² < radius² => alpha 1, otherwise 0.
|
||||||
// Smooth halo factor = saturate((halo² - dist²) / (halo² - core²)).
|
"mov r3.x, c0.z\n" ++
|
||||||
"sub r3.z, r3.y, r3.x\n" ++
|
"mul r3.x, r3.x, r3.x\n" ++
|
||||||
"rcp r3.z, r3.z\n" ++
|
"sub r3.y, r1.z, r3.x\n" ++
|
||||||
"sub r4.x, r3.y, r1.z\n" ++
|
"mov r6.w, c1.y\n" ++
|
||||||
"mul r4.x, r4.x, r3.z\n" ++
|
"cmp r4.w, r3.y, c0.w, r6.w\n" ++
|
||||||
"max r4.x, r4.x, c1.x\n" ++
|
// Do not paint over the model interior.
|
||||||
"min r4.x, r4.x, c1.y\n" ++
|
|
||||||
"mul r6.w, r4.x, c1.z\n" ++
|
|
||||||
// Solid-but-soft core inside the inner radius.
|
|
||||||
"sub r4.y, r1.z, r3.x\n" ++
|
|
||||||
"cmp r6.w, r4.y, r6.w, c3.x\n" ++
|
|
||||||
// Never paint over the original model interior.
|
|
||||||
"texld r5, v0, s1\n" ++
|
"texld r5, v0, s1\n" ++
|
||||||
"add r5.x, r5.a, c1.w\n" ++
|
"add r5.x, r5.a, c1.z\n" ++
|
||||||
"cmp r6.w, r5.x, c1.x, r6.w\n" ++
|
"cmp r4.w, r5.x, c0.w, r4.w\n" ++
|
||||||
"mov r6.xyz, c2.xyz\n" ++
|
"mov r4.xyz, r2.xyz\n" ++
|
||||||
"mov oC0, r6\n";
|
"mov oC0, r4\n";
|
||||||
|
|
||||||
/// Debug: composite silhouette RT directly. Forces alpha to 1.0 where silhouette
|
/// Debug: composite silhouette RT directly. Forces alpha to 1.0 where silhouette
|
||||||
/// has any content (alpha >= 0.002), 0.0 elsewhere. Bypasses JFA entirely.
|
/// has any content (alpha >= 0.002), 0.0 elsewhere. Bypasses JFA entirely.
|
||||||
@@ -1437,8 +1417,8 @@ fn runJfaPipeline(device: *anyopaque) void {
|
|||||||
if (saved_rt0) |rt| deviceSetRenderTarget(device, 0, rt);
|
if (saved_rt0) |rt| deviceSetRenderTarget(device, 0, rt);
|
||||||
deviceSetTexture(device, 0, rt_jfa_a_tex);
|
deviceSetTexture(device, 0, rt_jfa_a_tex);
|
||||||
deviceSetTexture(device, 1, rt_silhouette_tex);
|
deviceSetTexture(device, 1, rt_silhouette_tex);
|
||||||
// V38: slightly stronger 1.5px core with a subtler 3.1px falloff.
|
// V34: hard 3px edge unchanged; JFA seed precision is now full-float.
|
||||||
c0 = [4]f32{ fw, fh, 1.50, 3.10 };
|
c0 = [4]f32{ fw, fh, 3.0, 0.0 };
|
||||||
deviceSetPSConstF(device, 0, &c0);
|
deviceSetPSConstF(device, 0, &c0);
|
||||||
deviceSetPtr(device, types.VT.SetPixelShader, jfa_decode_ps.?);
|
deviceSetPtr(device, types.VT.SetPixelShader, jfa_decode_ps.?);
|
||||||
deviceSetRS(device, types.D3DRS.ALPHABLENDENABLE, 1);
|
deviceSetRS(device, types.D3DRS.ALPHABLENDENABLE, 1);
|
||||||
@@ -1646,7 +1626,6 @@ fn getD3D9VTable() ?[*]usize {
|
|||||||
|
|
||||||
pub fn installHooks() bool {
|
pub fn installHooks() bool {
|
||||||
if (hooks_installed) return true;
|
if (hooks_installed) return true;
|
||||||
if (shutdown_started) return false;
|
|
||||||
|
|
||||||
const vtable_ptr = getD3D9VTable() orelse return false;
|
const vtable_ptr = getD3D9VTable() orelse return false;
|
||||||
d3d9_vtable = vtable_ptr;
|
d3d9_vtable = vtable_ptr;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ fn renderDrawDetour(this: u32, view_matrix: u32, batch_data: u32, batch_indices:
|
|||||||
const idx_u: u32 = @bitCast(indices[i]);
|
const idx_u: u32 = @bitCast(indices[i]);
|
||||||
const model_ptr = hook.readMem(u32, batch_data +% idx_u *% 0x40 +% 4);
|
const model_ptr = hook.readMem(u32, batch_data +% idx_u *% 0x40 +% 4);
|
||||||
if (model_ptr != 0) {
|
if (model_ptr != 0) {
|
||||||
if (tracker.findOutlineEntryIncludingAttachment(model_ptr) != null) {
|
if (tracker.findOutlineEntry(model_ptr) != null) {
|
||||||
outline_count += 1;
|
outline_count += 1;
|
||||||
} else if (tracker.isGameObjectModel(model_ptr)) {
|
} else if (tracker.isGameObjectModel(model_ptr)) {
|
||||||
game_obj_count += 1;
|
game_obj_count += 1;
|
||||||
@@ -137,7 +137,7 @@ fn renderDrawDetour(this: u32, view_matrix: u32, batch_data: u32, batch_indices:
|
|||||||
const batch_idx = indices[i];
|
const batch_idx = indices[i];
|
||||||
const idx_u: u32 = @bitCast(batch_idx);
|
const idx_u: u32 = @bitCast(batch_idx);
|
||||||
const model_ptr = hook.readMem(u32, batch_data +% idx_u *% 0x40 +% 4);
|
const model_ptr = hook.readMem(u32, batch_data +% idx_u *% 0x40 +% 4);
|
||||||
if (model_ptr != 0 and tracker.findOutlineEntryIncludingAttachment(model_ptr) != null) {
|
if (model_ptr != 0 and tracker.findOutlineEntry(model_ptr) != null) {
|
||||||
reordered_indices[outline_pos] = batch_idx;
|
reordered_indices[outline_pos] = batch_idx;
|
||||||
outline_pos += 1;
|
outline_pos += 1;
|
||||||
} else if (model_ptr != 0 and tracker.isGameObjectModel(model_ptr)) {
|
} else if (model_ptr != 0 and tracker.isGameObjectModel(model_ptr)) {
|
||||||
@@ -193,7 +193,7 @@ fn drawBatchProjDetour(ctx: u32) callconv(hook.cc.thiscall) void {
|
|||||||
else
|
else
|
||||||
0;
|
0;
|
||||||
|
|
||||||
const entry = if (model_ptr != 0) tracker.findOutlineEntryIncludingAttachment(model_ptr) else null;
|
const entry = if (model_ptr != 0) tracker.findOutlineEntry(model_ptr) else null;
|
||||||
|
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
// This batch is an outline target - signal the DIP hook
|
// This batch is an outline target - signal the DIP hook
|
||||||
|
|||||||
@@ -12,15 +12,6 @@ pub const MODEL_OWNER_DIRECT: usize = 0x28;
|
|||||||
/// model + this → render callback owner pointer (set by SetRenderCallbacks).
|
/// model + this → render callback owner pointer (set by SetRenderCallbacks).
|
||||||
pub const MODEL_OWNER_CALLBACK: usize = 0x3C0;
|
pub const MODEL_OWNER_CALLBACK: usize = 0x3C0;
|
||||||
|
|
||||||
/// V40: parent/root CM2Model for an attached model.
|
|
||||||
/// Proven from WoW 1.12.1 build 5875 function 0x712F70:
|
|
||||||
/// child+0x1CC = root, child+0x1D0 = attachment id,
|
|
||||||
/// root+0x1DC = child-list head, child+0x1E4 = next sibling.
|
|
||||||
pub const MODEL_ATTACHMENT_PARENT: usize = 0x1CC;
|
|
||||||
pub const MODEL_ATTACHMENT_ID: usize = 0x1D0;
|
|
||||||
pub const MODEL_CHILD_HEAD: usize = 0x1DC;
|
|
||||||
pub const MODEL_NEXT_SIBLING: usize = 0x1E4;
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Render context
|
// Render context
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|||||||
@@ -109,11 +109,8 @@ pub fn initD3D9Deferred() void {
|
|||||||
/// Remove all outline hooks. Called during DLL_PROCESS_DETACH.
|
/// Remove all outline hooks. Called during DLL_PROCESS_DETACH.
|
||||||
pub fn cleanup() void {
|
pub fn cleanup() void {
|
||||||
if (g_is_hook_owner) {
|
if (g_is_hook_owner) {
|
||||||
// ExitFix: stop any future self-heal first, then detach the model hooks
|
|
||||||
// that can call lateRehookIfLost(), and only then tear down D3D9.
|
|
||||||
d3d9_hook.beginShutdown();
|
|
||||||
model_hook.removeHooks();
|
|
||||||
d3d9_hook.removeHooks();
|
d3d9_hook.removeHooks();
|
||||||
|
model_hook.removeHooks();
|
||||||
log.close();
|
log.close();
|
||||||
mod_mutex.release(&g_mutex);
|
mod_mutex.release(&g_mutex);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-26
@@ -79,19 +79,6 @@ pub fn findOutlineEntry(model_ptr: u32) ?*const types.OutlineEntry {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// V40: resolve a live attached M2 to the already-tracked root model.
|
|
||||||
/// 0x712F70 writes the root CM2Model pointer directly to child+0x1CC.
|
|
||||||
/// We only read that fixed field and compare the value; the parent pointer is
|
|
||||||
/// never dereferenced here.
|
|
||||||
pub fn findOutlineEntryIncludingAttachment(model_ptr: u32) ?*const types.OutlineEntry {
|
|
||||||
if (findOutlineEntry(model_ptr)) |entry| return entry;
|
|
||||||
if (model_ptr == 0) return null;
|
|
||||||
|
|
||||||
const parent = hook.readMem(u32, model_ptr + o.MODEL_ATTACHMENT_PARENT);
|
|
||||||
if (parent == 0 or parent == model_ptr) return null;
|
|
||||||
return findOutlineEntry(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if any outline targets are tracked this frame.
|
/// Check if any outline targets are tracked this frame.
|
||||||
pub fn hasTargets() bool {
|
pub fn hasTargets() bool {
|
||||||
return tracked_obj_count > 0;
|
return tracked_obj_count > 0;
|
||||||
@@ -99,7 +86,7 @@ pub fn hasTargets() bool {
|
|||||||
|
|
||||||
/// Get the outline colour for a model, or null if not tracked.
|
/// Get the outline colour for a model, or null if not tracked.
|
||||||
pub fn getModelColor(model_ptr: u32) ?u32 {
|
pub fn getModelColor(model_ptr: u32) ?u32 {
|
||||||
const entry = findOutlineEntryIncludingAttachment(model_ptr) orelse return null;
|
const entry = findOutlineEntry(model_ptr) orelse return null;
|
||||||
return switch (entry.category) {
|
return switch (entry.category) {
|
||||||
.target => types.COLOR_TARGET,
|
.target => types.COLOR_TARGET,
|
||||||
.raid_marked => if (entry.raid_mark > 0 and entry.raid_mark <= 8)
|
.raid_marked => if (entry.raid_mark > 0 and entry.raid_mark <= 8)
|
||||||
@@ -113,7 +100,7 @@ pub fn getModelColor(model_ptr: u32) ?u32 {
|
|||||||
|
|
||||||
/// Get the outline category for a model.
|
/// Get the outline category for a model.
|
||||||
pub fn getModelCategory(model_ptr: u32) types.ModelCategory {
|
pub fn getModelCategory(model_ptr: u32) types.ModelCategory {
|
||||||
const entry = findOutlineEntryIncludingAttachment(model_ptr) orelse return .none;
|
const entry = findOutlineEntry(model_ptr) orelse return .none;
|
||||||
return entry.category;
|
return entry.category;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +136,6 @@ pub fn classifyModel(model_ptr: u32) void {
|
|||||||
// Read the model's back-pointers to its owning game object.
|
// Read the model's back-pointers to its owning game object.
|
||||||
const owner_direct = hook.readMem(u32, model_ptr + o.MODEL_OWNER_DIRECT);
|
const owner_direct = hook.readMem(u32, model_ptr + o.MODEL_OWNER_DIRECT);
|
||||||
const owner_callback = hook.readMem(u32, model_ptr + o.MODEL_OWNER_CALLBACK);
|
const owner_callback = hook.readMem(u32, model_ptr + o.MODEL_OWNER_CALLBACK);
|
||||||
const attachment_parent = hook.readMem(u32, model_ptr + o.MODEL_ATTACHMENT_PARENT);
|
|
||||||
|
|
||||||
// Match against tracked outline objects (target, raid marks, dead players).
|
// Match against tracked outline objects (target, raid marks, dead players).
|
||||||
if (tracked_obj_count > 0 and frame_outline_count < MAX_OUTLINE_MODELS) {
|
if (tracked_obj_count > 0 and frame_outline_count < MAX_OUTLINE_MODELS) {
|
||||||
@@ -163,16 +149,6 @@ pub fn classifyModel(model_ptr: u32) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// V40: attached weapons, shields and other M2 children inherit the
|
|
||||||
// selected root's outline. This is only a value comparison; no traversal.
|
|
||||||
if (attachment_parent != 0 and attachment_parent != model_ptr and
|
|
||||||
findOutlineEntry(model_ptr) == null and frame_outline_count < MAX_OUTLINE_MODELS)
|
|
||||||
{
|
|
||||||
if (findOutlineEntry(attachment_parent)) |parent_entry| {
|
|
||||||
addOutlineEntry(model_ptr, parent_entry.category, parent_entry.raid_mark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match against game object pointers (for render ordering).
|
// Match against game object pointers (for render ordering).
|
||||||
if (game_obj_ptr_count > 0 and game_obj_model_count < MAX_GAME_OBJ_MODELS) {
|
if (game_obj_ptr_count > 0 and game_obj_model_count < MAX_GAME_OBJ_MODELS) {
|
||||||
for (game_obj_ptrs[0..game_obj_ptr_count]) |go_ptr| {
|
for (game_obj_ptrs[0..game_obj_ptr_count]) |go_ptr| {
|
||||||
|
|||||||
Reference in New Issue
Block a user