* 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.
OpenAL specification doesn't require alcGetIntegerv() to return meaningful values for ALC_MONO_SOURCES and ALC_MONO_SOURCES.
At least Apple's OpenAL implementation returns zeroes, although it can generate reasonable number of sources.
With late resolving it cannot be guaranteed at this point and caused some incorrectly compiled code. Since the cast gets optimized away anyway when not needed there's no point being this selective with applying it.
If done as before, forward-declared classes cannot be found, and the immediate resolving is only needed for constant expressions, so explicitly enabling it in the 4 places where it is needed ensures that those unresolvable expressions remain intact until the final processing pass righr before the code generator is started.
This cuts down on as much message noise as possible, outputs everything to a file specified as a parameter and then quits immediately, allowing this to run from a batch that's supposed to check a larger list of files for errors.
Multiple outputs get appended if the file already exists.
Converting a floating point value that is out of range for a signed integer will result in 0x80000000 with SSE math, which is used exclusively for this purpose on modern Visual C++ compilers, so this cannot be used anywhere.
On ARM there's problems with float to unsigned int conversions.
xs_Float does not depend on these
The first fix missed a second place where this happened and was incomplete.
Anything usable by Dehacked must be VARF_ACTION and VARF_MEMBER in order to work as intended.
- This isn't a real file or even a name, but the game would try and load
it, including running through various permutations, potentially resulting
in loading the current directory as an archive.
Please note that these still require the portal to be set up in the map with Line_SetPortal. It will not create a new portal if none exists on any line with the given ID.
* linked portals may never have a z-offset so the parameter for that needs to be ignored.
* for interactive portals, handling z-displacements when some distance calculation reaches through a portal is way too extensive and problematic to ever have a chance of really working. If such a portal gets defined it will be changed to a teleport-only portal and a message printed.
- store portal data in a separate structure.
- store portal data in savegames because some of this will be changeable later.
- run a cleanup pass after all portals have been created to weed out broken ones.
- add a definition type that's compatible with Eternity Engine's line portal types.
- swapped arg[2] and arg[3] of Line_SetPortal, because the type is more significant than the alignment.
- This might have been added in an effort to fix problems caused by mixing inclusive
and exclusive right edges. It might not be needed anymore. Let's find out...
- did some cleanup on the portal interface on linedefs: All checks should go through isLinePortal (gameplay related) and isVisualPortal (renderer related) which then can decide on the actual data what to return.
- removed portal_passive because it won't survive the upcoming refactoring.
- removed all direct access to portal members of line_t.
- always use the precise (and fast) version of P_PointOnLineSide inside the renderer.
This is to keep some people from jumping the gun on this and preventing the implementation of a proper toggling mechanism.
The feature itself will come back, but differently.
- removed portal setup from Build maps
they don't define it anyway so it makes no sense to have it there. Once this code gets refactored this will be in a different place that's identical for all map types.
- With multiple A_Jump calls possible in a single action now, it is now
possible for DoJump() to be called with a callingstate that does not
match self->state because the state had been changed by a prior A_Jump
in the same action function.
- replace all implicit conversions from FString to const char * in the header files (so that it can be test compiled with the implicit type conversion turned off without throwing thousands of identical errors.)
The function 'PClassActor::InitializeNativeDefault' is the only one which didn't allocate the 'Defaults' member variable with M_Malloc. Reported by the Address Sanitizer.