Added syntax for decorate: const(expression) returns the result of any constant float/integer expression. Here's an example where the goal is to have proportionate amounts of health:
Note on constants: I had to update the constant definitions for decorate, as they were not up to date with the most recent flags in zdoom. If this patch is applied, I suppose that the zdoom list of flags will no longer be updated, since it would exist merely for compatibility purposes.
Why wrap the expression in CONST()?
I could not just call the expression parser without knowing that there would be a terminator for that expression. The normal decorate assignments do not have a line terminator; they just get the first number and check for a comma. If I called the parser on something unterminated, it would try to read the next property/token as part of the expression. So it was either to put something ahead (const) that announced the alternate syntax, or a more complex check for an optional line-terminator that would support expression evaluation. I went with the easier one.
Why not just enclose it in parenthesis?
Because that has a meaning for some properties. 1) I didn't want the semantic mixup. 2) You can use const(expression) to set an amount of damage, so it really needs to be distinct from the (formula)-syntax. It is also not necessarily a bad thing that the text says const() explicitly.
The main purpose of this feature is to make the addition and expansion of Flaggish features easier (Activation, Morph-stuff, VisibleFilter). A secondary purpose is to let modders define and use constants for any centrally defined values they need.
I did struggle a bit with the scanner (I first tried a sc.GetToken()/sc.MustGetAnyToken() that would return directly if a numeric token was identified, process const if TK_Const if that was encountered, and reevaluate otherwise. Reevaluation consisted of sc.UnGet() and sc.MustGetNumber()/sc.MustGetFloat(). But if the string on entry was "-1", the token would be '-', and ungetting would make "-" the string, instead of restoring scanner status with the "-1" string. So I gave that up.). Also, my error messages may not be the brightest and best. Those, and other issues, I will handle if it is required to get the patch in.
EDIT: An updated patch applies exactly the same logic to state frame durations and offset specifications.