V40: inherit outline through exact attachment parent
This commit is contained in:
+26
-2
@@ -79,6 +79,19 @@ 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;
|
||||||
@@ -86,7 +99,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 = findOutlineEntry(model_ptr) orelse return null;
|
const entry = findOutlineEntryIncludingAttachment(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)
|
||||||
@@ -100,7 +113,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 = findOutlineEntry(model_ptr) orelse return .none;
|
const entry = findOutlineEntryIncludingAttachment(model_ptr) orelse return .none;
|
||||||
return entry.category;
|
return entry.category;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +149,7 @@ 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) {
|
||||||
@@ -149,6 +163,16 @@ 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