Scriptname _00E_PlayerhousingCurrentOTranslation extends ReferenceAlias EffectShader Property _00E_PlayerHousingTranslationShader Auto Actor Property PlayerRef Auto Bool bIsWorking = False Bool bIsWarmingUp = False Float fDistance Float fOffsetAngleZ Float fOffsetPosZ Float Property ORBIT_ANGULAR_SPEED_CAP = 30.0 AutoReadOnly Float Property FAST_TRANSLATION_SPEED = 1000000.0 AutoReadOnly Function Setup(_00E_Playerhousing_Furniture furnitureRef, Bool bEnteringPlacement, Float fStoredOffsetAngleZ, Float fStoredOffsetPositionZ) bIsWarmingUp = True furnitureRef.Disable() If PlayerRef == None PlayerRef = Game.GetPlayer() EndIf fDistance = furnitureRef.CustomDistance If fDistance <= 0.0 fDistance = 100.0 EndIf If bEnteringPlacement fOffsetAngleZ = furnitureRef.OffsetAngleZ fOffsetPosZ = furnitureRef.OffsetPositionZ If furnitureRef.IsSetPositionIncompatible == False Float x = PlayerRef.GetPositionX() Float y = PlayerRef.GetPositionY() Float z = PlayerRef.GetPositionZ() Float fAngleZ = PlayerRef.GetAngleZ() furnitureRef.SetPosition(x + fDistance * Math.sin(fAngleZ), y + fDistance * Math.cos(fAngleZ), z + fOffsetPosZ) furnitureRef.SetAngle(0, 0, fAngleZ + fOffsetAngleZ) EndIf ObjectReference myRef = furnitureRef as ObjectReference If (myRef as _00E_Playerhousing_MannequinControl) (myRef as _00E_Playerhousing_MannequinControl).StartPlacement() ElseIf (myRef as _00E_Phasmalist_Workbench) (myRef as _00E_Phasmalist_Workbench).StartPlacement() EndIf Else fOffsetAngleZ = fStoredOffsetAngleZ fOffsetPosZ = fStoredOffsetPositionZ EndIf ForceRefTo(furnitureRef) bIsWorking = True furnitureRef.Enable() EndFunction Function Shutdown() bIsWorking = False ObjectReference myRef = GetRef() If myRef While bIsWarmingUp && (PlayerRef.GetParentCell() == myRef.GetParentCell()) Utility.WaitMenuMode(0.05) EndWhile myRef.StopTranslation() _00E_PlayerHousingTranslationShader.Stop(myRef) Clear() EndIf EndFunction Event OnLoad() ; Loop needs to be extracted from the rest of the code due to performance reasons (don't know why exactly, but defining new functions slows this down dramatically) ObjectReference myRef = GetRef() Float fPrevAngleZ = -1.0 myRef.SetMotionType(4) ; Set motion type to Motion_Keyframed. This would fix "collision phantoms" of the object while the player is moving around "dragging" it. _00E_PlayerHousingTranslationShader.Play(myRef) bIsWarmingUp = False While bIsWorking Float x = PlayerRef.GetPositionX() Float y = PlayerRef.GetPositionY() Float z = PlayerRef.GetPositionZ() Float fAngleZ = PlayerRef.GetAngleZ() ; Cap the angular speed of the object's orbiting around the player at ORBIT_ANGULAR_SPEED_CAP. ; This fixes some objects pushing the player (because they pass THROUGH the player?) on sharp camera turns. If fPrevAngleZ >= 0.0 Float fDelta = fAngleZ - fPrevAngleZ If fDelta < -180.0 fDelta += 360.0 ElseIf fDelta > 180.0 fDelta -= 360.0 EndIf If fDelta < -ORBIT_ANGULAR_SPEED_CAP fAngleZ = fPrevAngleZ - ORBIT_ANGULAR_SPEED_CAP If fAngleZ < 0.0 fAngleZ += 360.0 EndIf ElseIf fDelta > ORBIT_ANGULAR_SPEED_CAP fAngleZ = fPrevAngleZ + ORBIT_ANGULAR_SPEED_CAP If fAngleZ >= 360.0 fAngleZ -= 360.0 EndIf EndIf EndIf If bIsWorking myRef.TranslateTo(x + fDistance * Math.sin(fAngleZ), y + fDistance * Math.cos(fAngleZ), z + fOffsetPosZ, 0, 0, fAngleZ + fOffsetAngleZ, FAST_TRANSLATION_SPEED, FAST_TRANSLATION_SPEED) EndIf fPrevAngleZ = fAngleZ EndWhile EndEvent