The new += array config command needs a non-inherited entry in that class, otherwise it simply overwrites.
Additinally using += on a parent and a child class in one config leeds to unexpected results. {F25058}
The new += array config command needs a non-inherited entry in that class, otherwise it simply overwrites.
Additinally using += on a parent and a child class in one config leeds to unexpected results. {F25058}
Issue 1:
Set up two configs and binarize them. Then start the game and watch the resulting configs in the config viewer.
Config 1:
class A {
array1[] = {"1"};
};
class B: A {
array2[] = {"1"};
};
Config 2:
class A;
class B: A {
array1[] += {"2"}; array2[] += {"2"};
};
Expected result in the game:
class B: A {
array1[] = {"1", "2"}; array2[] = {"1", "2"};
};
Actual result in the game:
class B: A {
array1[] = {"2"}; array2[] = {"1", "2"};
};
As you can see, instead of adding "2" to array1 it got overwritten, because it wasn't defined in B, but inherited from A.
array2 was defined directly in B, so "2" got added to the array correctly.
Issue 2:
Same steps, but the following setup:
Config 1:
class A {
array1[] = {"1"};
};
class B: A {
array1[] = {"1", "2"};
};
Config 2:
class A {
array1[] += {"3"};
};
class B: A {
array1[] += {"3"};
};
Expected result:
class A {
array1[] = {"1", "3"};
};
class B: A {
array1[] = {"1", "2", "3"};
};
Actual result:
class A {
array1[] = {"1", "3"};
};
class B: A {
array1[] = {"3", "3"};
};
The description is correct - this feature was never meant to work with inherited classes. The goal was to create a simple tool to work add into array with unknown previous values (e.g. Throw muzzle with various grenades) and it works just like that.
There is currently no plan to change the feature, it may be possibly done in the future, but I cannot promise anything.
When you say "not meant to work with inherited classes" does that also include inheritance inside a single config file?
I.e. what will the following produce (single config file only):
config1:
class A {
property[] = [a,b];
};
class B: A {
property[] += [c];
};
It doesn't. There is no difference whether you put stuff inside one config.cpp or into multiple aside from loading order.
Also for the record, += doesn't even work with "arrays with unkown previous values". In practice it ONLY works with Throw, because there is no reason to inherit from that class as every soldier uses it.
You can't for example add a custom silencer to the MX (compatibleItems[]), because the MXSW inherits from that.
Thanks for the explanation. Could you give an example usage (with Throw)?
I'm still trying to get my head around this operator (out of mere interest as it seems a fairly niche thing).
Slightly off-topic: Is there already a feature-request to turn += into a more general tool that *could* handle things like adding a custom silencer to the MX's compatibleItems[]?
As exemple with throw:
class CfgWeapons
{
class GrenadeLauncher; class Throw : GrenadeLauncher { muzzles[] += {"MGI_LacrymoMuzzle"}; class ThrowMuzzle: GrenadeLauncher {}; class HandGrenadeMuzzle: ThrowMuzzle { magazines[] = {"HandGrenade"}; }; class MGI_LacrymoMuzzle : ThrowMuzzle { magazines[] = {"MGI_Lacrymo_mag"}; };... then you need to repeat all grenade classes with their magazines (like handGrenadeMuzzle above)!
btw, i never found the way to add a magazine for the GL_3GL_F launcher. It works for UGL_F (EGLM) but no way for the GL_3GL_F (commonly used in plenty of addons). Seems to need rewriting all guns just for that!
+= certainly is "interesting", but not really useable outside of a few exceptions at this point.
You could say that this report is a feature request for that.
Thats exactly the issue I described. The grenade launcher class is inherited and therefore += doesn't work as expected.
BI, please consider to add this feature.
It's very important for island makers.
This command is the only way to make all islands compatible with each other.
Island maker must override (instead of appending) global vehicle classes to add his own dust effects for his terrain.
So end users can't properly use several islands simultaneously because every island override dust effects of all other islands.
More info can be found here: https://forums.bistudio.com/topic/176156-how-to-customize-terrain-dust-sound-and-ocean/?p=2918406
If you integrate it they way it's described in the original post this is going to add a very powerful tool for addon cross compatibility.
Please consider this.
Issue 2:
This happens because there are two resolve steps for appends.
One happens during config load, the other during config merge.
At game start, all addon configs are loaded as standalone configs. Then sorted by loadOrder, then merged into one master config according to order.
When the config is loaded, it doesn't know that any other "class A" exists. So it thinks it can just resolve the array append to B right then and there. So it turns it into array[] = {3,3} which, if it stays a standalone config (like description.ext) it would be perfectly correct.
But then later, the merge comes along. It now sees class B with array[] = {3,3} okey that's not a append, so it will overwrite the previous value that was there.
Easy solution, just don't resolve during load, and let it stay around till the merge. That would solve it.
But, then we end up with configs that don't get merged (description.ext) with unresolved array appends and that end would break.
And when a config is loaded, it doesn't know if it might get merged later, or not.
So due to technical debt and how the config loading was designed, we cannot solve this.
Alternate solution, don't resolve append on load if the previous definition was also append.
This would be a behaviour change
`class A { arr[] += {1,2,3}; }; class B : A { arr[] += {4}; // arr = [1,2,3,4] };
In addon config, this would be wrong. But in description.ext, this is correct result (though still kinda syntax error to append to a value that doesn't exist, but the game currently just turns that into a =)
So fixing it this way, would break incorrect code that currently works.
Issue 1:
This is a messup in the config merge code.
When we merge two configs together, we check if value exists in class (ignoring parents/inherited values), if yes we overwrite, if not we create a new one.
That works fine for most values, but not with array append. This behaviour causes it to think "Value doesn't exist, so we create new one" which is correct, but also "previous value wasn't found, so theres nothing I can append to" which is of course wrong.
I think that should be safe to fix
Issue 1 is fixed in 2.13/2.14 150692
Also next profiling branch build, probably early next week
For now I still expect that Issue 2 will stay broken