custom distances and meshes for placeable housing objects + script properties that the player can make potions for quests, overhaul of the placement system in the players house (with controller compatibility), fixed the spelling of the "Hay Bale", fixed the texture on the gramophone + volume message

This commit is contained in:
overdev 2021-10-11 18:42:23 +02:00
parent 38f443800f
commit c0b15af719
103 changed files with 2642 additions and 122 deletions

Binary file not shown.

BIN
meshes/clutter/bones/deerskullhornsstatic.nif (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
meshes/clutter/candles/candlehornfloor01.nif (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
meshes/clutter/common/commoncrate01.nif (Stored with Git LFS)

Binary file not shown.

BIN
meshes/clutter/common/commoncrate02.nif (Stored with Git LFS)

Binary file not shown.

BIN
meshes/clutter/glazedcandlesstatic02.nif (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
meshes/clutter/shrines/shrinebase.nif (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,132 @@
Scriptname _00E_Gaboff_GrammophoneSC extends ObjectReference
Message Property _00E_Gaboff_GrammophoneMSG Auto
Message Property _00E_PlayerhousingKoppophonVolume Auto
Sound Property _00E_MUS_Special_OceansWidowM Auto
MiscObject Property Gold001 Auto
Actor Property PlayerREF Auto
Int iSoundID = -1
Float fVolume = 0.5
Bool bMusicLocked = False
Float Property MUSIC_LENGTH = 212.3 AutoReadOnly
;=====================================================================================
; FUNCTIONS
;=====================================================================================
Function PlayMusic(Sound musicSound, Float fMusicLength)
If fVolume <= 0.0 || fVolume > 1.0
fVolume = 0.5
EndIf
RegisterForModEvent("BardsLoadGame", "OnBardsLoadGame")
iSoundID = musicSound.Play(Self)
Sound.SetInstanceVolume(iSoundID, fVolume)
RegisterForSingleUpdate(_00E_QuestFunctions.AdjustTimePeriodByEngineTimerError(fMusicLength))
GoToState("")
_00E_PlayerhousingKoppophonVolume.Show(fVolume * 100.0)
EndFunction
Function ChangeMusicVolume()
If fVolume >= 0.0 && fVolume < 1.0
fVolume += 0.25
Else ; fVolume >= 1.0 or something is wrong with fVolume
fVolume = 0.0
EndIf
Sound.SetInstanceVolume(iSoundID, fVolume)
_00E_PlayerhousingKoppophonVolume.Show(fVolume * 100.0)
EndFunction
Function StopMusic()
bMusicLocked = True
GoToState("DoneCleanup")
UnregisterForModEvent("BardsLoadGame")
UnregisterForUpdate()
If iSoundID != -1
Sound.StopInstance(iSoundID)
iSoundID = -1
EndIf
bMusicLocked = False
EndFunction
Function TryStopMusic()
If bMusicLocked == False
StopMusic()
Else
RegisterForSingleUpdate(0.5)
EndIf
EndFunction
;=====================================================================================
; EVENTS
;=====================================================================================
Event OnInit()
GoToState("DoneCleanup")
EndEvent
Event OnActivate(ObjectReference akActionRef)
If akActionRef == PlayerREF && bMusicLocked == False
bMusicLocked = True
If iSoundID == -1
If _00E_Gaboff_GrammophoneMSG.Show() == 0
PlayerREF.RemoveItem(Gold001, 5)
PlayMusic(_00E_MUS_Special_OceansWidowM, MUSIC_LENGTH)
EndIf
Else
ChangeMusicVolume()
EndIf
bMusicLocked = False
EndIf
EndEvent
Event OnUpdate()
TryStopMusic()
EndEvent
Event OnBardsLoadGame(string eventName, string strArg, float numArg, Form sender)
; Player just loaded a save with the gramophone playing. The sound is dead by now.
TryStopMusic()
EndEvent
Event OnCellAttach()
TryStopMusic()
EndEvent
Event OnLoad()
TryStopMusic()
EndEvent
Event OnCellDetach()
TryStopMusic()
EndEvent
Event OnUnload()
TryStopMusic()
EndEvent
State DoneCleanup
Event OnCellAttach()
; Do nothing
EndEvent
Event OnLoad()
; Do nothing
EndEvent
Event OnCellDetach()
; Do nothing
EndEvent
Event OnUnload()
; Do nothing
EndEvent
EndState

View File

@ -0,0 +1,186 @@
scriptName _00E_Game_Playerhouse_BoardSC extends ObjectReference conditional
;=====================================================================================
; FUNCTIONS
;=====================================================================================
function EnableFurniture(Int iLevel)
FadeToBlackIMOD.Apply(1.00000)
utility.Wait(2 as Float)
FadeToBlackHoldIMOD.ApplyCrossFade(1 as Float)
if iLevel == 1
_00E_Game_Playerhouse_ArkMarket_Level01Linker.Enable()
elseIf iLevel == 2
_00E_Game_Playerhouse_ArkMarket_Level02Linker.Enable()
elseIf iLevel == 3
_00E_Game_Playerhouse_ArkMarket_Level03Linker.Enable()
endIf
FadeToBlackBackIMOD.ApplyCrossFade(1 as Float)
endFunction
function DisableFurniture()
FadeToBlackIMOD.Apply(1.00000)
utility.Wait(2 as Float)
FadeToBlackHoldIMOD.ApplyCrossFade(1 as Float)
_00E_Game_Playerhouse_ArkMarket_Level01Linker.Disable(false)
_00E_Game_Playerhouse_ArkMarket_Level02Linker.Disable(false)
_00E_Game_Playerhouse_ArkMarket_Level03Linker.Disable(false)
FadeToBlackBackIMOD.ApplyCrossFade(1 as Float)
endFunction
function OnActivate(ObjectReference akActionRef)
;backwards compatibility for saves prior patch 1.2.3.0
If (_00E_Game_Playerhouse_ArkMarket_Level01Linker.IsEnabled())
_00E_FurniturePurchased.SetValue(1)
EndIf
;backwards compatibility for saves prior patch 1.2.3.0
Int iButton = _00E_Game_PlayerHouse_ArkMarket_Board.Show(0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000)
if iButton == 7
return
elseIf iButton == 0
If PlayerREF.GetParentCell() == CapitalCityPlayerhouse
PlayerREF.RemoveItem(Gold001, 300)
Else
PlayerREF.RemoveItem(Gold001, 1250)
EndIf
_00E_FurniturePurchased.SetValue(1)
self.EnableFurniture(1)
elseIf iButton == 1
If PlayerREF.GetParentCell() == CapitalCityPlayerhouse
PlayerREF.RemoveItem(Gold001, 500)
Else
PlayerREF.RemoveItem(Gold001, 1500)
EndIf
_00E_FurniturePurchased.SetValue(2)
self.EnableFurniture(2)
elseIf iButton == 2
If PlayerREF.GetParentCell() == CapitalCityPlayerhouse
PlayerREF.RemoveItem(Gold001, 700)
Else
PlayerREF.RemoveItem(Gold001, 1750)
EndIf
_00E_FurniturePurchased.SetValue(3)
self.EnableFurniture(3)
elseif iButton == 4
int iButton02 = _00E_Game_PlayerHouse_RemoveFurniture.Show()
if iButton02 == 0
ReturnAndRefund()
Else
Activate(PlayerREF)
EndIf
elseif iButton == 5
Cell cCurrentCell = Self.GetParentCell()
String sHouseName = NQ24.ChooseHouseName()
cCurrentCell.SetName(sHouseName)
If cCurrentCell == CapitalCityPlayerhouse
Player.sHouseMarketQuarterName = sHouseName
ElseIf cCurrentCell == CapitalCityPlayerHouseUpper
Player.sHouseNobleQuarterName = sHouseName
EndIf
elseif iButton == 6
_00E_PlayerhousingMaster.GetMaster().ShowExpansionBoardTutorial()
endIf
endFunction
;=====================================================================================
; FUNCTIONS
;=====================================================================================
Function ReturnAndRefund()
DisableFurniture()
If PlayerREF.GetParentCell() == CapitalCityPlayerhouse
If _00E_FurniturePurchased.GetValue() == 1
PlayerREF.AddItem(Gold001, 150)
_00E_FurniturePurchased.SetValue(0)
ElseIf _00E_FurniturePurchased.GetValue() == 2
PlayerREF.AddItem(Gold001, 250)
_00E_FurniturePurchased.SetValue(0)
ElseIf _00E_FurniturePurchased.GetValue() == 3
PlayerREF.AddItem(Gold001, 350)
_00E_FurniturePurchased.SetValue(0)
EndIf
ElseIf PlayerREF.GetParentCell() == CapitalCityPlayerhouseUpper
If _00E_FurniturePurchased.GetValue() == 1
PlayerREF.AddItem(Gold001, 625)
_00E_FurniturePurchased.SetValue(0)
ElseIf _00E_FurniturePurchased.GetValue() == 2
PlayerREF.AddItem(Gold001, 750)
_00E_FurniturePurchased.SetValue(0)
ElseIf _00E_FurniturePurchased.GetValue() == 3
PlayerREF.AddItem(Gold001, 875)
_00E_FurniturePurchased.SetValue(0)
EndIf
EndIf
EndFunction
;=====================================================================================
; PROPERTIES
;=====================================================================================
Actor Property PlayerREF Auto
Cell Property CapitalCityPlayerhouse Auto
Cell Property CapitalCityPlayerHouseUpper Auto
GlobalVariable Property _00E_FurniturePurchased Auto
bool Property bLevel01FurniturePurchased Auto Conditional Hidden
bool Property bLevel02FurniturePurchased Auto Conditional Hidden
bool Property bLevel03FurniturePurchased Auto Conditional Hidden
imagespacemodifier property FadeToBlackBackIMOD auto
ObjectReference property _00E_Game_Playerhouse_ArkMarket_Level01Linker auto
message property _00E_Game_PlayerHouse_ArkMarket_Board auto
imagespacemodifier property FadeToBlackIMOD auto
Bool property __Config_bHouseHasLevel02 auto conditional
{Check this if this house has level 02 furniture designed.}
ObjectReference property _00E_Game_Playerhouse_ArkMarket_Level02Linker auto
imagespacemodifier property FadeToBlackHoldIMOD auto
Bool property __Config_bHouseHasLevel01 auto conditional
{Check this if this house has level 01 furniture designed.}
ObjectReference property _00E_Game_Playerhouse_ArkMarket_Level03Linker auto
Bool property __Config_bHouseHasLevel03 auto conditional
{Check this if this house has level 03 furniture designed.}
MiscObject Property Gold001 Auto
Message Property _00E_Game_PlayerHouse_RemoveFurniture Auto
_00E_NQ24_Playerhousing_Functions Property NQ24 Auto
_00E_PlayerHousing_CellNameSC Property Player Auto

View File

@ -0,0 +1,161 @@
Scriptname _00E_PlaceableGrammophonPlay extends ObjectReference
Sound Property _00E_MUS_Placeable_Koppophon Auto
MusicType Property _00E_SilenceTransitionHighPriority Auto ; OBSOLETE. Left for version update on older saves.
MusicType Property _00E_SilenceKoppophon Auto
GlobalVariable Property _00E_AchievementsEnabled Auto
Message Property _00E_PlayerhousingKoppophonVolume Auto
Actor Property PlayerREF Auto
Int playbackId = -1
Float volume = 0.5
Bool bDone ; Unlocked END_KOPPOPHON_01 achievement
Bool bMusicLocked = False
Bool bOldSilenceUpdated = False
Float Property MUSIC_LENGTH = 87.2 AutoReadOnly
;=====================================================================================
; FUNCTIONS
;=====================================================================================
Function StopMusic()
bMusicLocked = True
UnregisterForModEvent("BardsLoadGame")
UnregisterForUpdate()
If bOldSilenceUpdated == False
bOldSilenceUpdated = True
If playbackId != -1
_00E_SilenceTransitionHighPriority.Remove()
EndIf
EndIf
If playbackId != -1
Sound.StopInstance(playbackId)
playbackId = -1
EndIf
_00E_SilenceKoppophon.Remove()
bMusicLocked = False
EndFunction
Function TryStopMusic()
If bMusicLocked == False
StopMusic()
Else
RegisterForSingleUpdate(0.5)
EndIf
EndFunction
Function Cleanup()
GoToState("DoneCleanup")
TryStopMusic()
EndFunction
;=====================================================================================
; EVENTS
;=====================================================================================
Event OnInit()
GoToState("DoneCleanup")
EndEvent
Event OnActivate(ObjectReference triggerRef)
If triggerRef == PlayerREF && _00E_PlayerhousingMaster.ReferenceCanBeActivated(Self) && bMusicLocked == False
bMusicLocked = True
If playbackId == -1 ; Start playing
bOldSilenceUpdated = True
RegisterForModEvent("BardsLoadGame", "OnBardsLoadGame")
_00E_SilenceKoppophon.Add()
playbackId = _00E_MUS_Placeable_Koppophon.Play(Self)
If volume <= 0.0 || volume > 1.0
volume = 0.5
EndIf
Sound.SetInstanceVolume(playbackId, volume)
RegisterForSingleUpdate(_00E_QuestFunctions.AdjustTimePeriodByEngineTimerError(MUSIC_LENGTH))
GoToState("")
_00E_PlayerhousingKoppophonVolume.Show(volume * 100.0)
If _00E_AchievementsEnabled.GetValueInt() == 1 && (bDone == False)
bDone = True
Game.UnlockAchievement("END_KOPPOPHON_01")
EndIf
ElseIf bOldSilenceUpdated == False
; Player just loaded an older save with the Koppophon playing. The sound is dead by now.
StopMusic()
Else ; Volume control
Float fNewVolume = volume + 0.25
If fNewVolume > 1.0
fNewVolume = 0.0
EndIf
Sound.SetInstanceVolume(playbackId, fNewVolume)
If fNewVolume == 0.0 ; On mute
_00E_SilenceKoppophon.Remove()
ElseIf volume == 0.0 ; On unmute
_00E_SilenceKoppophon.Add()
EndIf
volume = fNewVolume
_00E_PlayerhousingKoppophonVolume.Show(volume * 100.0)
EndIf
bMusicLocked = False
EndIf
EndEvent
Event OnUpdate()
TryStopMusic()
EndEvent
Event OnBardsLoadGame(string eventName, string strArg, float numArg, Form sender)
; Player just loaded a save with the Koppophon playing. The sound is dead by now.
TryStopMusic()
EndEvent
Event OnCellAttach()
Cleanup()
EndEvent
Event OnLoad()
Cleanup()
EndEvent
Event OnCellDetach()
Cleanup()
EndEvent
Event OnUnload()
Cleanup()
EndEvent
State DoneCleanup
Event OnCellAttach()
; Do nothing
EndEvent
Event OnLoad()
; Do nothing
EndEvent
Event OnCellDetach()
; Do nothing
EndEvent
Event OnUnload()
; Do nothing
EndEvent
EndState

View File

@ -0,0 +1,48 @@
scriptname _00E_Playerhousing_Furniture extends ObjectReference
{A manipulatable housing object while being in the world}
Float Property CustomDistance Auto
{ Custom distance from the player in the placemenet Move Mode }
Float Property OffsetAngleZ Auto
{ Custom offset Z rotation in the placemenet Move Mode }
Float Property OffsetPositionZ Auto
{ Custom offset Z position in the placemenet Move Mode }
Bool Property IsSetPositionIncompatible Auto
{ If the .nif of the object has a bhkCollisionObject with SET_LOCAL flag, SetPosition() or MoveTo() can easily mess this object up in the placement mode. }
Form Property InventoryItem Auto Hidden
_00E_Playerhousing_FurnitureItem Property furnitureItem Auto Hidden
{ OBSOLETE. Left for compatibility with older saves. }
Form Function GetInventoryItem()
If furnitureItem ; Update from the old way of storing the base inventory item
If InventoryItem == None
InventoryItem = furnitureItem.GetBaseObject()
EndIf
furnitureItem = None
EndIf
Return InventoryItem
EndFunction
Function finishPlacement()
; This function is called when the furniture object is at the right position and being placed.
SetMotionType(Motion_Dynamic, True)
; in case we place a mannequin, we need to store its position
ObjectReference myObjRef = self as ObjectReference
If myObjRef as _00E_Playerhousing_MannequinControl
(myObjRef as _00E_Playerhousing_MannequinControl).FinishPlacement()
Else
BlockActivation(true)
Disable()
Utility.Wait(0.1)
Enable()
If myObjRef as _00E_Phasmalist_Workbench
(myObjRef as _00E_Phasmalist_Workbench).FinishPlacement()
EndIf
EndIf
EndFunction

View File

@ -0,0 +1,43 @@
scriptname _00E_Playerhousing_FurnitureItem extends ObjectReference
{A manipulatable housing object while being in the players inventory}
ActorBase Property _MANNEQUIN_toCreate auto
Furniture Property _FURNITURE_toCreate auto
Container Property _CONTAINER_toCreate auto
Light Property _LIGHT_toCreate auto
MiscObject Property _MISC_toCreate Auto
Activator Property _ACTIVATOR_toCreate Auto
_00E_PlayerhousingMaster Property master Auto
Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
If akNewContainer == None
If master == None
master = _00E_PlayerhousingMaster.GetMaster()
EndIf
master.playerItemDropped(Self)
EndIf
EndEvent
_00E_Playerhousing_Furniture Function placeFurnitureAtMe()
_00E_Playerhousing_Furniture result = None
If _MANNEQUIN_toCreate
result = PlaceAtMe(_MANNEQUIN_toCreate, abForcePersist = True, abInitiallyDisabled = True) as _00E_Playerhousing_Furniture
ElseIf _FURNITURE_toCreate
result = PlaceAtMe(_FURNITURE_toCreate, abInitiallyDisabled = True) as _00E_Playerhousing_Furniture
ElseIf _CONTAINER_toCreate
result = PlaceAtMe(_CONTAINER_toCreate, abInitiallyDisabled = True) as _00E_Playerhousing_Furniture
ElseIf _LIGHT_toCreate
result = PlaceAtMe(_LIGHT_toCreate, abInitiallyDisabled = True) as _00E_Playerhousing_Furniture
ElseIf _ACTIVATOR_toCreate
result = PlaceAtMe(_ACTIVATOR_toCreate, abInitiallyDisabled = True) as _00E_Playerhousing_Furniture
ElseIf _MISC_toCreate
result = PlaceAtMe(_MISC_toCreate, abInitiallyDisabled = True) as _00E_Playerhousing_Furniture
EndIf
If result == None
Debug.MessageBox("ERROR: *_toCreate property in playerhousingfurnitureitem is no furnitureitem, please write a bugticket")
EndIf
Return result
EndFunction

View File

@ -0,0 +1,23 @@
Scriptname _00E_Playerhousing_LightFurniture extends _00E_Playerhousing_Furniture
Light Property LIGHT_toCreate auto
{not used due to graphic bugs}
; ObjectReference createdLight
function finishPlacement()
{this function is called when the furniture object is at the right position and being placed; use e.g. for light}
parent.finishPlacement()
;real light cannot be placed since it causes graphic bugs
;createdLight = placeAtMe(LIGHT_toCreate)
;createdLight.setScale(0.99)
Endfunction
;/
Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
if akOldContainer== None
createdLight.disable()
createdLight.delete()
Endif
Endevent
/;

View File

@ -0,0 +1,231 @@
Scriptname _00E_Playerhousing_MannequinControl extends Actor
import utility
Actor Property PlayerREF Auto
Bool bIsInPlacementMode = False
Bool bActivationBlocked = False
;=====================================================================================
; EVENTS
;=====================================================================================
Event OnCellLoad()
If bIsInPlacementMode == False
ResetOnLoad()
EndIf
EndEvent
Event OnLoad()
If bIsInPlacementMode
ResetOnLoad()
EndIf
EndEvent
Event OnActivate(ObjectReference TriggerRef)
If TriggerRef == PlayerREF && _00E_PlayerhousingMaster.ReferenceCanBeActivated(self) && bActivationBlocked == False
bActivationBlocked = True
ConvertArmorSlots() ; Version update
OpenInventory(True)
ResetPosition()
Wait(0.1)
EnableAI(False)
bActivationBlocked = False
EndIf
EndEvent
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
If (akBaseItem as Armor)
If TryRegisterAddedArmor(akBaseItem)
EquipItem(akBaseItem)
Else
;Turn it back if the mannequin has one of these already, or if all the slots are full.
RemoveItem(akBaseItem, aiItemCount, True, PlayerREF)
EndIf
Else
RemoveItem(akBaseItem, aiItemCount, True, PlayerREF)
EndIf
EndEvent
Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
If (akBaseObject as Armor)
UnregisterRemovedArmor(akBaseObject)
EndIf
EndEvent
;=====================================================================================
; ARMOR SLOTS TRACKING
;=====================================================================================
Form Property ArmorSlot01 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot02 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot03 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot04 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot05 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot06 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot07 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot08 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot09 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form Property ArmorSlot10 Auto Hidden ; Obsolete. Left for version updates on older saves.
Form[] ArmorSlots
Bool bConvertedArmorSlots = False
Function ConvertArmorSlots()
If bConvertedArmorSlots
Return
EndIf
bConvertedArmorSlots = True
ArmorSlots = New Form[10]
Int index = _ConvertArmorSlot(0, ArmorSlot01)
index = _ConvertArmorSlot(index, ArmorSlot02)
index = _ConvertArmorSlot(index, ArmorSlot03)
index = _ConvertArmorSlot(index, ArmorSlot04)
index = _ConvertArmorSlot(index, ArmorSlot05)
index = _ConvertArmorSlot(index, ArmorSlot06)
index = _ConvertArmorSlot(index, ArmorSlot07)
index = _ConvertArmorSlot(index, ArmorSlot08)
index = _ConvertArmorSlot(index, ArmorSlot09)
index = _ConvertArmorSlot(index, ArmorSlot10)
ArmorSlot01 = None
ArmorSlot02 = None
ArmorSlot03 = None
ArmorSlot04 = None
ArmorSlot05 = None
ArmorSlot06 = None
ArmorSlot07 = None
ArmorSlot08 = None
ArmorSlot09 = None
ArmorSlot10 = None
EndFunction
Int Function _ConvertArmorSlot(Int index, Form armorItem)
If armorItem && ArmorSlots.Find(armorItem) < 0
ArmorSlots[index] = armorItem
index += 1
EndIf
Return index
EndFunction
Bool Function TryRegisterAddedArmor(Form armorItem)
; First check to see if this is already in a slot
If ArmorSlots.Find(armorItem) >= 0
Return False
EndIf
; Now find an emtpy slot to put it in, if there is one.
Int i = 0
While i < ArmorSlots.Length
If ArmorSlots[i] == None
ArmorSlots[i] = armorItem
Return True
EndIf
i += 1
EndWhile
; Nope. No room left.
Return False
EndFunction
Function UnregisterRemovedArmor(Form armorItem)
;This loop will also clear duplicates that might have been generated.
Int i = 0
While i < ArmorSlots.Length
If ArmorSlots[i] == armorItem
ArmorSlots[i] = None
EndIf
i += 1
EndWhile
EndFunction
Function ReequipAllArmor()
UnequipAll()
Int i = 0
While i < ArmorSlots.Length
If ArmorSlots[i]
EquipItem(ArmorSlots[i])
EndIf
i += 1
EndWhile
EndFunction
;=====================================================================================
; FUNCTIONS
;=====================================================================================
Float forceX
Float forceY
Float forceZ
Float forceAngleX
Float forceAngleY
Float forceAngleZ
Bool bPosisionValidated = False
Function ResetPosition()
If bPosisionValidated == False
bPosisionValidated = True
If forceX == 0 && forceY == 0 && forceZ == 0
Float fAngleZ = PlayerREF.GetAngleZ()
Float fDistanceFromPlayer = 100.0
forceX = PlayerREF.GetPositionX() + fDistanceFromPlayer * Math.sin(fAngleZ)
forceY = PlayerREF.GetPositionY() + fDistanceFromPlayer * Math.cos(fAngleZ)
forceZ = PlayerREF.GetPositionZ()
EndIf
EndIf
SetPosition(forceX, forceY, forceZ)
SetAngle(forceAngleX, forceAngleY, forceAngleZ)
EndFunction
Function ResetOnLoad()
ConvertArmorSlots() ; Version update
BlockActivation()
EnableAI(True)
If bIsInPlacementMode == False
ResetPosition()
EndIf
ReequipAllArmor()
EnableAI(False)
EndFunction
Function StartPlacement()
bIsInPlacementMode = True
EndFunction
Function FinishPlacement()
bIsInPlacementMode = False
Disable()
forceX = GetPositionX()
forceY = GetPositionY()
forceZ = GetPositionZ()
forceAngleX = GetAngleX()
forceAngleY = GetAngleY()
forceAngleZ = GetAngleZ()
bPosisionValidated = True
Enable()
_00E_QuestFunctions.WaitForReferenceToLoad(self)
ResetOnLoad()
EndFunction

View File

@ -0,0 +1,336 @@
Scriptname _00E_PlayerhousingCurrentOManipulate extends ReferenceAlias
EffectShader Property _00E_PlayerHousingManipulationShader Auto
Sound Property UIMenuPrevNext Auto
Actor Property PlayerRef Auto
String Property CONTROL_TURN_LEFT = "Strafe Left" AutoReadOnly
String Property CONTROL_TURN_RIGHT = "Strafe Right" AutoReadOnly
String Property CONTROL_MOVE_UP = "Forward" AutoReadOnly
String Property CONTROL_MOVE_DOWN = "Back" AutoReadOnly
Int Property TRANSLATION_TURN_LEFT = 0 AutoReadOnly
Int Property TRANSLATION_TURN_RIGHT = 1 AutoReadOnly
Int Property TRANSLATION_MOVE_UP = 2 AutoReadOnly
Int Property TRANSLATION_MOVE_DOWN = 3 AutoReadOnly
Int Property STATE_IDLE = 0 AutoReadOnly
Int Property STATE_UPDATING = 1 AutoReadOnly
Int Property STATE_WORKING = 2 AutoReadOnly
Float Property ROTATION_SPEED_START = 15.0 AutoReadOnly
Float Property ROTATION_SPEED_FALLBACK = 20.0 AutoReadOnly
Float Property ROTATION_SPEED_MAX = 180.0 AutoReadOnly
Float Property ROTATION_SPEED_CHANGE_MOD = 0.25 AutoReadOnly
Float Property ROTATION_MAX = 90.0 AutoReadOnly
Float Property MOVEMENT_SPEED_START = 10.0 AutoReadOnly
Float Property MOVEMENT_SPEED_FALLBACK = 20.0 AutoReadOnly
Float Property MOVEMENT_SPEED_MAX = 200.0 AutoReadOnly
Float Property MOVEMENT_SPEED_CHANGE_MOD = 0.25 AutoReadOnly
Float Property MOVEMENT_MAX = 100.0 AutoReadOnly
Float Property FAST_TRANSLATION_SPEED = 1000000.0 AutoReadOnly
Float fObjectPosX
Float fObjectPosY
Float fObjectPosZ
Float fObjectAngleX
Float fObjectAngleY
Float fObjectAngleZ
Float fPlayerPosZ
Float fTablePosZ
Float fTranslationSpeed
Float fTranslationSpeedIncrease
Int iWorkingState
Int iCurrentTranslation
Bool bGamepadMode
Int iWatchedKeyCode
Int iTurnLeftKey
Int iTurnRightKey
Int iMoveUpKey
Int iMoveDownKey
Function Setup(ObjectReference curObjectRef)
ForceRefTo(curObjectRef)
iWorkingState = STATE_IDLE
bGamepadMode = Game.UsingGamepad()
If bGamepadMode == False
iTurnLeftKey = Input.GetMappedKey(CONTROL_TURN_LEFT, 0)
iTurnRightKey = Input.GetMappedKey(CONTROL_TURN_RIGHT, 0)
iMoveUpKey = Input.GetMappedKey(CONTROL_MOVE_UP, 0)
iMoveDownKey = Input.GetMappedKey(CONTROL_MOVE_DOWN, 0)
Else
iTurnLeftKey = 274
iTurnRightKey = 275
iMoveUpKey = 280
iMoveDownKey = 281
EndIf
If PlayerRef == None ; Just in case
PlayerRef = Game.GetPlayer()
EndIf
fPlayerPosZ = PlayerRef.GetPositionZ()
fTablePosZ = fPlayerPosZ + 64.0
GoToState("Working")
TryRegisterForKey(iTurnLeftKey, CONTROL_TURN_LEFT)
TryRegisterForKey(iTurnRightKey, CONTROL_TURN_RIGHT)
TryRegisterForKey(iMoveUpKey, CONTROL_MOVE_UP)
TryRegisterForKey(iMoveDownKey, CONTROL_MOVE_DOWN)
_00E_PlayerHousingManipulationShader.Play(curObjectRef)
EndFunction
Function TryRegisterForKey(Int iKeyCode, String control)
If iKeyCode > 0
RegisterForKey(iKeyCode)
Else
RegisterForControl(control)
EndIf
EndFunction
Function Shutdown(Bool bRegisterNewOffsets)
GoToState("")
UnregisterForAllKeys()
UnregisterForAllControls()
UnregisterForUpdate()
ObjectReference myRef = GetRef()
If myRef != None
_00E_PlayerHousingManipulationShader.Stop(myRef)
While iWorkingState != STATE_IDLE && iWorkingState != STATE_WORKING
Utility.WaitMenuMode(0.05)
EndWhile
If iWorkingState == STATE_WORKING
myRef.StopTranslation()
EndIf
If bRegisterNewOffsets
Float fNewOffsetAngleZ = myRef.GetAngleZ() - PlayerRef.GetAngleZ()
Float fNewOffsetPosZ = myRef.GetPositionZ() - PlayerRef.GetPositionZ()
(GetOwningQuest() as _00E_PlayerhousingMaster).RegisterNewHousingObjectOffsets(fNewOffsetAngleZ, fNewOffsetPosZ)
EndIf
Clear()
EndIf
EndFunction
State Working
Event OnKeyDown(Int iKeyCode)
TryStartTranslation(KeyCodeToTranslationMode(iKeyCode), iKeyCode)
EndEvent
Event OnKeyUp(Int iKeyCode, Float fHoldTime)
TryStopTranslation(KeyCodeToTranslationMode(iKeyCode))
EndEvent
Event OnControlDown(String control)
TryStartTranslation(ControlToTranslationMode(control), 0)
EndEvent
Event OnControlUp(String control, Float fHoldTime)
TryStopTranslation(ControlToTranslationMode(control))
EndEvent
Event OnUpdate()
; OnControlUp is not always properly triggered. Maybe OnKeyUp too. The code below is a workaround for that.
; For gamepads this failsafe is useless because Input.IsKeyPressed always returns False for controller buttons.
If iWatchedKeyCode > 0 && iWorkingState == STATE_WORKING
If Input.IsKeyPressed(iWatchedKeyCode)
RegisterForSingleUpdate(0.05)
Else
TryStopTranslation(iCurrentTranslation)
EndIf
EndIf
EndEvent
Event OnTranslationComplete()
; The previously started translation reached its end point
If iWorkingState != STATE_WORKING
Return
EndIf
iWorkingState = STATE_UPDATING
ObjectReference myRef = GetRef()
If iWatchedKeyCode <= 0 || fTranslationSpeedIncrease < 0.0
; Do nothing
ElseIf iCurrentTranslation == TRANSLATION_TURN_LEFT || iCurrentTranslation == TRANSLATION_TURN_RIGHT
Float fRotationAngle = GetNextTranslationStep(ROTATION_SPEED_MAX, ROTATION_SPEED_CHANGE_MOD, ROTATION_MAX)
fObjectAngleZ = myRef.GetAngleZ()
TurnTranslate(myRef, fRotationAngle)
iWorkingState = STATE_WORKING
Return
ElseIf iCurrentTranslation == TRANSLATION_MOVE_UP || iCurrentTranslation == TRANSLATION_MOVE_DOWN
Float fMoveZ = GetNextTranslationStep(MOVEMENT_SPEED_MAX, MOVEMENT_SPEED_CHANGE_MOD, MOVEMENT_MAX)
fObjectPosZ = myRef.GetPositionZ()
MoveTranslate(myRef, fMoveZ)
iWorkingState = STATE_WORKING
Return
EndIf
; Fallback
FinalizeTranslation(myRef)
UIMenuPrevNext.Play(PlayerRef)
iWorkingState = STATE_IDLE
EndEvent
EndState
Int Function KeyCodeToTranslationMode(Int iKeyCode)
If iKeyCode > 0
If iKeyCode == iTurnLeftKey
Return TRANSLATION_TURN_LEFT
ElseIf iKeyCode == iTurnRightKey
Return TRANSLATION_TURN_RIGHT
ElseIf iKeyCode == iMoveUpKey
Return TRANSLATION_MOVE_UP
ElseIf iKeyCode == iMoveDownKey
Return TRANSLATION_MOVE_DOWN
EndIf
EndIf
Return -1
EndFunction
Int Function ControlToTranslationMode(String control)
If control == CONTROL_TURN_LEFT
Return TRANSLATION_TURN_LEFT
ElseIf control == CONTROL_TURN_RIGHT
Return TRANSLATION_TURN_RIGHT
ElseIf control == CONTROL_MOVE_UP
Return TRANSLATION_MOVE_UP
ElseIf control == CONTROL_MOVE_DOWN
Return TRANSLATION_MOVE_DOWN
EndIf
Return -1
EndFunction
Function TryStartTranslation(Int iTranslationMode, Int iTriggerKeyCode)
If iTranslationMode < 0 || iWorkingState != STATE_IDLE
Return
EndIf
iWorkingState = STATE_UPDATING
iCurrentTranslation = iTranslationMode
iWatchedKeyCode = iTriggerKeyCode
ObjectReference myRef = GetRef()
fObjectPosX = myRef.GetPositionX()
fObjectPosY = myRef.GetPositionY()
fObjectPosZ = myRef.GetPositionZ()
fObjectAngleX = myRef.GetAngleX()
fObjectAngleY = myRef.GetAngleY()
fObjectAngleZ = myRef.GetAngleZ()
fTranslationSpeedIncrease = 0.0
If iCurrentTranslation == TRANSLATION_TURN_LEFT || iCurrentTranslation == TRANSLATION_TURN_RIGHT
If iWatchedKeyCode > 0
fTranslationSpeed = ROTATION_SPEED_START
TurnTranslate(myRef, fTranslationSpeed * ROTATION_SPEED_CHANGE_MOD)
Else
fTranslationSpeed = ROTATION_SPEED_FALLBACK
TurnTranslate(myRef, ROTATION_MAX)
EndIf
ElseIf iCurrentTranslation == TRANSLATION_MOVE_UP || iCurrentTranslation == TRANSLATION_MOVE_DOWN
If iWatchedKeyCode > 0
fTranslationSpeed = MOVEMENT_SPEED_START
MoveTranslate(myRef, fTranslationSpeed * MOVEMENT_SPEED_CHANGE_MOD)
Else
fTranslationSpeed = MOVEMENT_SPEED_FALLBACK
MoveTranslate(myRef, MOVEMENT_MAX)
EndIf
EndIf
If iWatchedKeyCode > 0 && bGamepadMode == False
RegisterForSingleUpdate(0.05)
EndIf
iWorkingState = STATE_WORKING
EndFunction
Function TryStopTranslation(Int iTranslationMode)
If iCurrentTranslation != iTranslationMode || iWorkingState != STATE_WORKING
Return
EndIf
iWorkingState = STATE_UPDATING
ObjectReference myRef = GetRef()
myRef.StopTranslation()
UnregisterForUpdate()
FinalizeTranslation(myRef)
iWorkingState = STATE_IDLE
EndFunction
Function TurnTranslate(ObjectReference myRef, Float fRotationAngle)
If iCurrentTranslation == TRANSLATION_TURN_LEFT
fObjectAngleZ -= fRotationAngle
Else
fObjectAngleZ += fRotationAngle
EndIf
myRef.TranslateTo(fObjectPosX, fObjectPosY, fObjectPosZ, fObjectAngleX, fObjectAngleY, fObjectAngleZ, FAST_TRANSLATION_SPEED, fTranslationSpeed)
EndFunction
Function MoveTranslate(ObjectReference myRef, Float fMoveZ)
If iCurrentTranslation == TRANSLATION_MOVE_DOWN
Float fNewZ = fObjectPosZ - fMoveZ
If fObjectPosZ > fTablePosZ && fNewZ < fTablePosZ
; A primitive "drop on the table"
fNewZ = fTablePosZ
fTranslationSpeedIncrease = -1.0 ; Stop on reaching fPlayerPosZ.
ElseIf fObjectPosZ > fPlayerPosZ && fNewZ < fPlayerPosZ
; A primitive "drop on the floor"
fNewZ = fPlayerPosZ
fTranslationSpeedIncrease = -1.0 ; Stop on reaching fPlayerPosZ.
EndIf
fObjectPosZ = fNewZ
Else
fObjectPosZ += fMoveZ
EndIf
myRef.TranslateTo(fObjectPosX, fObjectPosY, fObjectPosZ, fObjectAngleX, fObjectAngleY, fObjectAngleZ, fTranslationSpeed, FAST_TRANSLATION_SPEED)
EndFunction
Float Function GetNextTranslationStep(Float fSpeedMax, Float fSpeedChangeMod, Float fChangeMax)
If fTranslationSpeed < fSpeedMax
If fTranslationSpeedIncrease < 20.0
fTranslationSpeedIncrease += 5.0
EndIf
fTranslationSpeed += fTranslationSpeedIncrease
If fTranslationSpeed > fSpeedMax
fTranslationSpeed = fSpeedMax
EndIf
EndIf
Float fResult = fTranslationSpeed * fSpeedChangeMod
If fTranslationSpeed >= fSpeedMax || fResult > fChangeMax
Return fChangeMax
Else
Return fResult
EndIf
EndFunction
Function FinalizeTranslation(ObjectReference myRef)
; TranslateTo below prevents the object from twitching and becoming blurry when a translation ends
If iCurrentTranslation == TRANSLATION_TURN_LEFT || iCurrentTranslation == TRANSLATION_TURN_RIGHT
fObjectAngleZ = myRef.GetAngleZ()
ElseIf iCurrentTranslation == TRANSLATION_MOVE_UP || iCurrentTranslation == TRANSLATION_MOVE_DOWN
fObjectPosZ = myRef.GetPositionZ()
EndIf
myRef.TranslateTo(fObjectPosX, fObjectPosY, fObjectPosZ, fObjectAngleX, fObjectAngleY, fObjectAngleZ, FAST_TRANSLATION_SPEED, FAST_TRANSLATION_SPEED)
EndFunction

View File

@ -0,0 +1,117 @@
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

Some files were not shown because too many files have changed in this diff Show More