Okay I’m not great with this at all. It’s probably something stupid that I’m missing/not seeing or understanding. I have an array of names that is built beforehand. That’s fine, I’ve checked that the items in it all match up. Before I start these loops I clear the map, but I didn’t include a screenshot of that. So here’s the thing. I have this array of names (TempItemsToDeliverArray)
I have an array of active delivery targets (ActiveDeliveryTargets) that was probably obvious but anyway…
I created a map with the key being the object type of those active delivery targets, and the value being a struct, which contains just an array of AssignedItemNames. I’m trying to use two for each loops - the first to assure that each active delivery target is assigned at least one item name into its array in the map, and remove them from the array. The second loop then loops over the remaining items in the temp items array. Each loop I stored the value in a temp item bucket because it kept overwriting the item in the assigned item names in the struct.
I just want to assign random items to each active target from that list, and I feel like there ha sot be a better way to do this but I’ve tried a few things and nothing I’ve done has worked. I feel like I’m just missing something super obvious. Sorry to even bother anyone with this, but if anyone can help that would be awesome. I hope any of this is visible. Sorry for the huge mess.
Also, it almost works as it is, and will sometimes work perfectly, which makes it so confusing. Like say if there’s 3 of one item, and 3 of another in that array, then everything will be fine, 6 loops, 6 items assigned between the 2 map keys. But then sometimes it will assign just 5 items, or sometimes even 7, so I have no idea how to make sense of that. I’m probably doing this all in the worst possible way.
It’s hard for me to say without seeing all your actors and structs, i.e. without having the project in front of me, but this is pretty typical of debugging a system like this.
Is this wrapped in a function? Is it called or pure? Is there a return node? Those can have an effect. I’ve seen data loss related to pure/return that wasn’t due to the logic itself.
it looks like you’re updating the map correctly (which i BP means you basically have to copy the whole struct and overwrite the map key since you cant work with refs )
i cant read it too clearly but the likely issues are
altering arrays mid loop thereby changing the loop
pure nodes returning different values after changing the array
Yeah it ended up being quite a mess. I’m still not sure exactly where it went wrong but I’m sure you’re right on either of those or both really. Sorry for the low res screenshot I should have just combined closer screenshots in Photoshop or something. I actually woke up today and thought of a much better way to go about it. I ended up just adding a name array variable on the targets themselves, in their base BP, so it carries across all of them in my level. I add to that ItemsAssignedToHouse array, assuring each one gets at least 1 first, then assign randomly in the second loop until the tempitemstodeliverarray is empty.
Either way, I’m sure the way I was trying to do it before could be useful for some situations but this works perfectly fine for what I’m trying to do here, so hopefully I don’t run into another issue that I’m not thinking ahead about.
I make sure to clear that array before populating again since each day in game makes an entirely new list and has to do this all again.
This is all inside of one large function that runs after the player has completed something. It’s called when they complete that objective. Either way, I responded below, but I’ll copy and paste what I ended up doing.
I actually woke up today and thought of a much better way to go about it. I ended up just adding a name array variable on the targets themselves, in their base BP, so it carries across all of them in my level. I add to that ItemsAssignedToHouse array, assuring each one gets at least 1 first, then assign randomly in the second loop until the tempitemstodeliverarray is empty.
Either way, I’m sure the way I was trying to do it before could be useful for some situations but this works perfectly fine for what I’m trying to do here, so hopefully I don’t run into another issue that I’m not thinking ahead about.
I make sure to clear that array before populating again since each day in game makes an entirely new list and has to do this all again.
Array has a Shuffle() that is exposed to blueprints, so if you just want random ordering on an array, and the array isn’t changing size:
get to the array
call shuffle() on the array
use that shuffled array for your “random order”
shuffle is in place, memory non-destructive, and runs in C++ for efficiency. wins all around.
let the engine do the bookkeeping on the randomization of the elements. Removing elements from the array or map, you might end up needing to rebuild the arrays, but that operation is still easier.
after that the only thing I would have an issue with is
a Map, struct, array, and String/Name are all stack allocated, and contiguous. Then a Class Reference is an indirection string.
immagine a book store where you don’t know how big the book shelf box, the the shelf, or the books, or the page are going to be, and every time something is just a little bigger then was expected the whole thing is reconstructed from scratch, because for consistency the books all have to be the same size regardless of how much they actually have.
please don’t use objects and particularly classes soft or hard as keys to a map. for hard references/pointers it is address based, but for soft references it is string compares on a long string.
Yeah that’s how I’d like it to be. Basically like this:
Say I have 10 items total. Targets will always be less than number of items, so let’s say 2.
It goes through once to make sure that each one gets at least 1, and then cycles between the targets and just decides who gets the next one. So one could end up with 1, and the other with 9, or 3 and 7, etc.