[SOLVED]
My game uses a lot of clones for the shop purposes. Everytime the player buys an item, it clones into their inventory. When it's consumed it is RemoveObjected
This animal can be bought in shops multiple times or can be found in forest multiple times.
There is an rng for spawning it in forest (related to player.hunterperk. So the more expert the player is the more chance it will spawn). When the player moves to the next area, I want to destroy/Remove the animals.
Does having a lot of clones with null parent effect the game? Is it necessary to use destroy function instead?
The destroy function is very inconvenient. When I try to remove an object using the ScopeInventory function it gives this error:
foreach (x, ScopeInventory ()) {
destroy (x)
}
"Error running script: Error compiling expression 'x': RootExpressionElement: Cannot convert type 'Element' to expression result of 'String'"
This is my main issue with destroy function: It doesn't accept elements or scripts or functions. It has be string and specifically be the object.name I want to remove.
My second issue is that Quest won't let me set name attribute midgame:
foreach (x, ScopeInventory ()) {
obj = CloneObject ("blagget main")
obj.name = "blagget"
}
"Error running script: Cannot change name of element when not in Edit mode"
destroy won't take alias either.
Should I start giving specific names to the clones and how will I know which clone is the one I want to destroy? How can I destroy something if I don't know what its name going to be?
if (blagget.spawnnum > 0) {
foreach (x, ScopeReachableNotHeld ()) {
y = GetAttribute (x, "alias")
if (y = "blagget") {
destroy (x)
blagget.spawnnum = blagget.spawnnum - 1
}
}
}
another way I tried to do it. Error being not accepting element
EDIT: I found a solution. destroy doesn't accept elements but it does accept string so you just have to use ToString
foreach (x, ScopeInventory ()) {
x = ToString (x)
y = Replace(x, "Object: ", "")
destroy (y)
}
I should've paid more attention to the error message. I feel stupid
You start out by saying
This is my main issue with destroy function: It doesn't accept elements or scripts or functions. It has be string and specifically be the object.name I want to remove.
That pretty much tells you how to get the name of an object - you use its name
attribute.
In your final code, rather than messing about with ToString
you could just do y = x.name
. But I'm pretty sure that won't work - because as soon as you destroy the object, x
becomes an invalid variable, causing the foreach
to break.
The normal way to handle cases like this is to use a while
loop. So if you wanted to destroy all the objects in a list, you would first go through making a list of their names.
Also, if you're trying to delete clones of a specific item, you should use the prototype
attribute, which points to the original it was cloned from.
Your blagget-destroying example would then be:
blaggetnames = NewStringList()
if (blagget.spawnnum > 0) {
foreach (x, ScopeReachableNotHeld ()) {
if (x.prototype = blagget) {
list add (blaggetnames, x.name)
blagget.spawnnum = blagget.spawnnum - 1
}
}
}
foreach (n, blaggetnames) {
destroy (n)
}
Or slightly simpler:
blaggetnames = NewStringList()
if (blagget.spawnnum > 0) {
foreach (x, FilterByAttribute (ScopeReachableNotHeld (), "prototype", blagget)) {
list add (blaggetnames, x.name)
blagget.spawnnum = blagget.spawnnum - 1
}
}
foreach (n, blaggetnames) {
destroy (n)
}
Or to avoid making a second list, you can just avoid using foreach
, like this:
blaggets = FilterByAttribute (ScopeReachableNotHeld (), "prototype", blagget)
while (ListCount (blaggets) > 0) {
x = PickOneObject (blaggets)
list remove (blaggets, x)
destroy (x.name)
}
Thanks for the reply.
the y = x.name worked, even for multiple objects.
And the rest of your codes worked like a charm; thanks for everything!
Clones are a very tricky subject but slowly I'm getting the hang of it.