|
ColorModifierReasons = { |
|
|
|
|
|
} |
|
|
|
MapVar("ColorModifierReasonsData", false) |
|
local table_find = table.find |
|
local SetColorModifier = CObject.SetColorModifier |
|
local GetColorModifier = CObject.GetColorModifier |
|
local clrNoModifier = const.clrNoModifier |
|
local default_color_modifier = RGBA(100, 100, 100, 0) |
|
|
|
function SetColorModifierReason(obj, reason, color, weight, blend, skip_attaches) |
|
assert(reason) |
|
if not reason then |
|
return |
|
end |
|
local color_value = color |
|
|
|
if obj:GetRadius() > 0 then |
|
local data = ColorModifierReasonsData |
|
if not data then |
|
data = {} |
|
ColorModifierReasonsData = data |
|
end |
|
local mrt = data[obj] |
|
local orig_color |
|
if not mrt then |
|
orig_color = GetColorModifier(obj) |
|
mrt = { orig_color = orig_color } |
|
data[obj] = mrt |
|
end |
|
|
|
local rt = ColorModifierReasons |
|
local idx = table_find(rt, "id", reason) |
|
local rdata = idx and rt[idx] or false |
|
|
|
color = color or rdata and rdata.color or nil |
|
if not color then |
|
printf("[WARNING] SetColorModifierReason no color! reason %s, color %s, weight %s", reason, tostring(color), tostring(weight)) |
|
return |
|
end |
|
weight = weight or rdata and rdata.weight or const.DefaultColorModWeight |
|
if not weight then |
|
printf("[WARNING] SetColorModifierReason no weight! reason %s, color %s, weight %s", reason, tostring(color), tostring(weight)) |
|
return |
|
end |
|
|
|
if blend then |
|
orig_color = orig_color or mrt.orig_color |
|
if orig_color ~= clrNoModifier then |
|
color = InterpolateRGB(orig_color, color, blend, 100) |
|
end |
|
end |
|
local idx = table_find(mrt, "reason", reason) |
|
local entry = idx and mrt[idx] |
|
if entry then |
|
entry.weight = weight |
|
entry.color = color |
|
else |
|
entry = { reason = reason, weight = weight, color = color } |
|
table.insert(mrt, entry) |
|
end |
|
table.stable_sort(mrt, function(a, b) |
|
return a.weight < b.weight |
|
end) |
|
SetColorModifier(obj, mrt[#mrt].color) |
|
end |
|
if skip_attaches then |
|
return |
|
end |
|
obj:ForEachAttach(SetColorModifierReason, reason, color_value, weight, blend) |
|
end |
|
|
|
function SetOrigColorModifier(obj, color, skip_attaches) |
|
local data = ColorModifierReasonsData |
|
local mrt = data and data[obj] |
|
if not mrt then |
|
SetColorModifier(obj, color) |
|
else |
|
mrt.orig_color = color |
|
end |
|
if skip_attaches then return end |
|
obj:ForEachAttach(SetOrigColorModifier, color) |
|
end |
|
|
|
function GetOrigColorModifier(obj) |
|
local modifier = GetColorModifier(obj) |
|
return modifier == default_color_modifier and table.get(ColorModifierReasonsData, obj, "orig_color") or modifier |
|
end |
|
|
|
function ValidateColorReasons() |
|
table.validate_map(ColorModifierReasonsData) |
|
end |
|
|
|
function ClearColorModifierReason(obj, reason, skip_color_change, skip_attaches) |
|
assert(reason) |
|
if not reason then |
|
return |
|
end |
|
local data = ColorModifierReasonsData |
|
local mrt = data and data[obj] |
|
if mrt then |
|
if not IsValid(obj) then |
|
data[obj] = nil |
|
return |
|
end |
|
local idx = table_find(mrt, "reason", reason) |
|
if not idx then |
|
return |
|
end |
|
local update = idx == #mrt |
|
table.remove(mrt, idx) |
|
if #mrt == 0 then |
|
data[obj] = nil |
|
DelayedCall(1000, ValidateColorReasons) |
|
if not next(data) then |
|
ColorModifierReasonsData = false |
|
end |
|
end |
|
if update and not skip_color_change then |
|
local active = mrt[#mrt] |
|
local color = active and active.color or mrt.orig_color or const.clrNoModifier |
|
SetColorModifier(obj, color) |
|
end |
|
end |
|
if skip_attaches then |
|
return |
|
end |
|
obj:ForEachAttach(ClearColorModifierReason, reason, skip_color_change) |
|
end |
|
|
|
function ClearColorModifierReasons(obj) |
|
local data = ColorModifierReasonsData |
|
local mrt = data and data[obj] |
|
if not mrt then |
|
return |
|
end |
|
if IsValid(obj) then |
|
SetColorModifier(obj, mrt.orig_color or const.clrNoModifier) |
|
obj:ForEachAttach(ClearColorModifierReasons) |
|
end |
|
data[obj] = nil |
|
end |
|
|
|
OnMsg.StartSaveGame = ValidateColorReasons |
|
|
|
|
|
|
|
MapVar("InvisibleReasons", {}, weak_keys_meta) |
|
|
|
local efVisible = const.efVisible |
|
|
|
function SetInvisibleReason(obj, reason) |
|
local invisible_reasons = InvisibleReasons |
|
local obj_reasons = invisible_reasons[obj] |
|
if obj_reasons then |
|
obj_reasons[reason] = true |
|
return |
|
end |
|
invisible_reasons[obj] = { [reason] = true } |
|
obj:ClearHierarchyEnumFlags(efVisible) |
|
end |
|
|
|
function ClearInvisibleReason(obj, reason) |
|
local invisible_reasons = InvisibleReasons |
|
local obj_reasons = invisible_reasons[obj] |
|
if not obj_reasons or not obj_reasons[reason] then |
|
return |
|
end |
|
obj_reasons[reason] = nil |
|
if next(obj_reasons) then |
|
return |
|
end |
|
invisible_reasons[obj] = nil |
|
obj:SetHierarchyEnumFlags(efVisible) |
|
end |
|
|
|
function ClearInvisibleReasons(obj) |
|
local invisible_reasons = InvisibleReasons |
|
if not invisible_reasons[obj] then |
|
return |
|
end |
|
invisible_reasons[obj] = nil |
|
obj:SetHierarchyEnumFlags(efVisible) |
|
end |
|
|
|
|