Map things are writeable in Lua, which I am pretty certain is a mistake because mapthings are not sent over the network at all. I considered making them net-synced (it would be relatively easy), but it also aligns with another, more "philosophical" issue: Doom generally copies over properties from mapthing_t into mobj_t, and then only refers to it again when needing to respawn an object -- mapthing_t is not really intended to be referred to very often at runtime. At best it's slightly annoying since some objects rely on a spawnpoint for behavior changes, at worst it may make ACS more confusing in the future since Thing and Mobj tags are mixed together or less useful since they wouldn't be able to modify behaviors of objects that are based on args.
So I decided to solve these two issues at the same time; just treat mapthing_t as something to copy values from, like OG Doom does it. This basically just means that special and args are also part of the mobj now instead of the mapthing, which should fill any desire to edit this stuff from Lua, and reduces the number of instances where objects need to check for their spawnpoint to function properly.
P_LineOpening results are stored in a locally made struct instead of being a bunch of disorganized globals.
Waypoint traversals can go thru 1 line, if it was blocked by step-up rules, for free, similar concept to sound-blocking lines in Doom.
Adds some functions:
- K_Bumpers, bumper count for the count, intended for
where player->bumpers was used in HUD and visual
contexts.
- K_BumpersToHealth, converts bumper count to health
points.
player->mo->health replaces player->bumpers where it was
used in health contexts.
Removes some functions:
- K_HandleBumperChanges
- K_DestroyBumpers
Everything K_HandleBumperChanges did has either been
removed or moved elsewhere. P_KillMobj also already called
K_CheckBumpers.
K_DestroyBumpers became pointless after player->bumpers
was removed.
This fixes some thinkers never being removed due to having
negative reference counts.
And here's a breakdown of why the old code could produce
negative reference counts:
Consider P_CheckPosition. This function calls P_SetTarget
on tm.thing but does not call P_RestoreTMStruct. This
means that tm.thing will not be NULL the next P_SetTarget
is called on it. What are the implications of this?
Consider the following series of events:
- P_CheckPosition is called, tm.thing != NULL afterward
- Another function saves the tm struct and sets tm.thing to a different mobj
- - the old tm.thing will have its references decremented
- - the new tm.thing will have its references incremented
- This function calls P_RestoreTMStruct
What should happen when P_RestoreTMStruct is called? The
*new* tm.thing should have its references *decremented*
and the *old* tm.thing should its references
*incremented*, of course, for symmetry with P_SetTarget.
The old code correctly decremented new tm.thing's
references but did not increment old tm.thing's
references.
- Includes a struct definition for symmetrical objects
made out of papersprite sides.
- Dimensions of papersprite sides are looked up using
sprite cache.
- Monitors may contain multiple types of items.
- Item RNG is deterministic from the time the monitor is
spawned but the item types are not stored in memory.
Instead the RNG seed is restored every time an item type
needs to be determined. Item types need to be determined
every time the icon on the monitor's screen changes and
when the monitor is popped and drops all its items.
- Monitors sparkle like emeralds if there is an emerald
inside.
- Monitors take damage from players simply bumping into
them. The damage scales up with speed and weight.
- Activating a lightning shield in proximity decimates the
monitor into being able to be destroyed in one hit by
anything thereafter.
- All throwable / deployable items destroy a monitor in
one hit.
- Lines can be set to activate when crossing or bumping into them, with distinctions for players, enemies, and missiles+items.
- A new flag has been added to determine if a line special can activate more than once.
- Finish Line + Respawn Line are now handled like other specials. This means that:
- They follow the new line activation rules (so you can potentially have a finish line that you have to bump instead of cross)
- More importantly, they can be called as functions in ACS. (Player_FinishLine and Player_Respawn)
- Fixed linedef flags not being saved in save games.
- Things with MF_NOCLIP can still run code when touching things, but won't be blocked by them.
- Things need both (MF_NOCLIP|MF_NOCLIPTHING) to do a single movement step, since MF_NOCLIP can do thing collision now.
Old vanilla-ass code for platform-like objects that is conflicting super hard with bumping / horizontal momentum. If we ever have a moving platform object this code should be brought back only for that object, and not solid objects as a whole.
Can be used to disable VFX, so it can only appear if its owner is a display player. If no owner is provided, then it will be removed entirely.
Applied to most things that Ivo asked for
Gremlins happened whenever P_TryMove and P_SlideMove/P_BounceMove disagreed on what an object collided with. When TryMove said you collided with a line, but P_BounceMove said that you didn't, then you'd get gremlin'd.
To fix this, P_TryMove now can edit a struct to contain information on what it collides with. P_SlideMove and P_BounceMove no longer try to detect walls on their own and now requires this result from P_TryMove. If a slide/bounce is needed without moving the object, then you'd want to use P_CheckMove to get the result.
Lua is not supported right now.