4
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
7.6 KiB

Scriptname _00E_GypsyMinstrelsControlScript extends Quest Conditional
3 years ago
Int Property WAYPOINT_PERFORM_MARKET = 0 AutoReadOnly
Int Property WAYPOINT_TRAVEL_INN = 1 AutoReadOnly
Int Property WAYPOINT_SANDBOX_INN = 2 AutoReadOnly
Int Property WAYPOINT_TRAVEL_MARKET = 3 AutoReadOnly
Float Property SAFE_TELEPORT_DISTANCE = 4000.0 AutoReadOnly
; TIME_PERFORMANCE_START must be less than TIME_PERFORMANCE_END
; TIME_PERFORMANCE_START and TIME_PERFORMANCE_END must be greater than 0
; Otherwise the curHour check in UpdateWaypoint must be rewritten
Float Property TIME_PERFORMANCE_START = 7.0 AutoReadOnly
Float Property TIME_PERFORMANCE_END = 23.0 AutoReadOnly
3 years ago
Int Property CurrentWaypoint Auto Hidden Conditional
ReferenceAlias Property Alias_LutePlayer Auto
ReferenceAlias Property Alias_Dancer Auto
GlobalVariable Property GameHour Auto
Cell Property InnCell Auto
ObjectReference Property TipBasket Auto
ObjectReference Property TempStorageMarker Auto
3 years ago
Actor Property PlayerRef Auto
MusicType Property ArkMarketGypsyPerformanceSilence Auto
Keyword Property LinkCustom01 Auto
Keyword Property LinkPerformanceSpot Auto
Quest Property MQ12b Auto
Quest Property MQ14 Auto
ObjectReference Property MQ12c_Debris_Level_02_Linker Auto
;=====================================================================================
; EVENTS
;=====================================================================================
Event OnInit()
CurrentWaypoint = -1 ; Force update
RegisterForSingleUpdate(3.0) ; Give a few seconds for the game to warm up at the start
EndEvent
Event OnUpdate()
UpdateWaypoint()
EndEvent
Event OnUpdateGameTime()
UpdateWaypoint()
EndEvent
3 years ago
;=====================================================================================
; FUNCTIONS
;=====================================================================================
Function TriggerUpdate()
RegisterForSingleUpdate(1.0)
EndFunction
Bool IsTipBasketHidden = False
Bool WaypointUpdateLocked = False
; Called from OnUpdate, OnUpdateGameTime and from end events of travel packages
Function UpdateWaypoint()
While WaypointUpdateLocked
Utility.Wait(0.5)
EndWhile
WaypointUpdateLocked = True
3 years ago
If MQ14.GetStage() >= 40
; When we reach the endgame in MQ14, the schedule does not matter anymore
SetNewWaypoint(WAYPOINT_SANDBOX_INN, True, -1.0)
ElseIf MQ12b.GetStage() >= 45 && MQ12c_Debris_Level_02_Linker.IsDisabled()
; When the siege of Ark starts, force the minstrels to the inn and keep them there while the streets are cleaned up from debris and bodies.
Float nextUpdateTime = TIME_PERFORMANCE_START - GameHour.GetValue()
If nextUpdateTime < 0.0
nextUpdateTime += 24.0
EndIf
SetNewWaypoint(WAYPOINT_SANDBOX_INN, True, nextUpdateTime)
Else
; Routine time of day update
Float curHour = GameHour.GetValue()
If curHour >= TIME_PERFORMANCE_START && curHour < TIME_PERFORMANCE_END
RoutineWaypointUpdate(WAYPOINT_PERFORM_MARKET, WAYPOINT_TRAVEL_MARKET, curHour - TIME_PERFORMANCE_START, TIME_PERFORMANCE_END - curHour)
ElseIf curHour >= TIME_PERFORMANCE_END
RoutineWaypointUpdate(WAYPOINT_SANDBOX_INN, WAYPOINT_TRAVEL_INN, curHour - TIME_PERFORMANCE_END, TIME_PERFORMANCE_START - curHour + 24.0)
Else ; curHour < TIME_PERFORMANCE_START
RoutineWaypointUpdate(WAYPOINT_SANDBOX_INN, WAYPOINT_TRAVEL_INN, curHour - TIME_PERFORMANCE_END + 24.0, TIME_PERFORMANCE_START - curHour)
EndIf
EndIf
3 years ago
WaypointUpdateLocked = False
EndFunction
3 years ago
Function RoutineWaypointUpdate(Int iCampWaypoint, Int iTravelWaypoint, Float fMissedStartByHours, Float fNextUpdateTime)
Actor luter = Alias_LutePlayer.GetActorReference()
Bool bTravel = False
Bool bTeleport = False
; If the lute player is not in the intended "camp" location, travel to it.
; But if the start time is missed by a significant margin (probably because of the player sleeping or a quest time skip),
; teleport the minstrels to the "camp" directly, but only if it happens out of sight of the player.
If iCampWaypoint == WAYPOINT_PERFORM_MARKET
ObjectReference performRef = luter.GetLinkedRef(LinkPerformanceSpot)
If luter.GetDistance(performRef) > 256.0
If fMissedStartByHours > 0.6 && PlayerRef.GetDistance(luter) > SAFE_TELEPORT_DISTANCE && PlayerRef.GetDistance(performRef) > SAFE_TELEPORT_DISTANCE
bTeleport = True
Else
bTravel = True
EndIf
EndIf
Else ; iCampWaypoint == WAYPOINT_SANDBOX_INN
If luter.GetParentCell() != InnCell
If fMissedStartByHours > 0.6 && PlayerRef.GetDistance(luter) > SAFE_TELEPORT_DISTANCE && PlayerRef.GetParentCell() != InnCell
bTeleport = True
Else
bTravel = True
EndIf
EndIf
3 years ago
EndIf
3 years ago
If bTravel
If fNextUpdateTime > 0.5
fNextUpdateTime = 0.5 ; Failsafe if the end of the travel package is not triggered for some reason
EndIf
3 years ago
SetNewWaypoint(iTravelWaypoint, False, fNextUpdateTime)
Else
3 years ago
SetNewWaypoint(iCampWaypoint, bTeleport, fNextUpdateTime)
EndIf
EndFunction
3 years ago
Function SetNewWaypoint(Int iNewWaypoint, Bool bDoTeleport, Float fNextUpdateTime)
If fNextUpdateTime >= 0.0
RegisterForSingleUpdateGameTime(fNextUpdateTime + 0.025)
EndIf
3 years ago
If iNewWaypoint != CurrentWaypoint
Actor luter = Alias_LutePlayer.GetActorReference()
Actor dancer = Alias_Dancer.GetActorReference()
Bool bDoMusicReset = (CurrentWaypoint == WAYPOINT_PERFORM_MARKET)
; Teleport destination for the lute player
ObjectReference teleportLuterRef = None
If bDoTeleport
If iNewWaypoint == WAYPOINT_PERFORM_MARKET
teleportLuterRef = luter.GetLinkedRef(LinkPerformanceSpot)
ElseIf iNewWaypoint == WAYPOINT_SANDBOX_INN
teleportLuterRef = luter.GetLinkedRef(LinkCustom01)
EndIf
EndIf
3 years ago
; Teleport destination for the dancer
ObjectReference teleportDancerRef = None
If dancer
If iNewWaypoint == WAYPOINT_PERFORM_MARKET
ObjectReference performRef = dancer.GetLinkedRef(LinkPerformanceSpot)
If bDoTeleport
teleportDancerRef = performRef
ElseIf dancer.GetDistance(performRef) > 256.0 && PlayerRef.GetDistance(dancer) > SAFE_TELEPORT_DISTANCE && PlayerRef.GetDistance(performRef) > SAFE_TELEPORT_DISTANCE
teleportDancerRef = performRef
EndIf
ElseIf iNewWaypoint == WAYPOINT_SANDBOX_INN
If bDoTeleport
teleportDancerRef = teleportLuterRef
ElseIf dancer.GetParentCell() != InnCell && PlayerRef.GetDistance(dancer) > SAFE_TELEPORT_DISTANCE && PlayerRef.GetParentCell() != InnCell
teleportDancerRef = luter.GetLinkedRef(LinkCustom01) ; Yes, luter.GetLinkedRef
EndIf
EndIf
EndIf
; Wait for the lute player to finish his current song (if he's playing)
3 years ago
(luter as _00E_BardPlayInstrumentScript).FadeAndStopMusic()
3 years ago
CurrentWaypoint = iNewWaypoint
3 years ago
If teleportLuterRef
_00E_QuestFunctions.SafeMoveTo(luter, teleportLuterRef)
EndIf
If teleportDancerRef
_00E_QuestFunctions.SafeMoveTo(dancer, teleportDancerRef)
EndIf
luter.EvaluatePackage()
If dancer
dancer.EvaluatePackage()
EndIf
3 years ago
If CurrentWaypoint == WAYPOINT_PERFORM_MARKET
If IsTipBasketHidden
IsTipBasketHidden = False
TipBasket.MoveToMyEditorLocation()
EndIf
Else
If IsTipBasketHidden == False
IsTipBasketHidden = True
TipBasket.MoveTo(TempStorageMarker)
EndIf
EndIf
3 years ago
If bDoMusicReset
; Failsafe remove silence if the lute player alias fails to do this
ArkMarketGypsyPerformanceSilence.Remove()
EndIf
EndIf
3 years ago
EndFunction
3 years ago
Function GroupTravelFailsafe()
If CurrentWaypoint == WAYPOINT_TRAVEL_INN || CurrentWaypoint == WAYPOINT_TRAVEL_MARKET
Actor luter = Alias_LutePlayer.GetActorReference()
Actor dancer = Alias_Dancer.GetActorReference()
If luter && dancer && dancer.GetDistance(luter) >= 1024.0 && dancer.GetDistance(PlayerRef) > 4000.0
_00E_QuestFunctions.SafeMoveTo_NoWait(dancer, luter)
EndIf
EndIf
EndFunction