This assignment looks bogus. If the signature saved when the object
became stuck is different from the signature of the object currently
using that slot, then remove_obsolete_stuck_objects kills the object
using that slot. Signatures are defined to change when the object slot
is freed and reused. Therefore, this statement kills the new object
that took the slot of the obsolete object. This new object may be
important, such as a spawned robot or a weapon.
GCC std::array uses std::size_t for its size_type. On Linux/amd64,
`std::size_t` is `unsigned long`. On Win32, `std::size_t` is
`unsigned int`. This provokes format string warnings because an
unsigned int is passed where the format string declares an unsigned
long. On Win32, `unsigned int` and `unsigned long` are the same size,
so `unsigned long` could have been used to avoid this problem by
maintaining consistency with Linux, but it was not. This may have been
an attempt to achieve bug compatibility with Microsoft's types.
Add a workaround by defining a macro DXX_PRI_size_type in the style of
inttypes.h PRI* macros. Use an SConf test to determine the correct
value by inspecting which compilation runs succeed. Currently, Linux
needs "l", Win32 needs "", and Win64 needs "I64".
Previously, if the player was invulnerable, it was impossible to grab an
invulnerability powerup. Relax this by allowing a spawn-induced fake
invulnerability not to count as invulnerable for this test. Players
still cannot grab an invulnerability powerup if they are still under the
influence of a prior invulnerability powerup.
An optimizing compiler should inline these tests. Moving them out makes
the code easier to read, since the statements can focus on what is
updated, rather than how it is done.
Change the clearing of MultiLevelInv during initialization to reduce
wasted stores. MultiLevelInv has three fields.
Field ::Initial is not accessed by MultiLevelInv_CountLevelPowerups, and
is overwritten immediately afterward, so it does not need to be cleared
first.
Field ::Current is unconditionally cleared by
MultiLevelInv_CountLevelPowerups, so it does not need to be cleared
first.
Field ::RespawnTimer is not accessed by
MultiLevelInv_CountLevelPowerups, but needs to be cleared. Add a clear
of field .RespawnTimer and remove the clear of the entire structure.
All callers of MultiLevelInv_Count passed a constant value. Factor
out the top level blocks of MultiLevelInv_Count into helper functions,
then create two new functions corresponding to MultiLevelInv_Count(0)
and MultiLevelInv_Count(1), implemented by calling the appropriate new
helper functions.
Uses of `(short*)` usually want exactly a 16-bit signed integer. Most
platforms provide that as `short`, but that is not guaranteed.
s/(short \(*\+\)\s*)/(int16_t \1)/g
C casts do not require parentheses. C++ casts require grouping around
the target. Prepare for conversion to C++ casts by adding otherwise
unnecessary parentheses around the target of simple C casts.
s/\((\w\+\s*\*\+)\)\s*\(&\w\+\(\[[[:alnum:]+-]*\]\)*[]);]\)/\1(\2)/g
Grant processing code sets `Primary_weapon` to the user's preferred
weapon, but the delayed autoselect code then changed it back to
something else. Call select_primary_weapon instead of directly updating
`Primary_weapon`, so that `Delayed_primary` is updated too.
This also fixes a bug where the demo always recorded the player
switching to lasers/concussion, instead of the values that the player
actually received from the grant.
Reported-by: Mako88 <https://github.com/dxx-rebirth/dxx-rebirth/issues/184>
C casts do not require parentheses. C++ casts require grouping around
the target. Prepare for conversion to C++ casts by adding otherwise
unnecessary parentheses around the target of simple C casts.
s/\((\s*\(\(un\)\?signed\|int\|char\|short\|long\|float\|double\|s\?size_t\|\(u\?int[[:digit:]]\+_t\)\)\s*\**\s*)\s*\)\([&+-]\?\)\([[:alnum:]_.]\+\s*->\s*\)*\([[:alnum:]_.]\+\)\(\s*\[[^][]*\]\)*\(\s*\([];+>)*\/^%,|&<>]\)\|$\|\(\s*-\s*[^>]\)\)/\1(\5\6\7\8)\9/g
This pass only targets commonly used standard types.
s/(\(\s*\(\(un\)\?signed\|int\|char\|short\|long\|float\|double\|s\?size_t\|\(u\?int[[:digit:]]\+_t\)\)\)\s*)\s*(/static_cast<\1>(/g
C casts do not require parentheses. C++ casts require grouping around
the target. Prepare for conversion to C++ casts by adding otherwise
unnecessary parentheses around the target of some C casts.
This pass attempts to process expressions that involve parenthesized or
bracketed subexpressions, but only if those subexpressions do not
themselves contain parenthesized or bracketed subexpressions.
(int) f(1); // changed
(int) f(g()); // not changed
perl -p -i -e 's/(\(\s*((?:un)?signed|int|char|short|long|float|double|s?size_t|(?:u?int[[:digit:]]+_t))\s*\**\s*\)\s*)([&+-]?)([[:alnum:]_.]+\s*->\s*)*([[:alnum:]_.]+)((?:\s*(?:\[[^][]*\])*|(?:\([^()]*\))*))(\s*([;+>*\/^%,|&<>])|$|(\s*-\s*[^>]))/\1\(\3\4\5\6\)\7/g'
Object numbers are unsigned short, not signed short. If anyone ever
raises the object limit high enough, testing for negative values would
blacklist valid objects.
Remove unnecessary test for objnum!=object_none. If it were none,
constructing `obj` would have failed.
This pass only targets commonly used standard types.
s/(\(\s*\(\(un\)\?signed\|int\|char\|short\|long\|float\|double\|s\?size_t\|\(u\?int[[:digit:]]\+_t\)\)\s*\*\)\s*)\s*(/reinterpret_cast<\1>(/g
This pass only targets commonly used standard types.
s/(\(\s*\(\(un\)\?signed\|int\|char\|short\|long\|float\|double\|s\?size_t\|\(u\?int[[:digit:]]\+_t\)\)\)\s*)\s*(/static_cast<\1>(/g
C casts do not require parentheses. C++ casts require grouping around
the target. Prepare for conversion to C++ casts by adding otherwise
unnecessary parentheses around the target of simple C casts.
This pass does not attempt to process expressions that involve
any subexpression that can nest arbitrarily, such as parentheses or
brackets. It also works only on commonly used standard types.
(int) a->b; // changed
(int) a[b]; // not changed
s/\((\s*\(\(un\)\?signed\|int\|char\|short\|long\|float\|double\|s\?size_t\|\(u\?int[[:digit:]]\+_t\)\)\s*\**\s*)\s*\)\([&+-]\?\)\([[:alnum:]_.]\+\s*->\s*\)*\([[:alnum:]_.]\+\)\(\s*\([];+>)*\/^%,|&<>]\)\|$\|\(\s*-\s*[^>]\)\)/\1(\5\6\7)\8/g