myspace / Lua /FloatingDummy.lua
sirnii's picture
Upload 1816 files
b6a38d7 verified
raw
history blame
3.85 kB
DefineClass.FloatingDummy = {
__parents = {"Object", "InvisibleObject", "ComponentAnim", },
}
function FloatingDummy:GameInit()
self:SetAnimPhase(1, self:Random(self:GetAnimDuration()))
end
DefineClass.FloatingDummyCollision = {
__parents = {"Object" },
flags = { efWalkable = false, efCollision = false, efApplyToGrids = false },
clone_of = false,
}
local floating_dummy_attach_clear_enum_flags = const.efWalkable + const.efCollision + const.efApplyToGrids
function AttachObjectToFloatingDummy(obj, dummy, parent)
local o = PlaceObject("FloatingDummyCollision")
NetTempObject(o)
o.clone_of = obj
TargetDummies[obj] = o
o:ChangeEntity(obj:GetEntity())
local enum_flags = obj:GetEnumFlags(floating_dummy_attach_clear_enum_flags)
if enum_flags ~= 0 then
o:SetEnumFlags(enum_flags)
obj:ClearEnumFlags(enum_flags)
end
o:SetState(obj:GetState())
o:SetMirrored(obj:GetMirrored())
o:SetScale(obj:GetScale())
o:SetOpacity(0)
if parent then
parent:Attach(o, obj:GetAttachSpot())
o:SetAttachAxis(obj:GetAttachAxis())
o:SetAttachAngle(obj:GetAttachAngle())
o:SetAttachOffset(obj:GetAttachOffset())
else
local obj_axis = obj:GetAxis()
local obj_angle = obj:GetAngle()
local obj_pos = obj:GetPos()
if not obj_pos:IsValidZ() then obj_pos = obj_pos:SetTerrainZ() end
o:SetAxis(obj_axis)
o:SetAngle(obj_angle)
o:SetPos(obj:GetPosXYZ())
local attach_spot = dummy:GetSpotBeginIndex("Spot")
local spot_pos, spot_angle, spot_axis = dummy:GetSpotLoc(attach_spot, dummy:GetState(), 0)
if not spot_pos:IsValidZ() then spot_pos = spot_pos:SetTerrainZ() end
local attach_offset = RotateAxis(obj_pos - spot_pos, spot_axis, -spot_angle)
local attach_axis, attach_angle = ComposeRotation(obj_axis, obj_angle, spot_axis, -spot_angle)
dummy:Attach(obj, attach_spot)
obj:SetAttachAxis(attach_axis)
obj:SetAttachAngle(attach_angle)
obj:SetAttachOffset(attach_offset)
local phase = InteractionRand(obj:GetAnimDuration(), "FloatingDummy")
obj:SetAnimPhase(1, phase)
end
obj:ForEachAttach(AttachObjectToFloatingDummy, dummy, o)
end
function AttachObjectsToFloatingDummies()
if IsEditorActive() then return end
local collection = {}
MapForEach("map", "FloatingDummy", function(dummy, collection)
local col_index = dummy:GetCollectionIndex()
if col_index ~= 0 then
collection[col_index] = dummy
end
end, collection)
if not next(collection) then
return
end
SuspendPassEdits("AttachObjectsToFloatingDummies")
MapForEach("map", "CObject", function(obj, collection)
local dummy = collection[obj:GetCollectionIndex()]
if not dummy or obj == dummy or obj:GetParent() then
return
end
AttachObjectToFloatingDummy(obj, dummy)
end, collection)
ResumePassEdits("AttachObjectsToFloatingDummies")
end
local function RestoreFloatingDummyAttachFlags(o)
local obj = o.clone_of
if IsValid(obj) then
obj:SetEnumFlags(o:GetEnumFlags(floating_dummy_attach_clear_enum_flags))
obj:ClearHierarchyGameFlags(const.gofSolidShadow)
end
o:ForEachAttach(RestoreFloatingDummyAttachFlags)
end
function RestoreFloatingDummyAttach(o)
local obj = o.clone_of
if IsValid(obj) then
if IsKindOf(obj:GetParent(), "FloatingDummy") then
obj:Detach()
obj:SetPos(o:GetPosXYZ())
obj:SetAxis(o:GetAxis())
obj:SetAngle(o:GetAngle())
end
RestoreFloatingDummyAttachFlags(o)
end
DoneObject(o)
TargetDummies[obj] = nil
end
function DetachObjectsFromFloatingDummies()
SuspendPassEdits("DetachObjectsFromFloatingDummies")
MapForEach("map", "FloatingDummyCollision", RestoreFloatingDummyAttach)
ResumePassEdits("DetachObjectsFromFloatingDummies")
end
OnMsg.NewMapLoaded = AttachObjectsToFloatingDummies
OnMsg.GameEnteringEditor = DetachObjectsFromFloatingDummies -- called before GameEnterEditor, allowing XEditorFilters to catch these objects
OnMsg.GameExitEditor = AttachObjectsToFloatingDummies