Ich komme einfach nicht richtig zum Zocken, bin jetzt wohl langsam mehr als 10 Mal durch die Vault. Hintergrund: Wenn einem seine stabilität lieb sit, soll man keine Mods innrhalb eines Durchagngs installieren, vor allem keine gescripteten. Auf ejden fall sit das mein Test-Drive bis hin zum Red Rocket und meienr neuen Siedlung Red Rocket Cave. Erst wenn ich sicher bin, dass bis hierhin alles klappt, wie ich es will, geht es weiter.
Habe bereits wieder einen Mod deinstalliert und zwar Knockdown Overhaul, Das mag sicher nicht schlecht funktionieren, abeer ich traue halt einfach nur meinem eigenen Scripting und nicht mal dem. Aber wenn man fünfhundert Fehlermeldungen in mein Log bringt, muss man schon ein Über-Mod sein, damit man drin bleibt.
Ist vor allem interessant, wie er auf die exakt gleiche weise Gegner anpasst und zwar auf dem Spell LegendaryEffect, der praktisch jeder Actor im Spiel hat, musste einen Patch amchen, um beides laufen alssen zu können. Nur gibt mein Magic Effect alle paar Tage mal 20 Zeilen Fehler ins Log, die man aus meiner Sicht nicht fixen kann.
Dnn habe ich noch Creative Clutter fertig gefixt. Das ist sicher ein Must Have, aber im Scripting liegt er hinter allem anderen. Die Installationsroutine habe ich (wie bei Woodies Wasteland tuff) einfach gelöscht und manuell zugewiesen, das funktionierte sicher nicht hundertprozentig richtig und wenn das Spiel aus irgend einem Grund schon instabil ist, möchte ich nicht, dass beide Mods praktisch gleichezitig jedes Mal wieder die Formlisten des Workshop-Menus anfassen.
Dann gab es zwei Kühlschränke mit fehlerhaften Eigenschaften, die zu Script-Crashes und damit zum Nicth-Funktionieren des Systems führten. Musste das Hacken, um das weg zu kriegen.
Im Moment kotzt es mich gerade an, dass ich scheinbar nicht zu der letzten Version der Vanilla-Scripte komme. Scheinbar sind die Scripte im CK etwa auf Stand 1.5, statt 1.8, wie sie es sein sollten und ich kriege das nicht hin, die upzudaten. Das führt dazu, dass von mir geänderte sScripte nicht mit anderen übereinstimmen und neu geänderte Scripte eigentlich alte sind und nicht richtig funktionieren. Denke zwar nicht, dass es schlimm ist, aber es nervt trotzdem.
Dafür habe ich endlich herausgefunden, wie man einen Workshop in einem Keller mit dem Eltern-Workshop verlinkt, ohne dass komische Effekte auftreten, aber dafür immer mit den Items aus allen verlinkten Workshops versehen sind. Einfach die Keller-Location mit der Parent-Location per Script über den Karawanenlink verlinken.
Wen es interessiert, hier der aktuelle Stand meines Workshop-Controller-Scripts, das auf einem Aktivator liegt, den man mit bestehenden Workshops oder neuen verlinken kann. Im Fall eines neu erstellten Workshops(d.h. in einem laufenden Durchgang hinzugefügt) registriert es automatisch den Workshop im System, sodass er voll funktionsfähig wird. In diesem Script findet man alles, was man braucht. Falls es jemand verwenden möchte, kann ich gerne erklären, wie das geht.
Scriptname THEW:THEWWorkshopController extends ObjectReference
Group Flags
Bool Property IsNewWorkshop = false 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 = false 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. Do not use this for settlements unlocked by a quest.}
Bool Property ForceDebug = false Auto Const
{If set to true, this workshop will be registered and unlocked from this script again when all conditions are met.
Generally used for bugged vanilla settlements. Try to remove this flag before starting a new playthrough.}
EndGroup
Group EnableDisableOnUnlock
ObjectReference[] Property EnableOnUnlock Auto Const
{References to enable on unlock.}
ObjectReference[] Property DisableOnUnlock Auto Const
{References to disable on unlock.}
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
{If this is set true, location needs to be cleared. }
ObjectReference[] Property ActorRefsToKill Auto Const
{A list of actors the player has to kill. }
Quest[] Property QuestsToComplete Auto Const
{A list of quests to complete. }
Quest:QuestStage[] Property QuestStagesToComplete Auto Const
{A list of quest stages to complete. }
EndGroup
Group SettlementSystem
Location Property LinkedLocation Auto Const
{If defined the workshop will be linked with this location after unlock. Use it for sub cells of a workshop, eq from a cellar. }
Bool Property AddSettlersOnInit = false Auto Const
{Settlers will be added after unlock. }
Int Property AddSettlersCount = 3 Auto Const
{This count of settlers will be added. }
int property MaxTriangles auto
{ if > 0, initialize WorkshopMaxTriangles to this value }
int property MaxDraws auto
{ if > 0, initialize WorkshopMaxDraws to this value }
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.}
EndGroup
Group AnnoyanceSystem
ActorBase[] Property AnnoyanceActors Auto Const
{ A list of small enemies spawned in an interval to add life to a settlement. }
EndGroup
Group AttackSystem
WorkshopAttack[] Property WorkshopAttacks Auto Const
{A list of encounter groups to spawn. To Do!. }
EndGroup
Group Data
ObjectReference[] Property AttackMarker Auto Const
{Obsolete - delete var before next playthrough. }
Actor Property Player Auto Const Mandatory
WorkShopParentScript Property WorkShopParent Auto Const Mandatory
GlobalVariable Property GameDaysPassed Auto Const Mandatory
GlobalVariable Property GameHour Auto Const Mandatory
KeyWord Property WorkshopLinkAttackMarker Auto Const Mandatory
EndGroup
; Internal vars
WorkShopScript workshopRef
bool sysInitialized = false
bool workShopInitialized = false
bool workshopDrawInitialized = false
bool workShopRegistered = false
bool settlersSpawned = false
bool actorRefsKilled = false
bool questsCompleted = false
bool questStagesCompleted = false
bool locationCleared = false
float sysInterval = 60.0
int updateTimerId = 1
float updateInterval = 1.0
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
int forceDebugCount = 0
; Attack data type
Struct WorkshopAttack
Bool NightOnly = false
Bool IsHardcore = false
ActorBase EnemyActorsBoss
ActorBase EnemyActorsKnight
ActorBase EnemyActorsGeneral
ActorBase EnemyActorsPet
EndStruct
Event OnLoad()
DebugTrace("Workshop Controller loaded. Registered: " + workShopRegistered + " Debug: " + ForceDebug)
if sysInitialized == false || (ForceDebug == true && forceDebugCount < 1)
forceDebugCount = forceDebugCount + 1
sysInitialized = true
workShopInitialized = false
workShopRegistered = false
settlersSpawned = false
actorRefsKilled = false
questsCompleted = false
questStagesCompleted = false
locationCleared = false
GetMyWorkshop()
RegisterWorkshop()
; Unlocked only from the linked workshop, in case somebody don't want unused settlements in his list.
RegisterForRemoteEvent(workshopRef, "OnActivate")
endif
if workshopDrawInitialized == false
if MaxTriangles > 0
workshopRef.SetValue(WorkshopParent.WorkshopMaxTriangles, MaxTriangles)
endif
if MaxDraws > 0
workshopRef.SetValue(WorkshopParent.WorkshopMaxDraws, MaxDraws)
endif
workshopDrawInitialized = true
endif
if workShopInitialized == true
; Just in case, this link is removed for some reason
if LinkedLocation
DebugTrace("Linked my location to location " + LinkedLocation + ".")
workshopRef.myLocation.AddLinkedLocation(LinkedLocation, WorkshopParent.WorkshopCaravanKeyword)
endif
endif
EndEvent
Event OnTimerGameTime(int aiTimerID)
if aiTimerId == updateTimerId
UpdateWorkshop()
elseif aiTimerId == annoyanceTimerId
SpawnAnnoyance()
elseif aiTimerId == attackTimerId
SpawnEnemy()
endif
EndEvent
Event ObjectReference.OnActivate(ObjectReference akSender, ObjectReference akActionRef)
DebugTrace("Workshop activated.")
if workShopInitialized == false && akActionRef == Player && WorkshopCanBeInitialized()
DebugTrace("Trying to unlock workshop OnActivate().")
workShopInitialized = true
UnlockWorkshop()
endif
EndEvent
Function UpdateWorkshop()
; Spawn first settlers
if settlersSpawned == false && AddSettlersOnInit
settlersSpawned = true
int c = 0
DebugTrace("Initial settler will be created.")
while c < AddSettlersCount
WorkshopParent.CreateActorPUBLIC(workshopRef, GetSpawnMarker(), c == 0)
Utility.Wait(1.5)
c += 1
endWhile
DebugTrace(AddSettlersCount + " initial settler created.")
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("Location registration disabled on this workshop.")
workShopRegistered = true
endif
EndFunction
Function UnlockWorkshop()
DebugTrace("Workshop unlocked.")
if workshopRef.OwnedByPlayer == false && UnlockWhenAble == true
workshopRef.SetOwnedByPlayer(true)
DebugTrace("Workshop now owned by player.")
endif
UnregisterForRemoteEvent(workshopRef, "OnActivate")
StartTimerGameTime(updateInterval, updateTimerId)
StartTimerGameTime(Utility.RandomFloat(minAnnoyanceDay, maxAnnoyanceDay), annoyanceTimerId)
StartTimerGameTime(Utility.RandomFloat(minAttackDay, maxAttackDay), attackTimerId)
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)
DebugTrace("Object " + DisableOnUnlock[c] + " disabled.")
DisableOnUnlock[c].Disable()
c += 1
endwhile
endif
if LinkedLocation
DebugTrace("Linked my location to location " + LinkedLocation + ".")
workshopRef.myLocation.AddLinkedLocation(LinkedLocation, WorkshopParent.WorkshopCaravanKeyword)
endif
EndFunction
; No markers or no annoyances: This function will be disabled for the next time.
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()
if spawnMarkerRef
spawnedActor = spawnMarkerRef.PlaceAtMe(AnnoyanceActors[spawnType], 1)
spawnedActor.SetLinkedRef(self)
StartTimerGameTime(Utility.RandomFloat(minAnnoyanceDay, maxAnnoyanceDay), annoyanceTimerId)
endif
endif
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
else
DebugTrace("Could not aquire workshop from linked ref or property.")
endif
EndFunction
Bool Function PlayerIsNearby(float distance = 2500.0)
bool nearBy = GetDistance(Game.GetPlayer()) < distance
return nearBy
EndFunction
Bool Function WorkshopCanBeInitialized()
int c = 0
; Workshop 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 - Location: " + GetParentCell() + " - Workshop: " + workshopRef + " > " + text)
EndFunction
Alles anzeigen