Code:
Group Flags
Bool Property IsNewWorkshop = true Auto Const
{ If set to true, this workshop will be added to the workshop parent quest. Generally used for newly installed settlements. }
Bool Property UnlockWhenAble = true Auto Const
{ If set to true, this workshop will be unlocked from this script when all conditions are met. Generally used for newly installed settlements.}
EndGroup
Group EnaableDisableOnUnlock
ObjectReference[] Property EnableOnUnlock Auto Const
{References to enable on unlock.}
ObjectReference[] Property DisableOnUnlock Auto Const
{References to disable on unlock.}
EndGroup
Group Data
Actor Property Player Auto Const Mandatory
WorkShopParentScript Property WorkShopParent Auto Const Mandatory
WorkShopScript Property WorkShop Auto Const
{ This should only be used if you cannot link to the workshop for a reason. Otherwise you need to link the workshop.}
GlobalVariable Property GameDaysPassed Auto Const Mandatory
GlobalVariable Property GameHour Auto Const Mandatory
ObjectReference[] Property AttackMarker Auto Const
{Obsolete - delete var before next playthrough. }
KeyWord Property WorkshopLinkAttackMarker Auto Const Mandatory
EndGroup
Group UnlockConditions
Bool Property UnlockForFree = false Auto Const
{ If this is set true, no further checks are made. }
Bool Property UnlockWhenCleared = false Auto Const
ObjectReference[] Property ActorRefsToKill Auto Const
Quest[] Property QuestsToComplete Auto Const
Quest:QuestStage[] Property QuestStagesToComplete Auto Const
EndGroup
Group SettlementSystem
Bool Property AddSettlersOnInit = false Auto Const
Int Property AddSettlersCount = 3 Auto Const
EndGroup
Group AnnoyanceSytem
ActorBase[] Property AnnoyanceActors Auto Const
EndGroup
Group AttackSystem
WorkshopAttack[] Property WorkshopAttacks Auto Const
EndGroup
; Internal vars
bool sysInitialized = false
bool workShopInitialized = false
bool workShopRegistered = false
bool settlersSpawned = false
float sysInterval = 60.0
int updateTimerId = 1
float updateInterval = 0.25
int annoyanceTimerId = 2
float minAnnoyanceDay = 3.0
float maxAnnoyanceDay = 5.5
float annoyanceDay = 0.0
int attackTimerId = 3
float minAttackDay = 7.0
float maxAttackDay = 12.0
float attackDay = 0.0
bool actorRefsKilled = false
bool questsCompleted = false
bool questStagesCompleted = false
bool locationCleared = false
WorkShopScript workshopRef
Struct WorkshopAttack
Bool NightOnly = false
Bool IsHardcore = false
ActorBase EnemyActorsBoss
ActorBase EnemyActorsKnight
ActorBase EnemyActorsGeneral
ActorBase EnemyActorsPet
EndStruct
Event OnLoad()
DebugTrace("Workshop Controller loaded")
if sysInitialized == false
sysInitialized = true
GetMyWorkshop()
RegisterWorkshop()
MonitorWorkshop()
endif
if workShopInitialized == true
; Do something
endif
EndEvent
Event OnTimer(int aiTimerID)
; Workaround for already installed workshops, remove this before next playthrough
if !workshopRef
GetMyWorkshop()
endif
MonitorWorkshop()
EndEvent
Event OnTimerGameTime(int aiTimerID)
; Workaround for already installed workshops, remove this before next playthrough
if !workshopRef
GetMyWorkshop()
endif
if aiTimerId == updateTimerId
UpdateWorkshop()
elseif aiTimerId == annoyanceTimerId
SpawnAnnoyance()
elseif aiTimerId == attackTimerId
SpawnEnemy()
endif
EndEvent
; Monitor workshop location until all conditions are met
Function MonitorWorkshop()
if workShopInitialized == false && WorkshopCanBeInitialized()
workShopInitialized = true
UnlockWorkshop()
StartTimerGameTime(updateInterval, updateTimerId)
StartTimerGameTime(Utility.RandomFloat(minAnnoyanceDay, maxAnnoyanceDay), annoyanceTimerId)
StartTimerGameTime(Utility.RandomFloat(minAttackDay, maxAttackDay), attackTimerId)
else
StartTimer(sysInterval)
endif
EndFunction
; Update workshop in an interval
Function UpdateWorkshop()
; Spawn first settlers
if settlersSpawned == false && AddSettlersOnInit
settlersSpawned = true
int c = 0
while c < AddSettlersCount
Debug.Trace("Initial settler created")
WorkshopParent.CreateActorPUBLIC(workshopRef, GetSpawnMarker(), c == 0)
c += 1
endWhile
endif
; To do more
StartTimerGameTime(updateInterval, updateTimerId)
EndFunction
Function RegisterWorkshop()
DebugTrace("Trying to register workshop")
if IsNewWorkshop
WorkshopScript[] newWorkshops = new WorkshopScript[0]
newWorkshops.Add(workshopRef)
; add new workshops to main workshop arrays
if WorkshopParent.ReinitializeLocationsPUBLIC(newWorkshops, self) == false
; no locations to initialize - we're done (otherwise we wait for WorkshopInitializeLocation event sequence to complete)
workShopRegistered = true
DebugTrace("Workshop registered")
endif
else
DebugTrace("Workshop allready registered")
workShopRegistered = true
endif
EndFunction
Function UnlockWorkshop()
DebugTrace("Workshop unlocked")
if workshopRef.OwnedByPlayer == false && UnlockWhenAble == true
workshopRef.SetOwnedByPlayer(true)
endif
int c = 0
if EnableOnUnlock.Length > 0
c = 0
while (c < EnableOnUnlock.Length)
EnableOnUnlock[c].Enable()
c += 1
endwhile
endif
if DisableOnUnlock.Length > 0
c = 0
while (c < DisableOnUnlock.Length)
DisableOnUnlock[c].Disable()
c += 1
endwhile
endif
EndFunction
Function SpawnAnnoyance()
if AnnoyanceActors.Length > 0 && PlayerIsNearby()
debugTrace("Annoyance spawned")
int spawnType = 0
if AnnoyanceActors.Length > 1
spawnType = Utility.RandomInt(0, AnnoyanceActors.Length - 1)
endif
ObjectReference spawnedActor
ObjectReference spawnMarkerRef = GetSpawnMarker()
spawnedActor = spawnMarkerRef.PlaceAtMe(AnnoyanceActors[spawnType], 1)
spawnedActor.SetLinkedRef(self)
endif
StartTimerGameTime(Utility.RandomFloat(minAnnoyanceDay, maxAnnoyanceDay), annoyanceTimerId)
EndFunction
Function SpawnEnemy()
if PlayerIsNearby()
debugTrace("Enemies spawned")
endif
; To Do
StartTimerGameTime(Utility.RandomFloat(minAttackDay, maxAttackDay), attackTimerId)
EndFunction
Function GetMyWorkshop()
if GetLinkedRef() as WorkShopScript
workshopRef = GetLinkedRef() as WorkShopScript
elseif Workshop
workshopRef = Workshop
endif
EndFunction
Bool Function PlayerIsNearby(float distance = 2500.0)
bool nearBy = GetDistance(Game.GetPlayer()) < distance
return nearBy
EndFunction
Bool Function WorkshopCanBeInitialized()
int c = 0
; Worshop not registered yet
if workShopRegistered == false
return false
endif
; Workshop allready owned by player
if workshopRef.OwnedByPlayer == true
return true
endif
; Workshop can be unlocked for free
if UnlockForFree == true
return true
endif
; Actors to kill check
if actorRefsKilled == false
if ActorRefsToKill.Length > 0
int killCount = 0
c = 0
while (c < ActorRefsToKill.Length)
if (ActorRefsToKill[c] as Actor).IsDead()
killCount += 1
endif
c += 1
endwhile
if killCount == ActorRefsToKill.Length
DebugTrace("All actors killed")
actorRefsKilled = true
endif
else
DebugTrace("No actor to kill")
actorRefsKilled = true
endif
endif
; Quests completed check
if questsCompleted == false
if QuestsToComplete.Length > 0
int questCount = 0
c = 0
while (c < QuestsToComplete.Length)
if QuestsToComplete[c].IsCompleted()
questCount += 1
endif
c += 1
endwhile
if questCount == QuestsToComplete.Length
DebugTrace("All quests completed")
questsCompleted = true
endif
else
DebugTrace("No quest to complete")
questsCompleted = true
endif
endif
; Quest stages completed check
if questStagesCompleted == false
if QuestStagesToComplete.Length > 0
int questStagesCount = 0
c = 0
while (c < QuestStagesToComplete.Length)
DebugTrace("Checking for quest " + (QuestStagesToComplete[c].QuestToSet as Quest) + " stage " + QuestStagesToComplete[c].StageToSet + ". Current stage: " + (QuestStagesToComplete[c].QuestToSet as Quest).GetStage())
if (QuestStagesToComplete[c].QuestToSet as Quest).GetStage() > QuestStagesToComplete[c].StageToSet || (QuestStagesToComplete[c].QuestToSet as Quest).IsCompleted()
questStagesCount += 1
endif
c += 1
endwhile
if questStagesCount == QuestStagesToComplete.Length
DebugTrace("All quests stages completed")
questStagesCompleted = true
endif
else
DebugTrace("No quest stages to complete")
questStagesCompleted = true
endif
endif
; Location cleared check
if locationCleared == false
if UnlockWhenCleared
if GetCurrentLocation().IsCleared()
DebugTrace("Location cleared")
locationCleared = true
endif
else
DebugTrace("No location to clear")
locationCleared = true
endif
endif
; Check if all conditions are met
if actorRefsKilled && questsCompleted && questStagesCompleted && locationCleared
DebugTrace("All quests and quest stages completed, all actors killed, location cleared")
return true
else
return false
endif
EndFunction
ObjectReference Function GetSpawnMarker()
int c = 0
float highestDistance = 0
ObjectReference attackMarkerRef
ObjectReference[] attackMarkers = GetLinkedRefChildren(WorkshopLinkAttackMarker)
while (c < attackMarkers.Length)
if attackMarkers[c].GetDistance(Game.GetPlayer()) > highestDistance
highestDistance = attackMarkers[c].GetDistance(Game.GetPlayer())
attackMarkerRef = attackMarkers[c]
endif
c += 1
endwhile
return attackMarkerRef
EndFunction
; Callback function for workshop parent.
Event WorkshopParentScript.WorkshopInitializeLocation(WorkshopParentScript akSender, Var[] akArgs)
if workShopRegistered == false
DebugTrace("WorkshopInitializeLocation event received")
if (akArgs.Length > 0)
WorkshopScript workshopCheck = akArgs[0] as WorkshopScript
if workshopCheck
workShopRegistered = true
DebugTrace("Workshop " + workshopCheck.GetWorkshopID() + " successfully registered.")
else
DebugTrace("WorkshopInitializeLocation event received with invalid arguments")
endif
else
DebugTrace("WorkshopInitializeLocation event received with insufficient arguments")
endif
endif
EndEvent
Function DebugTrace(string text)
Debug.Trace("THEW DEBUG - Workshop Controller - Workshop: " + workshopRef + " - " + text)
EndFunction