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.