- fixed the return type checks in CallStateChain. These made some bogus assumptions about what return prototypes to support and would have skipped any multi-return function whose first argument was actually usable.
This should for now conclude actor class scriptification. The remaining ten classes with the exception of MorphedMonster are all too essential or too closely tied to engine feature so they should remain native.
- improved the class pointer to string cast to print the actual type it describes and not the class pointer's own type.
- fixed: The 'is' operator created non-working code when checking the inheritance of a class pointer, it only worked for objects.
There are a few which require explicit native construction or destruction that need to be exported to the VM, e.g. FCheckPosition.
The VM cannot handle this directly, it needs two special functions to be attached to handle such elements.
- created script exports for all relevant functions with all integral types.
- created script side definitions for the underlying data types.
- added a void pointer type so that the prototype for the pointer array can use a generic type every pointer can be assigned to.
- made ModifyDamage calls iterative instead of recursive. With going through the VM they'd be too costly otherwise.
- small optimization: Detect empty VM functions right when entering the VM and shortcut them. This is to reduce the overhead of virtual placeholders, which in a few cases (e.g. CanCollideWith and ModifyDamage) can be called quite frequently.
This function calculated everything correctly but ultimately set the vertical velocity wrong. Most importantly this meant that the actual velocity vector and actor pitch - if CMF_SAVEPITCH was used - did not match.
Since this bug has been present since the pitch parameter was added, this deprecates A_CustomMissile and replaces it with a properly implemented A_SpawnProjectile function and handling the compatibility case with a new flag and a scripted wrapper function.
All internal uses of A_CustomMissile have been replaced as well.
This will get called for both actors taking part in a collision, if one of the two calls returns false it will immediately abort PIT_CheckThing with no collision taking place at all.
It is utterly pointless to require every function that wants to make a VM call to allocate a new stack first. The allocation overhead doubles the time to set up the call.
With one stack, previously allocated memory can be reused. The only important thing is, if this ever gets used in a multithreaded environment to have the stack being declared as thread_local, although for ZDoom this is of no consequence.
- eliminated all cases where native code was calling other native code through the VM interface. After scriptifying the game code, only 5 places were left which were quickly eliminated. This was mostly to ensure that the native VM function parameters do not need to be propagated further than absolutely necessary.
- removed the native parts of SpecialBlastHandling. Since this is called from the script side and the only remaining native remnant was an empty function it's now 100% scripted.
- cleaned up the virtual function interface of APlayerPawn which still had many virtual declarations from old times when class properties were handled through virtual overrides. None of this makes sense these days anymore.
- Changed the glass shards so that they do not have to override FloorBounceMissile. It was the only place where this was virtually overridden and provided little usefulness.
- made 'out' variables work.
- fixed virtual call handling for HandlePickup.
- merged the FrontBlock searcher for the Bloodscourge into RoughMonsterSearch. This also fixes the bug that the searcher was not initialized properly for the MageBoss.
- made '->' a single token. Although ZScript does not use it, the parser tends to get confused and fatally chokes on leftover arrows so this ensures more robust error handling.
A few notes:
* this accesses the lines array in sector_t which effectively is a pointer to an array of pointers - a type the parser can not represent. The compiler has no problems with it, so for now it is defined internally.
* array sizes were limited to 65536 entries because the 'bound' instruction only existed as an immediate version with no provisions for larger values. For the static map arrays 65536 is not sufficient so now there are alternative instructions for these cases.
* despite the above, at the moment there is no proper bounds checking for arrays that have no fixed size. To do this, a lot more work is needed. The type system as-is is not prepared for such a scenario.
- fixed: Assignment from a readonly to a read-allowed pointer must be an error.
- made GetDefaultByType a builtin so that it can do proper type assignment to the result, which for a function would be problematic in this case, even if automatic type deduction was implemented. Since this returns the class defaults which are not a real object, the result cannot be subjected to a type cast.
- error out if a type cast of a readonly pointer is attempted.
- fixed: FxBooleanNot could clobber a local variable because it used the source register to manipulate the result.
- fixed issues with the refactoring of the recent commits. This one starts again.
- added builtins for TextureID.
Note about builtins: Currently they are just hacked into the compiler backend. They really should be made part of the respective types to keep matters clean and allow more widespread use of builtins to create more efficient code.
- refactored the ModifyDamage interface to be more scripting friendly.
In general it should be avoided having to call directly into chained inventory functions because they are very problematic and prone to errors. So this got wrapped into a single handler (on AActor, not AInventory!) which will later make it easier to refactor the parameters of ModifyDamage to work better for scripting and avoid the chaining.
Two reasons for this:
1. if this has to be routed through the VM each recursion will cost 1000 bytes of stack space which simply is not good.
2. having the virtual function only care about the item itself but not the entire inventory chain is a lot less error prone for scripting.
Since the scripting interface needs a separate caller function anyway this seemed like a good time to change it. The same will be done for the other chained inventory handlers as well.
- allow switch/case with names.
- fixed break jump target handling for switch/case. This only worked when the break was in the outermost compound statement, those in inner ones were missed.
Interesting tidbit: The damage calculation in P_MinotaurSlam had been incorrect for the Heretic version since the friendly Hexen Dark Servant was added, but nobody ever noticed in 14 years...
- Took the opportunity and fixed the logic for the Skull Rod's rain spawner. The old code which was part of the 3D floor submission was unable to work with portals at all. The new approach no longer tries to hide the dead projectile in the ceiling, it leaves it where it is and changes a few flags, so that its z-position can be used as reference to get the actual ceiling. This works for line portals, but for sector portals still requires some changes to sector_t::NextHighestCeilingAt to work, but at least this can be made to work unlike the old code.
- added names for the player-related translations to A_SetTranslation.
- fixed: Failure to resolve a function argument was checked for, too late.
- made the parameter for A_SetTranslation a name instead of a string, because it is more efficient. We do not need full strings here.
- scriptified all Effect functions of Fastprojectile's children
- implemented access to class meta data.
- added a VM instruction to retrieve the class metadata, to eliminate the overhead of the function call that would otherwise be needed.
- made GetClass() a builtin so that it can use the new instruction
Important note about this commit: Scriptifying CFlameMissile::Effect revealed a problem with the virtual function interface: In order to work, this needs to be explicitly enabled for each single native class that may be used as a base for a scripted class. Needless to say, this will end up way too much work, as there are over 100 native classes, excluding those which will be scriptified. But in order to fix the problem this partially broken state needs to be committed first.
- fixed: FxAssignSelf did not the correct number of registers for vector operations.
- fixed a few asserts in vector2 instructions.
- turned the virtual AActor::HitFloor method into a flag MF7_SMASHABLE. The only use of this function was to kill Hexen's pottery when they hit the floor, and this looks like something that can be exposed to modders less clumsily.
- added new VARF_Transient flag so that the decision whether to serialize a field does not depend solely on its native status. It may actually make a lot of sense to use the auto-serializer for native fields, too, as this would eliminate a lot of maintenance code.
- defined (u)int8/16 as aliases to the byte and short types (Can't we not just get rid of this naming convention already...?)
- exporting the fields of Actor revealed a few name clashes between them and some global types, so Actor.Sector was renamed to CurSector and Actor.Inventory was renamed to Actor.Inv.
- refactored state bitfield members into a flag word because the address of a bitfield cannot be taken, making such variables inaccessible to scripts.
- actually use PNativeStruct for representing native structs defined in a script.
- implemented method calls from struct instances.
- optimized disassembly of VM call instructions to print the function's name at the end where it is more visible and does not need to be truncated. Also use the printable name for script functions here.