kuzi127 Posted September 7, 2019 Share Posted September 7, 2019 So I'm testing a proof-of-concept mod and I'm making a custom function in a script that checks how many of a loose mod are in all of the workshops linked to the one the player is using, and stores it in a global in a quest script. I'd like some help with the syntax and how to use an event from a different class. I only started learning papyrus in the last few days, but I am somewhat familiar with other languages and scripting in general. A lot of the function was lifted from the vanilla workshop scripts and modified for what I need. Attached to the weapons benches: Scriptname WorkbenchScriptTEST extends ObjectReferenceWorkshopParentScript Property WorkshopParent Auto Const mandatory{ parent quest - holds most general workshop properties }TEST_ModCountManagerScript Property Auto Const mandatory{ manager quest - holds globals for condition checks };internal function for counting how many of a mod the player has availablefunction CountMods(ObjectReference Bench, Form MiscMod, GlobalVariable CountGlob);set up count variableint modcount = 0;get linked containerObjectReference linkedContainer = Bench.GetLinkedRef(WorkshopParent.WorkshopLinkContainer)if linkedContainermodcount = modcount + linkedContainer.GetIemCount(MiscMod)endif; get all linked containers (children)ObjectReference[] linkedContainers = Bench.GetLinkedRefChildren(WorkshopParent.WorkshopLinkContainer)int i = 0while i < linkedContainers.LengthlinkedContainer = linkedContainersif linkedContainermodcount = modcount + linkedContainer.GetIemCount(MiscMod)endifi += 1endWhile;set global to final countTEST_ModCountManagerScript.CountGlob = modcountendFunctionEvent OnActivate(ObjectReference akActionRef);;debug.trace(self + "OnActivate")if akActionRef == Game.GetPlayer()CountMods(self, TEST_miscmod_mod_General_Scope_SightReflex, TEST_ReflexSightCount)endifendEvent;Event OnPlayerModArmorWeapon(Form akBaseObject, ObjectMod akModBaseObject); ;same stuff as activate event;endEvent Can I set a globalvar property of another script using a function input like that? Do I have to initialize the loose mod as a property? Also, I'd like to run the count whenever the player mods an item, but that event is from the actor class so i don't think it'll work directly like that. What would be a good way to do this? Feel free to point out any other errors too. Link to comment Share on other sites More sharing options...
SKKmods Posted September 7, 2019 Share Posted September 7, 2019 Some suggestions in no particular order; You must define the properties for *everything|* in the script so it knows what database objects it is supposed to be using and link them: Keyword Property WorkshopItemKeyword Auto Const Mandatory Keyword Property WorkshopCaravanKeyword Auto Const Mandatory ObjectMod Property TEST_miscmod_mod_General_Scope_SightReflex Auto Const Mandatory GlobalVariable Property TEST_ReflexSightCount Auto Const Mandatory To do what you want first get the local workshop reference: ObjectReference ThisWorkshop = Self.GetLinkedRef(WorkshopItemKeyword) You don't need the local linked workbenches as containers as they share the local workshop container. Int iCount = ThisWorkshop.GetItemCount(TEST_miscmod_mod_General_Scope_SightReflex) Now get the stupid supply line linked workshops (stupid because Global Workshop storage is an actual thing these days) look for this line in WorkshopParentScript: Location[] linkedLocations = workshopRef.myLocation.GetAllLinkedLocations(WorkshopCaravanKeyword) and copy the While loop logic underneath it to count the OMODS in each of them: Location[] linkedLocations = ThisWorkshop.GetCurrentLocation().GetAllLinkedLocations(WorkshopCaravanKeyword) While ... iCount += ThisWorkshop.GetItemCount(TEST_miscmod_mod_General_Scope_SightReflex) ... Endwhile TEST_ReflexSightCount.SetValue(iCount) Rather than mess about attaching scripts to actual workbenches, create a start game enabled quest and attach a script to that which is event driven; Event OnQuestInit() RegisterForRemoteEvent(Game.GetPlayer(), "OnPlayerUseWorkBench") EndEvent Event Actor.OnPlayerUseWorkBench(Actor akSender, ObjectReference akWorkBench) ;stick your omod counting function in here EndEvent Once you have all that working for one simple static OMOD/GlobalVariable pair, then add the ability to define multiple OMODs and associated Global. Link to comment Share on other sites More sharing options...
kuzi127 Posted September 8, 2019 Author Share Posted September 8, 2019 (edited) Ah ok, I was looking at the workshop scripts and thought the children function was getting all of the linked workshops; didn't know that was handled by the caravan keyword. I already have a start game quest with a script to handle globals so I can just use that, that useworkbench event is useful. I think the main thing that's confusing me is that from reading the papyrus articles on the ck wiki, I think you can only use functions that belong to some script above in the "extends" tree. Is that true? Or can I use functions that belong to global scripts in objectreference scripts, etc. like that setvalue after the while loop? Should I separate the counting function (which would extend objectreference) and the quest script, and then can I use that function in the quest script just by calling it like any other function or do I have to define it as global or something? Thanks for the tips btw, just that stuff was a huge help. Edited September 8, 2019 by kuzi127 Link to comment Share on other sites More sharing options...
SKKmods Posted September 8, 2019 Share Posted September 8, 2019 (1) Start simple and just have a single quest attached script with a bunch of functions and events in it to get going. Starting with scripts spread about attached to different things and calling each other is a long hard way. Start simple unless you actually enjoy pain and frustration. (2) You can use any function *IN* any script (just about). I think what you are referring to is calling a function *ON* the wrong object. Trying to call the Weapon form function .GetAmmo() on an ObjectReference, even if it is a gun wont work. But understanding the entity hierarchy will allow you to cast to the right object/form level: Script mYScript extends Quest (ObjectReference ThisGun).GetAmmo() = fail(ObjectReference ThisGun as Weapon).GetAmmo() = success Edit: I have a lot of super complex scripts that I open up after a year or so to extend or maintain, so being totally explicit about each object and explicitly casting each call really helps rather than trying to be relaxed with short form notation and relying on the script compiler: Quest WorkshopParent.QuestFunction()(WorkshopParent as WorkshopParentScript).WorkshopParentScriptFunction() ObjectReference ThisWorkshop.ObjectReferenceFunction()(ThisWorkshop as WorkshopScript).WorkshopScriptFunction() ObjectReference ThisActor.ObjectReferenceFunction()(ThisActor as Actor).ActorFunction() ;the ObjectReference/Actor mix often gets confusing as the compiler knows an OR is an Actor so will accept an actor function call on an ObjectReference that is an actor. Confused ? Just cast explicitly. Link to comment Share on other sites More sharing options...
kuzi127 Posted September 8, 2019 Author Share Posted September 8, 2019 That makes a lot more sense; the way I had it before seemed like a really weird limitation. I'll mess around with it some more and see if I can get it working. Link to comment Share on other sites More sharing options...
Recommended Posts