While testing this it became clear that with the higher precision of doubles it has to be avoided at all costs to compare an actor's z position with a value retrieved from ZatPoint to check if it is standing on a floor. There can be some minor variations, depending on what was done with this value. Added isAbove, isBelow and isAtZ checking methods to AActor which properly deal with the problem.
* there is a new crushing mode 3, which means that the crusher will always slow down if it hits an obstacle.
* crushing mode 1 (Doom mode) will never slow down.
* crushing mode 0 (compatibility) will only slow down for the specials that did so before, and only if both up and downspeed are 8 and the game is not Hexen. The following specials are affected:
* Ceiling_LowerAndCrush
* Ceiling_LowerAndCrushDist
* Ceiling_CrushAndRaise
* Ceiling_CrushAndRaiseA
* Ceiling_CrushAndRaiseDist
* Ceiling_CrushAndRaiseSilentA
* Ceiling_CrushAndRaiseSilentDist
* Generic_Crusher was fixed to act like in Boom: Not only a speed value of 8 will cause slowdown, but all speed values up to 24.
* Hexen crushing mode will never cause slowdowns because Hexen never did this. (which also makes no real sense, considering that the crusher waits for the obstacle to die.)
- removed use of finesine for creating the player backdrop for the menu display. This mostly uses the code from the old 2.0 floating point version but fixes some of the constants in there which were not correct.
- Includes 2 flags, affixed by CBF_: AbsolutePos, and AbsoluteAngle.
- AbsolutePos: Absolute position of where to check.
- AbsoluteAngle: Angle parameter is used as is, not added onto the actor's current angle.
* Added falloff parameter to A_QuakeEx.
- Treated just like A_Explode's 'fullradiusdamage' parameter, where the quake will fall off from this distance on out to the edge. Default is 0, which means no falloff.
- Credits to MaxED and Michaelis for helping.
* - Added HighPoint parameter to QuakeEx.
- Allows fine tuning of where the quake's maximum or minimum occurs, in tics. This must be a range between [1, duration).
- For up or down scaling quakes, this sets the quake to reach maximum sooner or start minimizing later.
- For both, this indicates when the strongest will occur. Default is 0, or in the middle.
The original commits were nearly impossible to find in the convoluted commit tree, so I think it's preferable to have one clean commit instead.
- started converting g_hexen.
Most importantly this removes CHolyWeave as it is just a specialized version of A_Weave with far more convoluted use of parameters.
- replaced some uses of FRACUNIT with OPAQUE when it was about translucency.
- simplified some overly complicated translucency multiplications in the SBARINFO code.
- Having my edits to the grammar disappear because Visual Studio had
opened the copy instead of the original was super annoying. Using the -C
option with Lemon, this problem is avoided because there are no copies
to worry about.
- Enhancements to lemon to generate more compact action tables and to avoid making array bounds tests that can never fail on action table calculations. (user: drh)
- Update zcc-parse.lemon: YY_SZ_ACTTAB is now YY_ACTTAB_COUNT
Only things left here are accesses to AActor::ceilingz and radius in A_PainShootSkull, plus scaleX and scaleY in the ScriptedMarine sprite setting code.
Most is still using wrapper functions around the fixed point versions.
I can't believe I missed this for more than 10 years, considering that A_CustomMissile explicitly implements this case:
It makes a crucial difference whether P_SpawnMissileZ is used or the actual z-position is temporarily changed.
Reverted this function to the position changing method of the original.
- for quakes, making a distinction between circular and elliptic thrust is pointless, so the checks were removed and both paths consolidated. The elliptic code will do exactly the same for circles and there isn't even a performance difference.
- Converted P_MovePlayer and all associated variables to floating point because this wasn't working well with a mixture between float and fixed.
Like the angle commit this has just been patched up to compile, the bulk of work is yet to be done.
- Don't bother keeping track of uncompiled nodes in a special table. Use
the regular symbol table instead. This should in the future make
compiling nodes referenced deeper than (and before) their definitions
fairly straightforward.
- Also, break up the compiler's Message() function into Warn() and Error()
and get rid of zcc_errors.h. I can't really see having a set of error
numbers being useful.
Patched up everything so that it compiles without errors again. This only addresses code related to some compile error. A large portion of the angle code still uses angle_t and converts back and forth.
- Worked aorund modern GCC bug where C++ exceptions in Objective-C++ code would result in an ICE (bug is already on their tracker, but I doubt it will be fixed unless I decide to dig into the issue myself).
- Turn off fused floating point instructions since these can cause slight deviations in floating point code.
- Use -static-libgcc when compiling on the Mac with GCC since we need to use a custom version of GCC to do so now.
- Note: ZDoom will currently still crash on exit on PowerPC since it seems to be deciding that NameManager needs to be destructed before the console commands.
- fixed: P_TryMove could loop endlessly over a list of static portals when there was an error during portal creation.
# Conflicts:
# src/gl/models/gl_models.cpp
# src/gl/scene/gl_sprite.cpp
When a spechit results in teleportation, P_TryMove never accounted for that, so that subsequent spechits either failed or succeeded, depending on where the teleport ends up.
With portal-aware positions stored within the spechit this no longer worked, so some handling is needed to revert to the original behavior in case there's no portals to consider.
The ideal solution would have been to stop checking spechits (or to block further teleports) once this happens but the likelihood of some old maps depending on this is high.
- _FPU_GETCW is defined for more than just x87. Don't use it if the
control word for the target architecture doesn't support _FPU_EXTENDED
or _FPU_DOUBLE defined, e.g. pretty much anything but x87. If I had been
using glibc on PowerPC instead of Apple's libc, I probably would have
noticed this sooner, since _FPU_GETCW is part of glibc.
- First, don't crash when travelling to a map in a hub that doesn't have
any player starts that match the position given to Teleport_NewMap (or
equivalent).
- Seconed, move the player to the location they were at when the left the
level. At least that way, they shouldn't be in random geometry or off
the map entirely.
The patch content was destructed and then accessed when loading DeHackEd file of old/unsupported version
Do not print the whole patch content to console but only a filename
Links through sector portals are not done because nearly all the checks can be performed without doing this so if it works without there's no need to add more processing time.
Will have to see if there's cases left where such a link is needed and if so, whether there's better options to do it.
For line portals such links are necessary to have proper collision detection with actors that are currently transitioning the portal.
- handle a 'restart' CCMD a bit more controlled. Instead of throwing an exception in the CCMD handler it now just flags D_DoomLoop to return.
If the exception is thrown within the CCMD this can easily happen deep inside the renderer when it calls NetUpdate. But since the software renderer with its use of global variables is not equipped to be yanked out of lile this it could leave broken data behind that caused glitches or even crashes on subsequently played maps.
Notes:
* It is actually not enough to disable the early-out condition for the current block if there's a portal. It must be disabled for the entire rest of the trace because otherwise the collected lines never get processed.
* The block bounds check cannot be done globally with portals in the game. The actual trace can easily end up outside the blockmap bounds if portal offsets are factored into the distance between the two actors.
- This could happen in co-op games that did not have enough player starts
for all the players spawning. Voodoo doll starts were not excluded from
the set of possible starts as they should have been.
- The following Hexen specials all stop 8 units above the floor:
* Ceiling_CrushRaiseAndStay
* Ceiling_CrushAndRaise
* Ceiling_LowerAndCrush
We only and Ceiling_LowerAndCrush correct. Clearly, I should have paid
more attention when the Hexen source was released for the parts that I
had already reverse engineered.
This currently only works for linked portals. For other types some major refactoring may be necessary because it not only requires multiple passes of P_RadiusAttack but also an alteration of how sight checks work.
- fixed: P_FindFloorCeiling set the floorsector for a new ceilingheight.
Note: P_DrawRailTrail still needs to be changed, at the moment rail trails through portals will not work correctly.
- be a bit smarter about what to copy from a subtrace. There's 3 distinct pieces of information here: The hit itself, the CrossedWater setting for Boom-transfers and the CrossedWater setting for 3D floors.
Note: Ideally this should return all water hits it can detect, not just the first one.
- fixed: FMultiBlockLinesIterator initialized continueup twice but forgot continuedown.
- fixed: One of the debug messages in P_AimLineAttack was missing an if (aimdebug).
- Added new state options that DECORATE got to the lemon parser.
- Enable token generation for state options. They were previously not
generated, so the grammar treated them as function calls instead.
- I don't remember why I thought using PPointer as the metatype for
PClassPointer would be preferable, but it means that PPointer's MatchID
can potentially be called for PClassPointer entries.
* any line completely parallel to the portal is rejected
* any line with one end on the same straight line than the portal is solely decided by the other vertex.
* any line with both ends behind the portal cannot be visible inside, so there's no need to check for an intersection with the view range.
* due to the above P_IntersectLines could be removed as it was redundant.
* for any line that does intersect with the portal straight, do a reverse check: If both ends of the portal lie on the other side of the line than the viewpoint, the line is between viewpoint and portal and needs to be rejected.
This fixes nearly all the phantom wall glitches in the demo map.
* when starting directly on a blockline the trace was offset by one map unit. Do this only for the internal block trace calculations but not for the variable that's being exposed to the outside because in rare situations that can create incorrect values.
* using startfrac could lead to an actor whose inside was right at that positon to be missed.
* when using startfrac the adjusted trace start was not used for all calculations, which could cause the trace to fail.
With these issues fixed, P_AimLineAttack can now successfully navigate line portals.
To allow processing the hit through an arbitrary portal without reference to the portal group table, P_AimLineAttack and P_LineAttack need to pass some more info than just the linetarget.
We need the relative positions of shooter and target within the visual reference of the other to calculate proper angles and we need to know if such a portal was crossed at all, because a few things, e.g. seeker missiles won't work with them.
- fixed setup of target acquisition for the Mage Staff.
The pre-acquired seeker target was never passed to the spawned projectiles.
- converted the P_TranslatePortal* functions to use floating point trigonometry. The combination of R_PointToAngle and finesine even created discrepancies with perfectly parallel portals which is just not acceptable.
- added a function to FPathTraverse to relocate the trace and restart from the new position.
- made P_UseLines portal aware. Traversal through line portals is complete (all types, even teleporters), whether sector portals need better treatment remains to be seen - at the moment it only checks the range at the player's vertical center.
The function to do the work scanned the full list of drawsegs to find portals, which with a large amount of masked geometry and/or drawsegs could become extremely slow.
Changed it so that R_DrawMasked collects all portal related drawsegs up front so that the actual clipping code can
a) scan a far shorter list and
b) can skip half of the validation.
Also using P_PointOnLinePrecise to shave off a small bit of additional time.
The reason is that in such a case it is very likely that the IWAD defines its own menu and will most likely not provide all assets for the base definitions. See 'Adventures of Square' for an example.
Attempts to output errors with bad characters encountered during text lumps parsing were failed miserably because of UTF-8 conversion
Example: loading of GZ-Models-r16.pk3 with GZDoom caused 'NSConcreteAttributedString initWithString:: nil value' exception
During loading of .pk3 that stores hundred of .wad's significant amount of time were spent on scrolling text to the last line
The same applies to other cases like output of thousands warnings/errors
* Arch-Vile resurrection
* Boom point pushers (due to complete lack of z-handling only for line portals.)
* A_RadiusGive
These also require a more thorough collection of portal groups than simple position checks.
It can easily happen that the lower sector has no lines below the checked area, in which case it would not set the dropoffz correctly. To prevent this, P_LineOpening must, when it checks the opening over a sector portal, actually calculate the dropoff to the lower portal itself by calling sector_t::NextLowestPointAt. It also means that FindRefPoint must calculate a proper reference point when one side of the line to be checked is part of a floor portal.
This fixes Clang complaining about unknown command option '-Wno-unused-but-set-variable' when compiling dumb.
Also I got no new warnings on Clang by excluding '-Wno-unused-result'.
This includes:
* allow one sided portal linedefs to be crossable when part of a polyobject. Due to the limitations, two-sided linedefs won't work here. For general use this is still not allowed because making them passable would require some crippling fudging.
* delay portal finalization until after polyobjects have been spawned.
* the camera interpolation also needs to handle angle differences.
The code is still not 100% complete - the most important thing that is still missing is proper handling of P_CheckPosition through arbitrary portals.
- added portal offsetting to all AproxDistance, AngleTo and Vec*To members of AActor.
- optimized displacement retrieval so that the most common case with no offset retrieves a constant null-vector which can be optimized away fully by the compiler.
- early out in P_GetOffsetPosition if there's no portal lines nearby, so that the common case can skip the traverser completely even on maps with line portals.
- made some minor changes to FPathTraverse so that the Add*Intercepts methods can be virtually overridden.
- removed the PortalTracer class because in its existing form it was too costly. Replaced with a P_GetOffsetPosition function that does the minimum required work to get to the translated destination and that's better suited for being called from the Vec*Offset methods. Other use cases will require some changes to FPathTraverse anyway, or some wrapping class like the FMultiBlock iterators.
- renamed sector_t::soundorg in centerspot, changed the type to a fixedvec2 and removed the CenterSpot #define.
Since this thing was used in lots of places that have nothing to do with sound the name made no sense. Having it as a fixed_t array also made it clumsy to use and the CenterSpot #define used a potentially dangerous type cast.
- Split specific parsing for each intrinsic out of ParseExpression0 and
into their own functions.
- Instead of reserving keywords for intrinsics, identify them by name
within TK_Identifier's handling.
* Blocking lines above or below the current sector should only block if they actually intersect with the currently checking actor.
* Sectors above a ceiling portal should not change current floor information and vice versa.
- Don't use isMissile(). Check directly for the flag at the moment of calling and not the default. Otherwise, things changing themselves will still be ineligible for non-missile checks.
* removed all code for dealing with z-displacing portals in the iterator loops. This would cause too many problems so I decided to scrap any provisions for allowing interactive portals with z-displacement. They will remain restricted to pure teleporter portals.
* changed spechit to carry a position along with the special line. If something is activated through an interactive portal this is needed to calculate movement.
* pass the abovementioned position to CheckForPushSpecial.
* collect touched portal lines in a second array analogous to spechit.
* use FMultiBlockThingsIterator in P_TestMobjZ.
(This is just a safety commit before doing some more extensive behind-the-scenes refactoring.)
Notable changes here:
* use the same logic for determining whether a 3D floor is 'below' or 'above' the actor as all the other functions.
* removed the broken code which tried to detect whether an actor was touching a steep slope. Better use P_LineOpening to find the correct planes and store the results.
* improved detection whether the slopes on both sides of a plane are identical, using the same data as for steep slope detection.
- This is an effort to emphasize that these are just type casts. Now they
look like function-style casts with no action function styling.
They do no magic joojoo at all. The only reason they exist is because
the DECORATE parser can only parse return statements that call a
function, so these satisfy that requirement. i.e. *return int(666);* is
identical to *return 666;* (if the parser could handle the latter).
- Now that state jumps are handled by returning a state, we still need a
way for them to jump to a NULL state. If the parameter processed by this
macro turns out to be NULL, Actor's 'Null' state will be substituted
instead, since that's something that can be jumped to.
Note: This replaces AActor::intersects with a direct calculation. Although that function could be adjusted it'd mean some redundant distance calculations which are easily avoided.
- The FMOD 4.44 linux package contains both 32 and 64-bit versions, with the folder name without the '64' suffix for 64-bit.
- Add minor version '61' so that the latest FMOD package (at the time of this commit) can be detected and compiled successfully.
- some consolidation in p_map.cpp. PIT_CheckLine and PIT_FindFloorCeiling had quite a bit of redundancy which has been merged.
- čontinued work on FMultiBlockLinesIterator. It's still not completely finished.
- This is so that you can call an A_Jump-type function from inside an if
statement and do something other than jump if the jump condition was
met. e.g.
{
if (A_Jump(128, "Foo"))
{
A_Log("The function would have jumped");
}
else
{
A_Log("The function would not have jumped");
}
}
- Since DECORATE's return statement can only return the results of
function calls (I do not want to spend the time necessary to make it
return arbitrary expressions), here are three functions to get around
this limitation:
* A_State - Returns the state passed to it. You can simulate A_Jump
functions with this.
* A_Int - Returns the int passed to it.
* A_Bool - Returns the bool passed to it.
- e.g. If you want to return the number 3, you use this:
return A_Int(3);
If you want to jump to a different state, you use this:
return A_State("SomeState");
- The A_Jump family of action functions now return the state to jump
to (NULL if no jump is to be taken) instead of jumping directly.
It is the caller's responsibility to handle the jump. This will
make it possible to use their results in if statements and
do something other than jump.
- DECORATE return statements can now return the result of a function
(but not any random expression--it must be a function call). To
make a jump happen from inside a multi-action block, you must
return the value of an A_Jump function. e.g.:
{ return A_Jump(128, "SomeState"); }
- The VMFunction class now contains its prototype instead of storing
it at a higher level in PFunction. This is so that
FState::CallAction can easily tell if a function returns a state.
- Removed the FxTailable class because with explicit return
statements, it's not useful anymore.
A big problem with this function was that some flags required setting up some variables before calling it and others did not. It will now set everything up itself so all initializations to AActor::floorz and ceilingz that were made before these calls (which were all identical to begin with) could be removed and the internal initialization logic streamlined.
- removed Plane/Floor/CeilingAtPoint functions because they are overkill for the problem they were meant to solve. Calling ZatPoint with adjusted coordinates created with AActor::PosRelative is just as easy in the few places where this is needed.
- made P_HitWater and P_CheckSplash portal aware.
To summarize, anything that just works with map geometry doesn't need to bother, as does the renderer. (i.e. nearly all r_* files, p_floor.cpp, p_ceiling.cpp et.al)
But all calls that are somehow related to actor positions need to be made aware of potential portal transitions:
* added FloorAtPoint, CeilingAtPoint and PlaneAtPoint methods to sector_t, which can be used to calculate a plane's height with relation to a given actor, even if that actor is on the other side of a portal.
* added HighestCeilingAt and LowestFloorAt methods which traverse all ceiling/floor portals until they find an impassable plane.
* the temporary checking arrays are now static
* the array that gets the returned values only starts allocating memory when the third touched sector group is found. The most common cases (no touched portal and one touched portal) can be handled without accessing the heap.
- did some streamlining of AActor::LinkToSector:
* there's only now version of this function that can handle everything
* moved the FIXMAPTHINGPOS stuff into a separate function.
* removed LinkToWorldForMapThing and put all special handling this function did into P_PointInSectorBuggy.
- improved: If there's an offset mismatch, do not print group numbers as they are utterly meaningless. Instead look for a sector in each group and report those.
- added a copyright notice and some comments to portals.cpp.
This was to resolve some circular dependencies with the portal code.
The most notable changees:
* FTextureID was moved from textures.h to doomtype.h because it is frequently needed in files that don't want to do anything with actual textures.
* split off the parts from p_maputl into a separate header.
* consolidated all blockmap related data into p_blockmap.h
* split off the polyobject parts into po_man.h
* set up linked sector portals so that everything that will eventually have to be considered is present, even though the software renderer currently can't handle those adequately.
* tag all skybox things with a type so that they can easily be distinguished at run time.
* fill in the linked portal types in xlat/eternity.txt.