-
Posts
15 -
Joined
-
Last visited
Everything posted by comradezero
-
Uninstalled Immersive Roads, this texture is still floating there mid-air. Uninstalling Immersive Roads worked.
-
I've encountered these floating roads in several locations. Here is a screenshot of one example in Whiterun. Following is my load order. I've merged some plugins that affect visuals (relevant mod here is Immersive Roads). Has anyone else encountered this bug?
-
Getting a list of all workshops
comradezero replied to comradezero's topic in Fallout 4's Creation Kit and Modders
The Workshops array is indeed the same every time we look at it, but the loop in CheckForSettlementsToClean() doesn't reach the same result every time it's called by OnTimerGameTime(). Say, for example, that Workshops[0] is passed to QueueSettlement() the first time that CheckForSettlementsToClean() is called. The next time that CheckForSettlementsToClean() runs, ShouldCleanSettlement(Workshops[0]) will return false, and the loop will then look at Workshops[1], and so on and so forth until it finds the next eligible settlement. I think I may get what you're asking: why bother looping through the same Workshops array elements if they're already marked "clean" (stored in the CleanedSettlements array)? At the moment, rather than removing cleaned settlements from the Workshops array, I'm just adding them to the CleanedSettlements array and checking that array for each settlement during the loop in CheckForSettlementsToClean(). If I wanted to instead remove cleaned settlements from the Workshops array, I would just update the RecordQueuedSettlement() and SettlementIsClean() functions accordingly, and not bother with the CleanedSettlements array at all. I'm not sure whether it's more efficient to declare two arrays with a given number of elements at the beginning, or to remove elements from an existing array (resizing that array) every time CheckForSettlementsToClean() is called. Normally I think that it's considered more memory-intensive to resize an array. -
Getting a list of all workshops
comradezero replied to comradezero's topic in Fallout 4's Creation Kit and Modders
I'm glad I could help, y'all. ThoraldGM and spacefiddle, sorry to hear about your injuries...me, I'm a seasonal worker so I get the summer off other than a bit of work that I do on the side for clients. -
Getting a list of all workshops
comradezero replied to comradezero's topic in Fallout 4's Creation Kit and Modders
In my script, I use the WorkshopScript boolean property OwnedByPlayer to determine whether a given workshop is owned by the player. Is that what you mean by an activated settlement? Does this answer your question? If not and you're looking for something more specific, I'm still trying to learn Papyrus and the CK (been at it for a few days now) so I'd be happy to try helping with your Scavver looting problem. Don't have to go back to work until October 1. :D -
Getting a list of all workshops
comradezero replied to comradezero's topic in Fallout 4's Creation Kit and Modders
Thanks. :smile: I couldn't find much documentation on using Alias text replacement, either, other than this and a few other pages on that wiki. So I turned to looking through base scripts, and I did indeed find MessageRefAlias and MessageLocationAlias in WorkshopParentScript. To get them working with text replacement, I set up my own versions of them, along with Messages, in the CK as follows: 1) I opened up my Quest from the Object Window > Character > Quest, navigated to the Quest Aliases tab, and created two new Aliases like so: http://motheroforder.net/wp-content/uploads/2016/07/message-location-alias.jpg http://motheroforder.net/wp-content/uploads/2016/07/message-ref-alias.jpg 2) Then I navigated to the Scripts tab, selected my script (after compiling it), then Properties, and assigned my script's ReferenceAlias properties to the Aliases that I just created, like so: http://motheroforder.net/wp-content/uploads/2016/07/message-location-alias_property.jpg http://motheroforder.net/wp-content/uploads/2016/07/message-ref-alias-property.jpg 3) I created my Messages under Object Window > Miscellaneous > Message: http://motheroforder.net/wp-content/uploads/2016/07/clean-settlement-msg.jpg http://motheroforder.net/wp-content/uploads/2016/07/clean-settlement-pre-msg.jpg 4) and set up the Message properties much the same way as I did for my Aliases: http://motheroforder.net/wp-content/uploads/2016/07/clean-settlement-msg_property.jpg http://motheroforder.net/wp-content/uploads/2016/07/clean-settlement-pre-msg_property.jpg The DisplayMessage() function takes care of forcing the Aliases to point at the Location where I want them to point in my script, so the Message text replacement works properly. As you can see, although I set up MessageRefAlias, I haven't set up the corresponding Messages to make use of it, and in my script I'm just using MessageLocationAlias. Still, I just wanted to go ahead and set both Aliases up while I'm working on my mod in case I want to use one or either of them later; I'll eventually trim down to just what I need or anticipate needing in the future. Also, I suppose that I could have tried simply pointing my ReferenceAlias properties to the corresponding Aliases under the WorkshopParent Quest, but I wanted to be safe and set up copies attached to my own Quest, just in case. If I had to guess why I needed to copy DisplayMessage() to my own script and couldn't just call WorkshopParent.DisplayMessage(), I'd say it's because the original function is looking for Aliases attached to its own Quest. But since Messages are attached to Quests, and hence will look for Aliases attached to the same Quests, I think what I did is necessary. I could just create Messages and point them to the WorkshopParent Quest and point my ReferenceAlias properties to the same Quest, and I think that would all work, but like I said, I want to set up these assets separately for my Quest for the time being. -
Getting a list of all workshops
comradezero replied to comradezero's topic in Fallout 4's Creation Kit and Modders
Finally, I did it. My code was fine several hours ago, but I missed a checkbox ("Stores Text") one on of my reference aliases under Quest > Quest Aliases. For those who are curious, I used the WorkshopParent quest as a model (I abandoned the idea of modeling WorkshopGunnerAttack01 that I'd been pursuing, as mentioned in the thread linked in the OP). One hang-up that I ran into was that I couldn't call WorkshopParent.DisplayMessage() and still get successful replacement text. I even passed self into the parameters (e.g. self.MessageName), with no success. So I simply copied the function into my script, and it worked. Now, on to actually removing that pesky debris. -
Getting a list of all workshops
comradezero replied to comradezero's topic in Fallout 4's Creation Kit and Modders
Well, I've populated the lost of Workshops, but getting their Location is still eluding me. I've tried 2 methods. Method A: Location function GetSettlementLocation(WorkshopScript inputSettlement) WorkshopScript workshopRef = inputSettlement as WorkshopScript if (workshopRef) WorkshopParent = workshopRef.WorkshopParent if (WorkshopParent) Location theLocation = workshopRef.myLocation as Location endif endif return theLocation endFunction(I've also tried using GetCurrentLocation() rather than myLocation.) Method B: Location[] Property WorkshopLocations Auto ; Populate WorkshopLocations. Called before the below function. function SetWorkshopLocations() WorkshopLocations = WorkshopParent.WorkshopLocations endFunction Location function GetSettlementLocation(WorkshopScript inputSettlement) int index = Workshops.Find(inputSettlement) return WorkshopLocations[index] endFunctionI've used debug.MessageBox() to try to display the location like so (using 0 as an example): debug.MessageBox(WorkshopLocations[0])My output is just "[Location" (without the quotes). For the moment, I'm stumped. -
Getting a list of all workshops
comradezero replied to comradezero's topic in Fallout 4's Creation Kit and Modders
OK, I figured out what my problem was. I forgot to pick the Object for my WorkshopParent property. Now I successfully get a list of all of the settlements. For those who would like to know specifically how: 1) Open up the Quest. 2) Navigate to the Scripts tab. 3) Click on Properties. 4) Click on WorkshopParent. 5) Select "WorkshopParent" from the Pick Object drop-down menu. This same process has to be done for reference aliases, messages, and the like. Now I've just gotta get the text replacement to work in my messages. -
Hi all. I could really use some help here. I'm working on my first mod at the moment, and I've written a script attached to my quest that compiles successfully. So that you have a picture of what I'm trying to accomplish, this is what I hope the script will do: 1) Loops through all workshops, 2) finds workshops with at least 10 settlers, 3) displays a message saying that settlers of the found workshop will clean their settlement up in 2 days, 4) starts a timer (atm it's short, but it will be 48 hours), 5) and at the end of the timer, removes a list of debris and displays another message. I'm attaching the script for reference, as it's a bit long for a post. The problem that I have is that I can't get a list of all of the workshops. Here is the pertinent function: ; Populate workshopList. WorkshopScript[] function SetWorkshopList() workshopList = WorkshopParent.Workshops endFunctionI used debug.MessageBox() to display the length of the resulting workshopList variable: 0. As a result, my script never gets through the first step, and nothing happens. What am I doing wrong? Thanks! PS--this thread is a follow-up to this one, and I referenced some of the suggestions in this thread for getting the workshops list and counting the settlers.
-
So, I've answered the basic question that I was looking to answer. My script compiles successfully but I'm still having troubles capturing the right data. Since that's a different issue than what I posted about, I'll start a new thread for a different question. For reference, this is what I have so far: Scriptname CleanSettlementScript extends Quest {This script automates settlers removing brambles and debris from their settlements.} Import Keyword WorkshopParentScript Property WorkshopParent Auto WorkshopScript Property WorkshopScriptRef Auto WorkshopScript[] workshopList Keyword Property QuestEvent Auto Message Property CleanSettlementPreMsg Auto {This message alerts the player to a given settlement that will be cleaned.} Message Property CleanSettlementMsg Auto {This message alerts the player to a given settlement that has been cleaned.} ; The time, in game-time hours, between checking for settlements to queue. float checkTimer = 0.3 const ; The time, in game-time hours, between queuing a settlement and cleaning it. float cleanTimer = 0.3 const ; The timerID for checking for settlements to queue. Used in OnTimerGameTime(). int checkTimerID = 1 const ; The timerID for cleaning settlements in the queue. Used in OnTimerGameTime(). int cleanTimerID = 2 const ; An object holding the settlement queued for cleaning. WorkshopScript queuedSettlement ; The minimum number of settlers needed to trigger cleaning the settlement. int settlerGoal = 10 const ; The number of settlers in a given settlement. int settlerCount = 0 ; The number of settlements. int workshopCount = 0 ; A list of cleaned settlements. int[] cleanList ; Start up the plugin. Event OnInit() debug.trace(self + "OnInit") ; A list of settlements. workshopList = GetWorkshopList() workshopCount = workshopList.length ; A list of cleaned settlements. cleanList = new int[workshopCount] StartTimerGameTime(checkTimer, checkTimerID) EndEvent ; Calls the CheckForSettlementsToClean() and CleanSettlement() functions. Event OnTimerGameTime(int inputTimerID) debug.trace(self + "OnTimerGameTime") if inputTimerID == checkTimerID ; Check for settlements to clean. CheckForSettlementsToClean() elseif inputTimerID == cleanTimerID ; Clean queued settlement. CleanSettlement() endif EndEvent function CheckForSettlementsToClean() debug.trace(self + "CheckForSettlementsToClean") int i = 0 bool break = false while (i < workshopCount) if !break if ShouldCleanSettlement(workshopList[i]) QueueSettlement(workshopList[i]) break = true endif i += 1 else i = workshopCount endif endWhile StartTimerGameTime(checkTimer, checkTimerID) endFunction ; Calls the DisableObjects() function and displays a message. function CleanSettlement() debug.trace(self + "CleanSettlement") if queuedSettlement DisableObjects(queuedSettlement) SetQueuedSettlement(NONE) CleanSettlementMsg.Show() QuestEvent.SendStoryEvent(queuedSettlement.myLocation) endif endFunction ; Disables objects for the provided settlement. function DisableObjects(WorkshopScript inputSettlement) debug.trace(self + "DisableOBjects") ; Stuff goes here endFunction ; Queues settlement for cleaning. function QueueSettlement(WorkshopScript inputSettlement) debug.trace(self + "QueueSettlement") SetQueuedSettlement(inputSettlement) StartTimerGameTime(cleanTimer, cleanTimerID) ; A timer ID of 1 is used for queued settlements. RecordQueuedSettlement(inputSettlement) CleanSettlementPreMsg.Show() QuestEvent.SendStoryEvent(inputSettlement.myLocation) endFunction ; Records queued settlement in cleanList array. function RecordQueuedSettlement(WorkshopScript inputSettlement) debug.trace(self + "RecordQueuedSettlement") int arrayIndex = workshopList.Find(inputSettlement) cleanList[arrayIndex] = arrayIndex endFunction ; Checks to see if settlement should be queued for cleaning. bool function ShouldCleanSettlement(WorkshopScript inputSettlement) debug.trace(self + "ShouldCleanSettlement") if GetSettlerCount(inputSettlement) >= settlerGoal && !SettlementIsClean(inputSettlement) return true else return false endif endFunction ; Checks whether settlement has already been stored in the cleanList array. bool function SettlementIsClean(WorkshopScript inputSettlement) debug.trace(self + "SettlementIsClean") int arrayIndex = workshopList.Find(inputSettlement) if cleanList.Find(arrayIndex) < 0 return false else return true endif endFunction ; Gets the queued settlement. WorkshopScript function GetQueuedSettlement() return queuedSettlement endFunction ; Gets the settlement location. ; function GetSettlementLocation(inputSettlement) ; endFunction ; Gets the settlerCount for the inputSettlement. int function GetSettlerCount(WorkshopScript inputSettlement) debug.trace(self + "GetSettlerCount") WorkshopDataScript:WorkshopRatingKeyword[] ratings WorkshopScriptRef = inputSettlement as WorkshopScript if (WorkshopScriptRef) WorkshopParent = WorkshopScriptRef.WorkshopParent if (WorkshopParent) ratings = WorkshopParent.WorkshopRatings settlerCount = WorkshopScriptRef.GetBaseValue(ratings[WorkshopParent.WorkshopRatingPopulation].resourceValue) as int endif endif ratings = NONE return settlerCount endFunction ; Sets the queued settlement function SetQueuedSettlement(WorkshopScript settlementToQueue) queuedSettlement = settlementToQueue endFunction ; Return workshopList. WorkshopScript[] function GetWorkshopList() debug.trace(self + "GetWorkshopList") if workshopList.length <= 0 SetWorkshopList() endif return workshopList endFunction ; Populate workshopList. WorkshopScript[] function SetWorkshopList() debug.trace(self + "SetWorkshopList") workshopList = WorkshopParent.Workshops endFunction As for the Quest, under Quest Data in the CK, I selected Script Event under the Event drop-down menu, and under Quest Aliases I created an Alias called myLocation. For that, I selected as the Fill Type "Find Matching Location," checked "From Event," and under the Event Data drop-down I selected Location. This is fed to the Quest by the SendStoryEvent() function. For getting Messages to show, I followed Bethesda's tutorial. Curiously, it's not on the Message page, but on a more or less random one. In the message, I used <Alias=myLocation> to grab the Quest Alias that I created as described above. I am using the WorkshopGunnerAttack01 Quest as a guide/example for how to do some of this.
-
OK, so I have this: Scriptname CleanSettlement extends Quest {A test script to display a message 48 hours after a settlement has obtained at least 10 settlers.} Quest Property WorkshopParentScript Auto Const Mandatory Quest Property WorkshopScript Auto Const Mandatory Message Property CleanSettlementMsg Auto Int CleanSettlementTimer = 48 Int SettlerCount = 0 ObjectReference[] Settlers = WorkshopParentScript.GetWorkshopActors(WorkshopScript workshopRef) While (SettlerCount < Settlers.length) SettlerCount += 1 EndWhile If SettlerCount >= 10 ;if the population is 10 or more StartTimerGameTime(48, CleanSettlementTimer) ;starts a timer for 48 hours in-game EndIf Event OnTimerGameTime(CleanSettlementTimer) ;when the timer expires, show the message Debug.MessageBox("The event is triggering this message.") CleanSettlementMsg.Show() EndEventWhen I compile, it fails, throwing these errors: C:\Users\...\AppData\Local\Temp\PapyrusTemp\CleanSettlement.psc(11,29): no viable alternative at input 'WorkshopParentScript' C:\Users\...\AppData\Local\Temp\PapyrusTemp\CleanSettlement.psc(11,49): required (...)+ loop did not match anything at input '.' C:\Users\...\AppData\Local\Temp\PapyrusTemp\CleanSettlement.psc(11,18): Unknown user flag workshopparentscript No output generated for CleanSettlement, compilation failed. What are the numbers in parentheses? I'm accustomed to seeing line and column numbers but the above doesn't correspond to what I've got in my file. As for the message, I'm not sure that I understand what you're suggesting. Where would I use <Alias=MyMessageName>? And if I have to use the name of the location in my message body, what's the point in text replacement? At the moment I've added a Location Alias to the Quest, associated it with SanctuaryHillsLocation, and used the Alias, "Sanctuary." In my message, titled CleanSettlementMsg (so its content should be displayed by the above script, right?), I have this: The people of <Alias=Sanctuary> have cleaned up their settlement! Of course, I still have no idea how I would get the message to dynamically show any location.
-
Thanks! That's very helpful. How does this line know which settlement's settlers it is counting: ObjectReference[] Settlers = WorkshopParentScript.GetWorkshopActors(WorkshopScript workshopRef)Is that counting the total of all settlement's settlers? I'm looking through the WorkShopParentScript.psc and WorkshopScript.psc files but it's not yet apparent to me how this works. I'm not clear on how this example script knows which settlement it's dealing with. Do I need to actually do something a lot more specific, as talked about here? Also, in addition to displaying a message, what I'm looking for is to remove a bunch of objects from the settlement in the same Event that triggers the message. Would I need to go into the Creation Kit and get reference ID's for all of the objects that I want to remove, and then add those to an array (for example) and iterate through that with a command to remove all of the objects from the game? For example, using ObjectReference Disable? As for displaying the message, does the message ID that I create in the CK need to match the Message Property that I'm setting in the script (in this example, DebrisClearMessage)? For text replacement, there's not anything in the above linked documentation that talks about locations. Would I use <Alias=SanctuaryHillsLocation> for just Sanctuary?
-
Hi, I'm working on my first mod using the Creation Kit. I'm getting rid of the debris in settlements, starting with Sanctuary, and want to set two conditions so that 1) the settlement needs to have 10 or more settlers and 2) 48 in-game hours need to have passed in order for the debris to be cleared, with a message appearing that says, "The people of [settlement name] have cleaned up their settlement!" Is this possible, and can this be done in the Creation Kit interface? Does it need to be done in Papyrus? I write PHP/HTML/CSS and can read/dabble in other languages, I just need a starting point if using Papyrus is necessary, as I'm totally new to this and haven't been able to find any information on setting conditions in the CK. Any pointers would be much appreciated!