Search the Community
Showing results for tags 'array'.
-
Here's how to create a Papyrus Array of arbitrary size and type, using just vanilla capabilities: ; declare desired array type (example: a struct called MyDesiredType) and it's size (example: 500 elements) MyDesiredType[] myArray Int size = 500 ; for each element in the desired array... ObjectReference newRef Int i = 0 While (i < size) ; ...place dummy object at xmarker in helper cell ; (force persistence as, ideally, the helper cell is not in loaded area) newRef = markerInHelperCell.PlaceAtMe(dummyForm, 1, true, true, false) ; ...reflink the placed dummy to the marker with whatever keyword newRef.SetLinkedRef(markerInHelperCell, kwdWorkshopItem) i += 1 EndWhile newRef = none ; ask the engine to hand us an objectreference array with the 500 dummies we linked to the marker ObjectReference[] linkedRefs = markerInHelperCell.GetRefsLinkedToMe(kwdWorkshopItem) ; ask the engine to create a copy of the array and to recast the copy into the desired type myArray = (linkedRefs as Var[]) as MyDesiredType[] ; clean up all the dummy refs i = linkedRefs.Lenght - 1 While (i > -1) linkedRefs[i].Delete() i -= 1 EndWhile ; done: myArray has 500 elements. Papyrus VM may prohibit you from creating large Arrays - but you can coerce the engine to create one via GetLinkedRefs() and then leverage Var[] casting magic to change the type. It wont be fast due to the PlaceAtMe() call, but it works. NOTE: If MyDesiredType is incompatible with ObjectReference, every element in myArray will be initialized to <none>. If the types are compatible, then the elements will contain the dummy references. You definitely don't want that, so add an intermediary cast through an incompatible type in this case: ; using Location as the incompatible type here myObjectReferenceArray = (((linkedRefs as Var[]) as Location[]) as Var[]) as ObjectReference[] Enjoy.
-
Say you have a input Array that you've obtained through some native code means and which has or might have more than 128 entries: ObjectReference[] linkedRefs = refSettlementWorkshop.GetRefsLinkedToMe() Say you also have an output Array of some data type other than ObjectReference: ; the struct type Struct ObjectDescriptor ObjectReference TheRef Int Status EndStruct ; array of struct ObjectDescriptor[] objectsToProcess I use a Struct here because I can. You could however use any type here, other than ObjectReference. Now assume that, for every element in the input Array, you want to put a new instance of the ObjectDescrptor Struct into the output Array. The traditional approach would be to write a loop that reads each element of the input Array, creates a new Struct and fills it, and finally adds the new Struct to the output Array: Int i = 0 ObjectReference[] linkedRefs = refSettlementWorkshop.GetRefsLinkedToMe() ObjectDescriptor[] objectsToProcess = new ObjectDescriptor[0] While (i < linkedRefs.Length) ObjectDescriptor newDescriptor = new ObjectDescriptor newDescriptor.TheRef = linkedRefs[i] newDescriptor.Status = 1 objectsToProcess.Add(newDescriptor) i += 1 EndWhile BUT: The Array.Add() will fail after 128 elements, because Papyrus VM doesn't allow it! And the same is, unfortunately, true if we try to create the Array at a size >128 directly - Papyrus VM won't allow it. =( =( =( Now what??? You could rely on the Large Array Patch in LLFourplay.dll of course. Or, you could use MergeArrays() in SUP F4SE. But what if you want or need to work without any F4SE magic at all? How can you do this then? Is there a simple solution? Yes. Here's what you do instead: Int i = 0 ObjectReference[] linkedRefs = refSettlementWorkshop.GetRefsLinkedToMe() ObjectDescriptor[] objectsToProcess = (linkedRefs as Var[]) as ObjectDescriptor[] While (i < linkedRefs.Length) ObjectDescriptor newDescriptor = new ObjectDescriptor newDescriptor.TheRef = linkedRefs[i] newDescriptor.Status = 1 objectsToProcess[i] = newDescriptor i += 1 EndWhile The intermediate cast of ObjectReference[] through Var[] into ObjectDescriptor[] will result in a new Array of type ObjectDescriptor being created, with the same number of entries as the ObjectReference Array has. However, because the data types (ObjectReference vs ObjectDescriptor) are not compatible, all the entries in the resulting Array will be... none. Which coincidentally just so happens to be the exact sort of thing you need here, of course: A properly sized Array, with empty entries you can fill. Safe and effective. Enjoy! NB: If your output Array is of the same datatype as the input Array, search for my SOLUTION for creating copies of Arrays here in the forum.
-
Hey guys, any idea why my array length is still 0 after using array Add() function? Actor Property spawned_actor Auto Actor[] Property enemy_actor_pool Auto spawned_actor = spawn_points[random_spawn].PlaceActorAtMe(LvlFeralGhoul,1) enemy_actor_pool.Add(spawned_actor) Function ResetActorPool() Debug.MessageBox("Array len: " + enemy_actor_pool.length) ;Displays zero Int iElement = enemy_actor_pool.Length While iElement Debug.MessageBox("iElement found") ;Doesn't display. So nothing looping iElement -= 1 enemy_actor_pool[iElement].SetCriticalStage(enemy_actor_pool[iElement].CritStage_DisintegrateEnd) enemy_actor_pool.Remove(iElement) EndWhile EndFunction
-
So I'm trying to make a mod that stores the player's spells in a spellbook. In theory, it would add all the spells to the player when the player equips it, and I've got a script set up that adds the spells the player learns to an array. Is there a way to have a script run through the array and add all the spells in it to the player? Please and thank you :D
-
Hi folks. I'm doing some study into using arrays with Papyrus, currently I'm looking at how I can use a dynamic array to do what I want. I've got a bout 6 or so wiki pages up that I've been reading through, as well as various example code I've looked at in War of the Commonwealth. I was hoping to get some advice on what I've learnt so far. First I'll say what I want to do with this and then I'll post the example code I just made. What we want to do is, dynamically create a list of Actors that spawn at a spawn point (that I've made) so I can do things with them later, such as disable them/delete them when they have been unloaded for some time. And I also want to destroy the array in that particular case so it's not making my spawnpoint persistent forever. You might say I can do that with PlaceAtMe function, but I need to use PlaceActorAtMe function, so I need to do this instead. Here is example/test code I wrote, with commentary: Event OnCellAttach ;Do what I need to do to get to Function Spawn(), if we do Spawn() EndEvent Function Spawn() if (WhoToSpawn == 1) && (1S_Allowed_Raiders_R1.GetValueInt() == 1) ;1 = Raiders, and are we allowed to spawn Raiders according to user settings SpawnCounter = 1S_Max_Allowed_Raiders_R1.GetValueInt() ;Maximum allowed units to spawn while (SpawnCounter > 0) if (Utility.RandomInt(1,100) >= 1S_Chance_Raiders_R1.GetValueInt()) ;Chance of a unit actually spawning (makes the spawn amounts a bit more dynamic) Actor[] SpawnList = new Actor[0] ;The list of Actors that will be controlled, maybe I should make this straight after the function call instead of in this block Spawn = Self.PlaceActorAtMe(LvlRaider, Utility.RandomInt(1,Difficulty), R1_EZ) ;Place the spawn Spawn.SetLinkedRef(PatrolMarker) ;Set the NPC to use the Patrol marker network I've created, there is a starting marker next to each point (we use GetClosest function rather than property) SpawnList[GroupMembers].Add(Spawn as Actor) ;Add the spawnpoint to the array, GroupMarkers is a declared Int starting at 0. Not sure if this is correct method but for example only GroupMembers = GroupMembers + 1 ;Increment the index number + 1 SpawnCounter = SpawnCounter - 1 ;Lower spawn count remaining Spawn = None ;Ready for next actor SpawnSuccess = True ;This value is used for another function else SpawnCounter = SpawnCounter - 1 ;Lower spawn count on unsuccessful dice roll for dynamic group size endif endwhile endif EndFunction Event OnCellDetach SpawnPointLoaded = false Utility.Wait(10) if (SpawnPointLoaded = true) && (Player.IsInCombat == true) ;I'll figure out how to loop this efficiently eventually elseif (SpawnPointLoaded == false) && Player.IsInCombat == false) ;We can disable/delete or do stuff to the Actors in array if true) while GroupMemebers > -1 ;Not sure if this is what you do here SpawnList[GroupMembers].Remove() ;Remove the highest index actor from the list GroupMembers = GroupMembers - 1 ;And count down until the list is empty endwhile ; Whats the best way to destroy the array here so it's not saved endif EndEvent
-
So I added a script to a trigger box because I'm trying to detect when two things are within this trigger box but for some reason when I add something to an array it just stays blank Scriptname MQNS_MRPH_ROBOTRETURNSCRIPT extends ObjectReference ObjectReference Property Actor1 Auto ObjectReference Property Actor2 Auto Quest Property SelectedQuest Auto ObjectReference[] Property ObjectsInMe Auto //Ignore this Int Property timerID Auto Const Event OnInit() if SelectedQuest.GetStage() == 10 StartTimer(2, timerID) endif EndEvent //stop ignoring Event OnTriggerEnter(ObjectReference akActionRef) ObjectsInMe.Add(akActionRef) Debug.Notification(ObjectsInMe) EndEvent Event OnTriggerLeave(ObjectReference akActionRef) int i = 0 int arrLeng = ObjectsInMe.Length While i < arrLeng if ObjectsInMe[i] == akActionRef ObjectsInMe.Remove(i) Debug.Notification(ObjectsInMe[i]) i += 1 endif endWhile EndEvent The notification debug that pops up says [] otherwise an empty array. What am I doing wrong? Would I declare the array somewhere else? Thanks
-
Hello all, I was hoping to get steered in the right direction so that I can be on my way to develop a mod that I've been wanting to create for a while now. To get to the point, I would like to summon a certain number of objects (10 for example) at the target location of a spell. These items can be base items for all I care, I am just looking for framework here. Now, I was able to get one item to summon (A door in this case, but it can obviouslly be changed to anything) using this method http://forums.nexusmods.com/index.php?/topic/3105920-script-help-summoning-a-door/ My issue is trying to adopt this to summon multiple items, preferable in a circle around the target (I can work on that later though), for now I just want to know what I'm doing wrong. Incorperating a array in the matter is what's most troubling to me at the moment. I'm not sure if this method is the right direction or not but its something I tried to combined from another script Scriptname _TeleportDoorMarkerScript extends ObjectReference Door Property TeleportDoor Auto Activator Property EffectSummonBanishFX Auto ObjectReference[] Doors Event OnInit(Actor Target) Doors = new ObjectReference[10] int i = 0 While i < 10 Self.SetAngle(0.0,0.0, Game.GetPlayer().GetAngleZ() + 90 + i) Self.PlaceAtMe(EffectSummonBanishFX) Doors[i]=Self.PlaceAtMe(TeleportDoor) Doors[i].Enable() i+= 1 EndWhile EndEvent I also tried something like below to no avail. Scriptname _TeleportDoorMarkerScript extends ObjectReference Door[] Property TeleportDoor Auto Activator Property EffectSummonBanishFX Auto Event OnInit(Actor Target) int i = 0 While i < 10 Self.SetAngle(0.0,0.0, Game.GetPlayer().GetAngleZ() + 90 + i) Self.PlaceAtMe(EffectSummonBanishFX) Self.PlaceAtMe(TeleportDoor[i]) i+= 1 EndWhile EndEvent Again, super rough code but I'm just trying to get the point across. (I honestly don't think a .Enable should even be necessary). I think the Self. portion is what's throwing me off the most. So again, main idea is to shoot a spell at a target (could be the ground or a person) and it will summon 10 items of whatever. Even if you can point me to a thread remotely close to what I'm looking for would be helpfull because I sure can't find one other than maybe this one. http://forums.nexusmods.com/index.php?/topic/694996-i-need-help-making-a-script-for-a-multiple-summons-spell/ I'm not entirely sure how to adopt that to what I'm looking for as I don't know if NPC vs objects differ at all. Anyways, if you could help I would appreciate it, if not, no worries. I'll be happy to clear anything up that I can.
-
Assuming an array I've already cast "Workshops" as a WorkshopScript, that does seem to populate with a list of workshops, I'm trying to run a check on each one as follows: int shopid = 0 while (shopid < Workshops.length) debug.traceandbox("Checking " + Workshops[shopid]) if somecondition somefunction(Workshops[shopid]) endif shopid += 1 Utility.Wait(0.5) endWhileBut it's not working, and the debug message shows "Checking [workshopscript" and the rest of the script doesn't get the ID of the workshop. It seems to follow the format of the examples in the wiki. What am I doing wrong? Edit: actually I think I may be looking at a race condition and the weird debug message is a red herring, as far as functionality. Meanwhile if anyone knows why I'm getting [workshopscript instead of the actual ref ID like I was expecting, I'd love to hear it. Edited edit: while I'd still like to know how to properly get the refID of a settlement into a debug message, you know what really helps in building an array? DECLARING THE ^&@?!!iING ARRAY oh well. For anyone having workshop troubles, or the morbidly curious: the "somefunction" above was taking a subset of Workshops and cramming it into its own dynamic array. Except, while I had defined the array in the Group section at the top of the script, I at no point actually declared it. Papyrus happily compiled my script despite it containing instructions to shove elements into an array that consisted of a black hole.
-
- workshopscript
- array
-
(and 1 more)
Tagged with:
-
I have a Bool array and i wanted to use it's values as conditions for a message through the use of GetVMQuestVariable, the quest has the conditional keyword and the arrays too but they don't appear on the list when i choose GetVMQuestVariable. I have tested with a non-array on the same quest and it works so i guess arrays cannot be used for that... Quite dissapointing, thought arrays would work just like any other property. Is there any workaround for that? I have to work with arrays, that can't change, but maybe once the array is setup i could set a bunch of variables to each value of the array and use those for the conditionals, sort of "translating" the array. The length of the arrays won't change so i can have a fixed number of variables (2 arrays of 9 elements, so 18 more properties). It would be something like this: Bool Property Element0 Auto Conditional Bool Property Element1 Auto Conditional ... Bool Property Elementn Auto Conditional Bool[] Property MyArray Auto Conditional Function TranslateArray(Bool[] Array) ; haven't used arrays for parameters of functions yet, is that right? Element0 = Array[0] Element1 = Array[1] ... Elementn = Array[n] EndFunctionAny better ideas? Wondering why does it let me compile it if it doesn't work... Thanks in advance.
-
Is it possible to use an array for a required ingredient in a crafting station? For example, my Breakfast of Champions is crafted in the cooking station with Sugar Bombs and beer. The beer MUST be a beer object with formID 0011EA93. It would be more robust if the player could use any of the beer or liquor variants. The old LPC way to do this was to create an array of acceptable items, then check that the player had an item on that list at the time of crafting. I'm just using the breakfast as an example. There are many things that could be improved with arrays. A Nuka Cola grenade that could be crafted with any of the warm/cold/flavored empty bottle variants is another example. So far, the only way I see is to require the scrapped component (glass instead of bottle), but that adds a trip to the workshop and makes it more tedious on the player. I suppose if the modder created an object with a custom crafting script, that would be possible. (Example: a tool belt that deletes ingredients and clones a grenade when activated.) But it would be nice if arrays could be done with things listed in the different stations.
- 4 replies
-
- array
- ingredient
-
(and 6 more)
Tagged with:
-
So in my recent scripting adventures i found myself needing to know if there was a a value between to indexes in my array. There's find and rfind both have a starting index parameter but not a stop index so i made this: Bool Function FindBoolBetween(Bool[] ArrayToSearch, Bool BoolToLookFor, Int LowerLimit, Int UpperLimit) ; both included. Int FirstElement = ArrayToSearch.Find(BoolToLookFor, LowerLimit) If (FirstElement >= 0) && (FirstElement <= UpperLimit) return True Else return False Endif EndFunctionIs the logic right? Also, the native find functions works for any element type, can i make mine do so? or i would need to make another funcion with all bools as ints? While i am at it, little thing about another function (not really, just a part of one), to compare whole arrays against some predefined set of values i'm casting them to string: ;VARS String String1 = "[-1, 1, 2, 0, -1, -1, 3, 4, 5]" String String2 = "[-1, 1, -1, 0, 2, -1, 3, -1, 5]" ; PIECE OF THE FUNCTION If MyArray as string == String1 ; do whatever ElseIf MyArray as string == String2 ; do another thing EndifAnd it seams to work, not sure how long the array can be without the string being truncated with "..." but mines are rather short and all trace tests gave the whole array. But what about comparing two arrays? If MyArray as string == MyArray2 as stringor does this work with arrays (i asummed it doesn't) If MyArray == MyArray2Thanks in advance for any help in the matter and if the function is indeed right, anyone is free to use if they find it useful i guess.
-
I am trying to get a random selection from an array and then remove that item from the list of options. However, when I try to do that, I am told remove is not a function or does not exist. Am I doing this properly? My code is below, at least the parts that are important: Scriptname SirBeastXM02PrepQuestScript extends Quest ;-----Properties ;In charge of all possible locationsLocation[] Property HaafingarLoc Auto Location[] Property ReachLoc Auto Location[] Property WinterholdLoc Auto Location[] Property WhiterunLoc Auto Location[] Property RiftLoc Auto Location[] Property FalkreathLoc Auto Location[] Property EastmarchLoc Auto Location[] Property HoldLocations Auto int ArrayRandFindHoldInt ArrayRandFindInt ArrayRemove Location FirstHoldLocationLocation SecondHoldLocationLocation ThirdHoldLocationLocation FourthHoldLocation Location FirstLocationLocation SecondLocationLocation ThirdLocationLocation FourthLocation ;-----Events Event OnInit()HoldsArrayLength = HoldLocations.length;Debug.trace("There are " + HoldsArrayLength + " locations in Hold Locations Array.")HaafingarArrayLength = HaafingarLoc.length;Debug.trace("There are " + HaafingarArrayLength + " locations in the Haafingar Array.")ReachArrayLength = ReachLoc.length;Debug.trace("There are " + ReachArrayLength + " locations in the Reach Array.")WinterholdArrayLength = WinterholdLoc.length;Debug.trace("There are " + WinterholdArrayLength + " locations in the Winterhold Array.")WhiterunArrayLength = WhiterunLoc.length;Debug.trace("There are " + WhiterunArrayLength + " locations in the Whiterun Array.")RiftArrayLength = RiftLoc.length;Debug.trace("There are " + RiftArrayLength + " locations in the Rift Array.")FalkreathArrayLength = FalkreathLoc.length;Debug.trace("There are " + FalkreathArrayLength + " locations in the Falkreath Array.")EastmarchArrayLength = EastmarchLoc.length;Debug.trace("There are " + EastmarchArrayLength + " locations in the Eastmarch Array.");Debug.messagebox(HoldLocations) ;ArrayRandFindHold = Utility.RandomInt(0, (HoldsArrayLength - 1));FirstLocation = HoldLocations[ArrayRandFindHold]; Debug.trace(FirstLocation + "has been found.") EndEvent Event OnUpdate()if XM02Prep.GetStage() == 10;Assign location aliases ;Alias OneArrayRandFindHold = Utility.RandomInt(0, (HoldsArrayLength - 1))FirstHoldLocation = HoldLocations[ArrayRandFindHold]HoldLocations.Remove(ArrayRandFindHold) ;Alias twoArrayRandFindHold = Utility.RandomInt(0, (HoldsArrayLength - 1))SecondHoldLocation = HoldLocations[ArrayRandFindHold]HoldLocations.Remove(ArrayRandFindHold) endifEndEvent Thank you for all the help.
-
Hello, Thank you for taking time out of your day to read this. I am currently working on a mod called "MCM Cheat Menu", My ultimate aim is to add as many commands and option you could possibly want whether you are a modder, mod creator or cheater. But I have run into a problem and I will start with that stuff now. Thanks again for reading this and possibly helping me out. So I have to features which I am currently working on one is an NPC spawner/placeatme/moveto option and the other one is going to be similar to additemmenu. The problem I am currently facing, however, is that I can't find any good way of getting items to be added to my array automatically, Which is a big problem because it wouldn't add items from other mods, I am facing a similar problem with the NPC one but if I find the solution to one then the other one will be easily fixed as well. Anyway, If I didn't make something clear enough please just ask. PS: I know I could probably download someone else mod that does this and copy their code but it would feel like I am stealing stuff, Which would kill my motivation to make this mod.
-
Good evening everybody! So, I am new to this whole "scripting" thing ... But I think I understand the "basics" like events, functions, properties, ... I was thinking about implementing some stuff with a script and the following questions about arrays came up: How many "entries" can an array have in FO4? Can I "save" an array or can it just be used in the script that "defines" it? Can you import / export the contents of an array from / into a CSV or TXT file? The CK wiki article about "arrays" isn't really helpful, it just talks about using arrays inside of scripts. Could some of the scripting gods here (or anybody else who knows this) please share their knowledge about this? Thanks ...
-
These are some lines in my script: I'm trying to simplify it to make my script more compact and better looking. I'm still new to Papyrus and i heard about arrays recently, so i tried to learn about it but couldn't manage to solve my case here yet. What i'm actually trying to do is making MoralityChance to be more accurate by giving it a base value of 0.01 (or 1%) instead of 0.05 (or 5%) as stated in above lines. I heard about arrays so i thought i might use it, not only to simplify these lines but also making MoralityChance more accurate by giving it 0.01 (1%) base value and incremented until 1.00 (100%) value. So, can we simplify these lines in my script? If so, would anyone give me a guide on how to?
- 2 replies
-
- array
- simplify the script
-
(and 1 more)
Tagged with:
