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.
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.
Latency placement is no longer fixed:
* If time is visible, it is placed on top of the screen and latency is placed below
* If time is not visible, latency is placed on top of the screen
Both are displayed on alternative HUD only
- Somebody might want to set a midtexture's Y scale negative to flip it
vertically. I'm pretty sure this would mess up 3D mid textures if we
don't make it positive again for those.
The reason for this is that on my system, the static or delay loaded method always picks the (obsolete) system-installed OpenAL version (needed for some old games) which is not wanted here if there's another one in the local ZDoom directory.
This also removes the dependency on the broken import library that comes with OpenAL Soft which causes compile errors with more modern MSVC compilers on default settings.
These objects are supposed to be bright, but the standard translations for player do not take this into account, creating dark and/or invisible projectiles depending on the color being used.
The new translation uses hue and saturation from the player color, but combines brightness from the original color with the one for the player in an 8:2 ratio, so that no matter for the player color, these always remain bright and visible.
- Since voxels can have their origin behind the viewer and still have a
portion visible in front of the viewer, they aren't clipped to MINZ like
face sprites are. The 3D floor handling in R_DrawSprite() neglected to
clamp it when recalculating the diminished light colormap.
- Aside, but R_DrawSprite() probably shouldn't be messing with these
properties at all. Why isn't this done in R_ProjectSprite() before it
ever gets to the drawing part?
Independently from OS version the game will enter fullscreen mode when zoom button is clicked
Window zooming behavior introduced in Yosemite is available on all supported versions of OS X
- The original Doom renderer was inclusive for all right edges. This was
fine for the wonky projection it did. This was not fine for a standard
perspective divide, so I had to change walls to be right-edge exclusive
when I changed the projection. I only touched what was needed. Until
now. The right edge is always exclusive now, which should prevent any
more bugs related to mixing the two clusivities incorrectly.
- The flags use TELF_ since DECORATE has an A_Teleport with its
own set of TF_ flags.
- TELF_KEEPVELOCITY is used instead of TELF_HALTVELOCITY, because
there was only one call that ever set bHaltVelocity to false.
According to Blzut3:
The issue happens when the fullscreen resolution is the same as the desktop resolution. In this case WM_DISPLAYCHANGE doesn't occur so the editor never appears. This appears to be fixable by also catching WM_STYLECHANGED since at the very least the window caption will appear/disappear.
- having a value of 5000 as the default for autoaim makes no sense, since this is an angle value that will always be clamped to [0..35]. So now 35 is both the default and the maximum.
- Renamed the 'noabsolute' parameter in side_t::GetLightLevel to 'is3dlight', what it actually is, to avoid the confusion that caused the abovementioned error.
- fixed: The Down2Up render path for sides of 3D floors had the 'is3dlight' check inverted.
These checks had some major issues:
* they calculated incorrect positive values for hitting a ceiling
* the way they used the plane equations made some incorrect assumptions.
* velz has the velocity reduction from bouncing already factored in from the calling code so doing it here again is not necessary.
- Check if a co-op start exists. If not, pick one at random.
- Don't telefrag other players when spawning in co-op games, since
you're allowed to move out of other players now.
Fixing this required adding an external list of active stack objects that the garbage collector can access.
A nice side effect: It's no longer necessary to pass around the stack info to various functions that might end up triggering a garbage collection.
Issues this fixes:
* all original Doom attack functions unconditionally altered the flash state.
* A_FireOldBFG, A_RailAttack and A_Blast never checked for a valid ReadyWeapon.
* CustomInventory items could deplete an unrelated weapon's ammo.