Constant expressions for global constants and for Definition properties are
now treated the same way. The preparser creates the structure that
the parser will fill in. Since the structure will not move, the parser can
refer to it before it is filled in, just like functions can call siblings
defined further down in the script. This will also allow proplists (and later
functions) to refer to each other.
For example, the proplist in Clonk.ActMap.Walk is saved as DClonk.ActMap.Walk.
Should the script defining the proplist change while the savegame is stored,
the proplist will have the new contents instead of the old ones after savegame
load.
Also, save functions as DFlint.Hit instead of fDFlint.Hit. Loading uses the same
code as static proplist loading.
Curiously, this makes g++ 4.4 use the C4RefCntPointer move constructor,
which was broken until now. Fix it to take a mutable rvalue reference.
This is done with the new C4ValueNumbers class. Every array and proplist
with the exception of objects, definitions and effects gets a number
when the game is saved and is restored via that number on load.
There's no need to go through the entire object list to get an object
number, so convert most usages of ObjectNumber(obj) with obj->Number. Add a
new method to check proplist pointers for debugging purposes to
C4PropListNumbered.
With references gone, the engine can sanely run code upon modification of
properties, or throw exceptions on read-only ones. This obsoletes one use
case of GetEffect, simplifying the function a lot.
This time with more manual checking and using git blame -M -C, so that
a few cases of copied code get a copyright notice corresponding to
their initial introduction.
There might be a usecase for finding out from script whether a property is
on an object instead of a prototype of the object, but so far that feature
has not been missed.
This way, a mere reference does not need to add an entry to a proplist. This
can be deferred to the point when the reference is used to change the value.
Because PropLists have an identity, they need to be saved in a central
place and have C4Values reference them, the same as objects. Objects.txt
can be used for that.
This doesn't save PropLists which are definitions. These are reloaded from
the c4ds at game start and identified by their C4ID, not their number.
This patch produces a measurable slowdown on my computer, but it's not
directly related to the change but probably rather to hashtable collisions
in C4StringTable.h. The performance drop vanishes when increasing the
initial size of the hashtable.
I am not changing that right now because a) it's rather unrelated to
this change and b) would require some more profiling to find a good value.
Maybe changing the hash function or increasing the hash table size before
it's half full would be better things to do.