Jump to content

NoCashNoExp

Members
  • Posts

    60
  • Joined

  • Last visited

Everything posted by NoCashNoExp

  1. Sadly, pathing is handled by the engine. PathToReference() function can fail due to a couple of reasons. You can check if the pathing worked or not. bool success = Looter1.PathToReference(Corpse1, 1.0) Debug.Notification("Did Looter go to corpse? " + success)You need to test the intricacies of this function because I have no clue what it does. Try a simple straight path first. One more advice for your sanity, enable papyrus logging and start using Debug.Trace() instead. The output should be in Documents/My Games/Fallout4/Logs/Script/Script0.log
  2. Do not modify array length while looping on it. Example: Array has 5 ObjectReferences and the 3rd is the player. Demonstration: - [Actor, Actor, Player, Actor, Actor] i=0, len=5 At i = 2 (Remove Player) - [Actor,Actor,Actor,Actor] BUT len was resolved to = 5 At i = 4 [Actor,Actor,Actor,Actor,??? <---- Out of bounds] len is still = 5
  3. Looter variables or corpse variables are not being assigned properly. Even if the actor failed to path to their target, the items should still be moved to them. Also, PathToReference is latent meaning it blocks script execution until it's done so your code should be like this: Scriptname NPCLootingScript extends ReferenceAlias Actor Property PlayerRef Auto Const Actor Property Corpse1 Auto Actor Property Corpse2 Auto Actor Property Corpse3 Auto Actor Property Looter1 Auto Actor Property Looter2 Auto Actor Property Looter3 Auto int Property TimerDuration Auto Const Keyword Property ActorTypeNPC Auto Keyword Property RELootedCorpse Auto Const int Property distance Auto Const ObjectReference[] Property NPCs Auto Event OnInit() Self.StartTimer(TimerDuration, 0) EndEvent Event OnTimer(int aiTimerID) Debug.Notification("Script running") If !PlayerRef.IsInCombat() NPCs = PlayerRef.FindAllReferencesWithKeyword(ActorTypeNPC, distance) int i = 0 While i < NPCs.Length Actor MyActor = NPCs[i] as Actor ActorBase PlayerBase = MyActor.GetActorBase() String name = PlayerBase.GetName() as String Debug.Notification("Found " + name + " in" + i as string) if MyActor == PlayerRef NPCs.Remove(i) ElseIf MyActor.IsDead() && !MyActor.HasKeyword(RELootedCorpse) if !Corpse1 Debug.Notification("Corpse1 Assigned") <---- Corpse1 = MyActor ElseIf !Corpse2 Corpse2 = MyActor ElseIf !Corpse3 Corpse3 = MyActor EndIf Else if !Looter1 Debug.Notification("Looter1 Assigned") <---- Looter1 = MyActor ElseIf !Looter2 Looter2 = MyActor ElseIf !Looter3 Looter3 = MyActor EndIf EndIf i+=1 EndWHile If Looter1 && Corpse1 Debug.Notification("Looter1 is moving") <---- Looter1.PathToReference(Corpse1, 1.0) Corpse1.RemoveAllItems(Looter1) Corpse1.AddKeyword(RELootedCorpse) Debug.Notification("Looter1 is done looting") <---- EndIf If Looter2 && Corpse2 Debug.Notification("Looter2 is moving") <---- Looter2.PathToReference(Corpse2, 1.0) Corpse2.RemoveAllItems(Looter2) Corpse2.AddKeyword(RELootedCorpse) Debug.Notification("Looter2 is done looting") <---- EndIf If Looter3 && Corpse3 Debug.Notification("Looter3 is moving") <---- Looter3.PathToReference(Corpse3, 1.0) Corpse3.RemoveAllItems(Looter3) Corpse3.AddKeyword(RELootedCorpse) Debug.Notification("Looter3 is done looting") <---- EndIf EndIf Self.StartTimer(TimerDuration, 0) EndEvent
  4. The problem: You need to detect when the player has acquired a new perk and run your code. Sadly, I don't think there's a way to do this using a quest script. If you don't mind modifying the vanilla perk record, you can create a fragment script on the perk itself that runs when the perk gets added and removes the item.
  5. Well, the items array currently has base form junk items that the game decided to use up. This means we can copy those in another separate container and count them to make sure. This is untested and I am not sure if it will return correct numbers. It's more conceptual really. The problem is again how would you know that the game is done with RemoveComponents(). Scriptname TestScript extends Quest FormList Property CA_JunkItems Auto Const Mandatory ; A Formlist that contains all junk items in FO4. I found this one already made in CK but I am not sure if it has all the junk items. Component Property c_Steel Auto Const Mandatory Container Property TempContainer Auto Const Mandatory ; Temp Container Property Struct ConsumedItem Form baseForm int count EndStruct ConsumedItem[] items Event OnInit() AddInventoryEventFilter(CA_JunkItems) RegisterForRemoteEvent(Game.GetPlayer(), "OnItemRemoved") EndEvent Event ObjectReference.OnItemRemoved(ObjectReference akSender, Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) Debug.Trace("[TestScript] OnItemRemoved() Removed " + aiItemCount + " of item: " + akBaseItem) ConsumedItem cItem = new ConsumedItem cItem.baseForm= akBaseItem cItem.count = aiItemCount items.Add(cItem) EndEvent Function removeComps() items = None items = new ConsumedItem[0] Game.GetPlayer().RemoveComponents(c_steel, 20) Debug.Trace("[TestScript] removeComps() finished") EndFunction ; When to call this?? Function onRemoveComponentsDone() ​ ObjectReference cont = Game.GetPlayer().PlaceAtMe(TempContainer) int i = 0 While i < items.length cont.AddItem(items[i].baseForm, items[i].count, true) i = i + 1 EndWhile Debug.Trace("The game consumed (" + cont.GetComponentCount(c_steel) +") steel components from player") cont.DisableNoWait() cont.Delete() EndFunction Edit: I've just realised, this is such a roundabout way for this problem. Why not just call GetComponentCount() before even calling RemoveComponents() to make sure whether the container has 20 steel or not.
  6. I am going to offer my 2 cents here. This is the best I can come up with. Maybe you can improve this script. Replace player with your container's ObjectReference. Scriptname TestScript extends Quest FormList Property CA_JunkItems Auto Const Mandatory ; A Formlist that contains all junk items in FO4. I found this one already made in CK but I am not sure if it has all the junk items. Component Property c_Steel Auto Const Mandatory Struct ConsumedItem Form baseForm int count EndStruct ConsumedItem[] items Event OnInit() AddInventoryEventFilter(CA_JunkItems) RegisterForRemoteEvent(Game.GetPlayer(), "OnItemRemoved") EndEvent Event ObjectReference.OnItemRemoved(ObjectReference akSender, Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) Debug.Trace("[TestScript] OnItemRemoved() Removed " + aiItemCount + " of item: " + akBaseItem) ConsumedItem cItem = new ConsumedItem cItem.baseForm= akBaseItem cItem.count = aiItemCount items.Add(cItem) EndEvent Function removeComps() items = None items = new ConsumedItem[0] Game.GetPlayer().RemoveComponents(c_steel, 20) Debug.Trace("[TestScript] removeComps() finished") EndFunction ; When to call this?? Function onRemoveComponentsDone() int i = 0 While i < items.length Debug.Trace("[TestScript] Item: " + items[i].baseForm + ", Count: " + items[i].count) i = i + 1 EndWhile EndFunction The problem is I don't know how to detect when RemoveComponents() has done its work. removeComps() finishes before all the events are even fired. Maybe you could find a workaround for this one using timers or something. I honestly don't know
  7. That's why the address library exists but even this gets updated by people. So, there has to be some waiting period when a new fallout update comes out.
  8. My intention wasn't to discourage you but instead to save your time. It's not my place to say what you should do and what you shouldn't. If you're enjoying this and you have time to spend then by all means. Good luck on your mod.
  9. I am going to give you a bit of advice. You're going down a rabbit hole that has no end without an understanding of deeper computer science subjects such as assembly, how programs are executed/loaded into memory, stack/heap memory, hexadecimal and binary numbering systems and many many more. Trust me on this one you'll get nowhere useful. These addresses that you're writing down probably change each time you restart the game because of ASLR. What you're doing right now is called reverse engineering, if you truly what to learn that you will need dedicate time and research what topics are needed before you can even begin because there's a lot but if you're doing all of this to code a small or even a big mod for a game it's not the worth the time in my humble opinion.
  10. Depending on the items that need to be inserted in this container, I might have a better solution. GetGoldValue() allows you to retrieve the value of any form but it will only return the base value even for weapon/armors that have mods that modify their value. You can then make a x:y ratio between your currency and caps. MiscObject Property Caps001 Auto Const Mandatory ; Replace with your currency bool silentAdd = true ; Prevents displaying a message to the player when caps are added to their inventory Event OnInit() AddInventoryEventFilter(MiscItems) EndEvent Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) Game.GetPlayer().AddItem(Caps001, aiItemCount * akBaseItem.GetGoldValue(), silentAdd) EndEvent
  11. I've noticed when adding a new script that CK keeps track of all namespaces even for mods that I have completely deleted from the data folder. While it's a handy feature, I would still like to delete those namespaces until I am actually using them. Edit: I've found it. It's in the CreationKitPrefs.ini file under [Papyrus] category. The key always starts with "sMRUNamespace".
  12. Have you tried "Damn Apocalypse"? Personally, it's the mod that I always recommend to people asking for difficulty mods. It provides a good amount of challenge without making the game a chore.
  13. I am forcing the player to unequip/equip their weapon in my script. I am not sure if this is possible but I would like to cancel the unequipping and equipping animations to make it seem like nothing really happened (The ammo counter would be a dead giveaway but I'll handle that later). I don't really know anything about animations so I would like some advice. I currently have two leads. 1 - Play an Idle animation before or after the part where I start the unequip/equip functions. Doesn't seem to be working, either the idle doesn't play or it doesn't stop the animations from playing. 2 - This function from the creation kit documentation looks very promising but I have 0 clue how I could use something like this.
  14. There's actually a very cool mod called Minutemen (Radiant) Squads that allows you to assign squads to the minutemen quests. The problem with these kinds of mods honestly is that it's just a couple of button clicks on some UI. There's no player interaction at all. In the case of this mod, it's actually fixing an annoying issue in vanilla FO4 in a nice way. Let's say your new mod will allow Piper to complete some side quest on her own, how would you implement this? Do you have to go talk to her and tell her to do this quest? If that's the case what's, it's still some UI button click and the quest is magically done after some time. In that case, it's best just to leave the quest uncompleted because the player didn't really care about doing the quest in the first place so they clicked a couple of UI buttons to get the quest done. She just goes and does it on her own? How would you represent to the player that Piper did a quest on her own? There needs to be some kind of visual change in the world to indicate the quest is done instead of sending a boring Debug message "Piper finished quest X". What if the player wanted to do that quest themselves? There's really a lot of headaches and issues that spiral from this concept.
  15. If this variable X that is undefined is the name of your new book, you need to add it as a property to your script in order for the script to know about it. Create a new property of type book with the same name as the book's editor name that should fill it automatically. If it doesn't do it, make sure to fill it manually. You can now do AddItem(BookProperty) in the script fragment.
  16. I am also using MCM for some of my mods. Although, I don't know exactly how they do it, I can kind of take a guess. An interesting feature about MCM is that when you change something in the config.json file and open/close the MCM menu in game, your changes will get updated without restarting the game. It's possible but again I am not sure that these mods have code in their F4SE plugin that modifies the config.json file on the fly and there's some kind of undocumented rerender function in MCM that is used to update the screen. Edit: There's actually three functions in the MCM.psc file that could help you. GetModSettingString(), SetModSettingString() and RefreshMenu() meaning strings are implemented but the documentation is just old. I bet with a bit of tinkering, you can get them to work for you.
  17. Pretty sure OnBeginState event needs a string parameter which is the old state. Your code should look like this: Scriptname SpecIslandInstReborn:KlaxonToggleScript extends ObjectReference {Controls the Klaxon light in the workshop with a master enable parent marker (EnableMarker) and a switch with this script attached to turn on and off when the switch is activated} ObjectReference Property EnableMarker auto {The marker set as the enable parent of all the lights} ObjectReference Property myKlaxonLight auto Event OnInit() If (EnableMarker.IsDisabled()) GoToState("LightsOff") Else GoToState("LightsOn") EndIf EndEvent State LightsOff Event OnBeginState(string asOldState) EnableMarker.Disable() EndEvent Event OnActivate(ObjectReference akActionRef) GoToState("LightsOn") EndEvent EndState State LightsOn Event OnBeginState(string asOldState) EnableMarker.Enable() myKlaxonLight.Activate(Game.GetPlayer()) EndEvent Event OnActivate(ObjectReference akActionRef) GoToState("LightsOff") EndEvent EndState
  18. I have never really done patches with CK but in CK, you can select multiple objects from the object window and you can drag/move them to a formlist window that you have open. You can also click then shift + click to select from top to bottom.
  19. Ok, this is a bit complicated for your request but it might work. If you can attach this script to the cooking workbench object reference, this should make the bench automatically melt snow into water once the player moves snow to the workbench's inventory. I haven't really tested this, it's mostly just theory code. Scriptname SnowMelterScript extends ObjectReference Form Property YourModSnow Auto Const Mandatory Form Property YourModWater Auto Const Mandatory int Property timerIDIndex = 0 Auto Struct Recipe int timerID = 0 Form input Form output int itemCount = 0 EndStruct Recipe[] Property recipes Auto float timeForSnowToMelt = 60.0 Const ; In seconds Event OnInit() recipes = new Recipe[10] AddInventoryEventFilter(YourModSnow) EndEvent Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) ; If the player added snow to the cooking workbench If akBaseItem == YourModSnow ; If the array that is used to track recipes is not full If recipes.Length < 10 Debug.Notification("Starting New Recipe") ; Create new recipe Recipe newRecipe = new Recipe newRecipe.timerID = timerIDIndex newRecipe.input = YourModSnow newRecipe.output = YourModWater newRecipe.itemCount = aiItemCount recipes.Add(newRecipe) StartTimer(timeForSnowToMelt, timerIDIndex) timerIDIndex = timerIDIndex + 1 If timerIDIndex > 19 timerIDIndex = 0 EndIf Else Debug.Notification("Bench is full of recipes") EndIf EndIf EndEvent ; Some recipe finished its time Event OnTimer(int aiTimerID) int i = 0 ; Find the recipe in the array While i < recipes.Length && i != -1 If recipes[i].timerID == aiTimerID ; Found the recipe Recipe currentRecipe = recipes[i] ; Remove snow, add water to workbench RemoveItem(currentRecipe.input, currentRecipe.itemCount, true) AddItem(currentRecipe.output, currentRecipe.itemCount, true) ; Remove the tracked recipe from the array recipes.remove(i) ; This is used to break from the while loop if we found the recipe i = -2 Debug.Notification("Recipe Done") EndIf i = i + 1 EndWhile EndEvent
  20. Why not just store references to the three main worldspaces Commonwealth, Nukaworld and Farharbor and then when the player's location changes check if the worldspace is not one of the three main worldspaces? If it's not then it must be a child worldspace.
  21. I am kind of confused by his term "child worldspace", I am not sure if he means a child location in general or a child location that is also an exterior because some interiors are considered child locations of the main worldspace. Both his examples are child locations that are exteriors so I assume that's what he meant by worldspace.
  22. If this ctd bug happens when you save even on a fresh game then there's another solution I would like to propose. Instead of disabling 1 mod at a time, disable the first half your mod list then go into the game and test. If the bug is still there then you know that this mod in the first half and if it's not then it's in the lower half. Now, take the half that has the bugged mod and divide it into two halves and rinse and repeat. This will allow you to pinpoint the mod in a couple of tests depending on your mod list size. If you have 300 mods for example, the next list would be 150 mods and so on. Saves a ton of time. This is a searching strategy in computer science called binary search in case you're interested in reading about it. About the reading scripts part, you could go into your Fallout4/Data/Scripts/Source/User folder, open .psc files using any text editor and read the source code for scripts but some modders don't release the source code for their scripts meaning you might not find the offending mod using this method.
  23. AddInventoryEventFilter(None) allows all items. This was mentioned in the documentation here.
  24. A very simple solution would be to update the value of HC_IncomingDamageMult actor value for the player actor when the player reaches certain levels. Unfortunately, editing the base form of a certain actor or race would lead to incompatibilities with a lot of mods. Edit: Unless you want different races to get different damage boost perks.
×
×
  • Create New...