This could cause problems with functions that take states as parameters but use them to set them internally instead of passing them through the A_Jump interface back to the caller, like A_Chase or A_LookEx.
This required some quite significant refactoring because the entire state resolution logic had been baked into the compiler which turned out to be a major maintenance problem.
Fixed this by adding a new builtin type 'statelabel'. This is an opaque identifier representing a state, with the actual data either directly encoded into the number for single label state or an index into a state information table.
The state resolution is now the task of the called function as it should always have remained. Note, that this required giving back the 'action' qualifier to most state jumping functions.
- refactored most A_Jump checkers to a two stage setup with a pure checker that returns a boolean and a scripted A_Jump wrapper, for some simpler checks the checker function was entirely omitted and calculated inline in the A_Jump function. It is strongly recommended to use the boolean checkers unless using an inline function invocation in a state as they lead to vastly clearer code and offer more flexibility.
- let Min() and Max() use the OP_MIN and OP_MAX opcodes. Although these were present, these function were implemented using some grossly inefficient branching tests.
- the DECORATE 'state' cast kludge will now actually call ResolveState because a state label is not a state and needs conversion.
- removed AMinotaurFriend::IsOkayToAttack. The condition it checks (i.e. friendliness with player) is already covered by the base version of this function so this is quite redundant.
- removed a few 'virtual' qualifiers from functions that never get overridden.
- made some tests about calling script code from native functions.
* scriptified A_SkullAttack to have something to test
* changed the A_SkullAttack call in A_PainShootSkull.
* use a macro to declare the function pointer. Using local static variable init directly results in hideous code for the need of being thread-safe (which, even if the engine was made multithreaded is not needed here.)
* Importsnt node here: Apparently passing an actor pointer to the VMValue constructor results in the void * version being called, not the DObject * version.
This bypasses a declaration in the script in favor of a simpler implementation. In order to work it is always necessary to have an offset table to map the variables to, but doing it fully on the native side only requires adding the type to the declaration.
- added support for global variables to the code generator - not the compiler, though. For the handful of entries this is needed for it may just as well be done manually. So far FLevelLocals level is the only one being exported.
- fixed: The VM disassembler truncated 64 bit pointers to 15 digits because the output buffer was too small.
- resolve entire FxSequences instead of aborting on the first failed entry. This allows to output all errors at once.
- exported thinker iterator and drop item chain to scripting. Unlike its native counterpart the script-side iterator is wrapped into a DObject to allow proper handling for memory management.
- fixed: The VMFunctionBuilder only distinguished between member and action functions but failed on static ones.
- fixed: FxAssign did not add all needed type casts. Except for purely numeric types it will now wrap the expression in an FxTypeCast. Numeric handling remains unchanged for both performance reasons and not altering semantics for DECORATE.
- exported all internal flags as variables to scripting. They still cannot be used in an actor definition.
- make ATAG_STATE the same as ATAG_GENERIC. Since state pointers exist as actual variables they can take both values which on occasion can trigger some asserts.
- gave PClass a bExported flag, so that scripts cannot see purely internal classes. Especially the types like PInt can cause problems.
Todo: we need readonly references to safely expose the actor defaults. Right now some badly behaving code could overwrite them.
- fixed: FxMinusSign trashed local variables that were used with negation.
- fixed: FxConditional only handled ints and floats, but not pointers and strings.
- fixed: A 'no states in non-actors' error was triggered, even for classes without any states.
- swapped parameters of two-parameter VelToAngle method, so that internal and script version are in line.
- fixed parameter asserts to handle NULL pointers properly.
- fixed: Script functions did not receive the function name when being created.
- relaxed the asserts for PARAM_STATE, because the VM knows nothing about ATAG_STATE. Any state variable's content (e.g. Actor.SeeState) will receive ATAG_GENERIC, rather than ATAG_STATE.
- added a 'NeedResult' flag so that certain operations can create shorter code if the result of the expression is not needed. So far only used for postdecrement/increment statements on local variables (which is the most frequent case where this matters.)
- fixed postincrement and decrement for local variables. Due to the result preservation semantics it created faulty code.
- removed 'self' as a dedicated token. Internally this gets handled as a normal but implicitly named variable so the token just gets in the way of proper processing.
- removed P_ prefix from SpawnMissile export.
- fixed a crash with misnamed function exports.
- allow class extensions.
These are separate blocks in different files that get concatenated to one class body for processing. The reason is to allow spreading the many functions in Actor over multiple files, so that they remain manageable. For example, all the Doom action functions should be in their respective files, but their symbols need to be in Actor. To extend a class, both files need to be in the same translation unit, so it won't allow user-side extension of internal classes.
- Setting an actor's Crash state has the potential to destroy the actor if
the Crash state has one or more 0-tic states that end with Stop. This
was not taken into account when the object's Z velocity was 0, but it
was under the floor anyway.
* everything related to scripting is now placed in a subdirectory 'scripting', which itself is separated into DECORATE, ZSCRIPT, the VM and code generation.
* a few items have been moved to different headers so that the DECORATE parser definitions can mostly be kept local. The only exception at the moment is the flags interface on which 3 source files depend.
- Sets the absolute amount of an inventory actor.
- Limits itself to the range [0, MaxAmount]. Setting beyondMax to true disregards the MaxAmount. Default is false.
There have been reports about crashes in here with Linux that point to some of the code that gets called here doing unwanted things on the owner, so with these links cleared that should no longer be possible.
- Fixed properties not having the proper indices.
- Use ViewPos-to-actor instead of measuring actor-to-actor.
- Use the actual camera instead of the actor so camera textures can work.
- added sanity checks to prevent a savegame from being loaded with an incompatible map
- refactored a few things to simplify serialization.
- started work on main level serializer function.
The way this was done was a major headache inducer, requiring reconstruction of the function each time the value was changed and in general made actor damage a major hassle.
There was a DECORATE wrapper to mimic the original behavior but this looked quite broken because it completely ignored the different semantics of both damage calculation types.
It also made it impossible to determine if damage was a function or a value.
This accessor has been reverted to what it should be, only returning the constant, which now is -1 for a damage function. I am sorry if this may break the odd mod out but a quick look over some DECORATE-heavy stuff showed that this was never combined in any of them so that accessing 'damage' in DECORATE code depended on an actual damage function.
To get proper damage, a future commit will add a DECORATE function which calls AActor::GetMissileDamage.
- Crashes occurred if a particular actor was a tracer to the player and the actor was not gone by the time the player unmorphs.
- Failed unmorphs occur if tracer was manipulated through means like A_RearrangePointers, etc.