118 lines
3.5 KiB
Plaintext
118 lines
3.5 KiB
Plaintext
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
|