Here's my proposal for how exactly this could be done:
We add a
modifiers property to the
quality prototype of the type
dictionary[string -> dictionary[string -> Struct]] where the
Struct has a
type property of the type
"additive"|"multiplicative" and a
value property of the type
double.
The
string keys of the outer dictionary would be the types of entity prototypes and the
string keys of the inner dictionaries would be the names of properties of the entity prototype the inner dictionary that are any kind of number. For instance, the key of
"name" wouldn't be allowed but the key of
"crafting_speed" would if the key for the inner dictionary in the outer dictionary is
"character",
"assembling-machine",
"rocket-silo" or
"furnace", since prototypes with those as their type can have the
"crafting_speed" property. (although
"character" might be excluded because it doesn't currently seem to support quality)
If the
type property of the
Struct is
"additive", then entities with a type of the outer key will have the
value property added to the property with the name of the inner key when they have the quality that the
modifiers property is of.
If the
type is
"multiplicative" then it's the same thing, but the
value is multiplied to the property rather than being added to it.
Here's a basic example:
Code: Select all
local rare_quality = {
name = "rare",
type = "quality",
[...]
modifiers = {
["assembling-machine"] = {
["crafting-speed"] = {type = "multiplicative", value = 1.2}
}
},
[...]
}
data:extend{rare_quality}
The
[...] is referring to other properties that aren't directly related to the example.
Anyway, this example creates a quality called
rare which multiplies the crafting speed of assembling machines (and only assembling machine prototypes) by 1.2. (unless overridden by the specific assembling machine) Yeah, it's that simple...
Many of the existing properties for controlling parameters have defaults based on the value of
level, but those can easily be added into the table where the values aren't already set.
If you try to modify a property that can only be of integer value, then the property should get rounded. (down?) If the modified property goes outside the normal bounds of the property, then it should get clamped into range - for instance, if you had an underground belt with a
max_distance of 255, then it wouldn't receive any increases from qualities, since the
max_distance property doesn't go any higher than 255, being a
uint8. It could, still, however, be reduced by qualities though.
I'm quite sure that this is entirely possible. Really, the only thing that would need restricting is making sure that different qualities of the same entity don't have different sizes or grids, so that they can still replace each other.