Later commits will enable the player to press a movement key to respawn on death, then move with the same keypress. This commit makes sure the player stops moving when the key is released.
Movement handling has an ugly hack that tries to grab powerups near the
console player, but it reuses general collision handling and fails to
check whether the player is alive.
Add a liveness check. Place the check so that it happens once, before
the objects are scanned, rather than being needlessly repeated for every
object.
Refactor the collision code to let the movement hack skip the parts it
does not need.
Reported-by: ryusei117 <https://github.com/dxx-rebirth/dxx-rebirth/issues/302#issuecomment-275816259>
PCH mode causes the Valgrind-wrapper header to be included in places
it is not meant to be used, which leads to spurious compiler errors.
PCH mode causes the Valgrind-wrapper __real_* stub functions to see
the physfsx.h PHYSFS macros, which also causes errors.
Fortunately, both cases can be easily fixed.
Add preprocessor guards to the Valgrind-wrapper header to cause it to
compile out when the PCH phase runs. It has no include guard, so it
will be rescanned with the proper macros when the two consuming files
are built normally.
Modify the Valgrind-wrapper __real_* stub functions to use
the standard macro avoidance trick so that they do not call the
physfsx.h PHYSFS macros.
Kreator proposed restoring the Descent 2 cheat that grants homing
capability to all weapons. This commit implements that proposition,
with some changes to the implementation details.
Based-on-patch-by: Chris Taylor <chris@icculus.org>
Requested-by: Chris Taylor <https://github.com/dxx-rebirth/dxx-rebirth/pull/318>
Yarn reported that Descent 2: Counterstrike level 9 can place the
guidebot in a situation where
(Escort_goal_index == object_guidebot_cannot_reach &&
Escort_special_goal != ESCORT_GOAL_UNSPECIFIED)
If this happens and the player grabs a powerup, then the game crashes
trying to check if the grabbed powerup was of the type that the guidebot
sought. Since the guidebot was not seeking any object, the answer is
that this is not the sought object.
The design ought not set Escort_goal_index to an invalid object index,
but it does. Fixing that is too invasive for now. Add a special case
to prevent this crash.
Reported-by: Yarn <http://www.dxx-rebirth.com/frm/index.php/topic,2158.0.html>
Typing "BALDGUY" after enabling cheats will activate the 'baldguy' easter egg for D1X-Rebirth, which will show next time a briefing is shown featuring Dravis (Mac D1 data only). As with the original, it just plays the 'Cheater!' sound with no HUD message.
Pressing ALT-B when in the briefings using Mac Descent 1 data in D1X-Rebirth works again - showing Dravis wearing a silly hat. Before it would exit load_briefing_screen prematurely.
Function `object_create_explosion_sub` is supposed to be given a weapon
and an object on which to explode it. However, the original game abused
`object_create_explosion_sub` by also calling it from
`object_create_badass_explosion`, which can be called from
`explode_badass_object`, which can be called from
`explode_badass_player`. Chained together, this lets
`object_create_explosion_sub` check the weapon ID of a dying player,
which is not a valid operation. This causes a diagnostic from
`get_weapon_id`. Add an explicit test that the object is a weapon so
that non-weapons do not cause a diagnostic.
Reported-by: ryusei117 <https://github.com/dxx-rebirth/dxx-rebirth/issues/302#issuecomment-272048330>
Analyzed-by: zicodxx <https://github.com/dxx-rebirth/dxx-rebirth/issues/302#issuecomment-272710279>
Commit e36abb25cb fixed one problem with demo access (invalid bits in
the high byte of index values), but created another. That commit
switched from direct loading of `front_wall_num` to instead load into
`type`, then move the value to `front_wall_num`. However, `type` is
`sbyte` (an archaic spelling of `int8_t`), so assignments from `type` to
`front_wall_num` were implemented as a sign-extending move, rather than
a zero-extending move. When the wall number was 0x80 or greater, the
sign-extending move produced an incorrect result, which led to a crash
when valptridx trapped the invalid index.
Fix this by changing the types of all three byte-sized variables to
`uint8_t`. None of them need to be signed.
Reported-by: Dosgamer <http://www.dxx-rebirth.com/frm/index.php/topic,2151.0.html>
Fixes: e36abb25cb ("Fix invalid access reading demos")
`get_weapon_id` must be called only on objects of type `OBJ_WEAPON`.
One path in `multi_compute_kill` could call `get_weapon_id` on an object
that is either a robot or a weapon. The code tested for a robot, but
only after performing an access that assumed it had a weapon. Reorder
the tests to prevent the type mismatch diagnostic.
Reported-by: ryusei117 <https://github.com/dxx-rebirth/dxx-rebirth/issues/302#issuecomment-275546550>
By design, valptridx will throw an exception on invalid input. This is
better than silently permitting invalid input to corrupt program state.
Past releases blindly trusted that multiplayer peers would not send
invalid input. Conversion to the valptridx design eliminated the
undefined behavior when peers send invalid input, but still allowed
multiplayer peers to remotely crash the game by sending invalid inputs.
Add a mechanism to trap invalid inputs and gracefully ignore those
messages. This may cause game consistency issues, but will not allow
data corruption.
Contains 2 calls - to obj_create and init_ai_object. For safety reasons and tidiness compared to using obj_create directly. The call to init_ai_object in recreate_thief was already redundant.
All releases to date have a bug where they treat certain segment number
fields as an int, not a segment number. Storing segment_none (0xffff)
into the save file causes affected releases to crash in various places
because it fails to recognize that this is segment_none.
Current code correctly treats segment_none as a non-segment and works
correctly without this hack. The hack is only required to get past
releases to work correctly after loading a saved game written by current
code.
All releases to date have a bug where they treat MarkerObject as an int,
not an object number. Storing object_none (0xffff) into the save file
causes affected releases to exhibit several problems. Most obviously,
they crash if the automap is opened, because they try to show
Objects[0xffff] as a marker, but no such object exists. Additionally,
they refuse to let the player drop a marker because none of the elements
of MarkerObject are -1, so they incorrectly tell the player that all
marker slots are busy. Finally, they will crash if the guidebot is
killed, because the guidebot death code deletes marker 0xffff because it
fails to recognize that this is object_none.
Current code correctly treats object_none as a non-object and works
correctly without this hack. The hack is only required to get past
releases to work correctly after loading a saved game written by current
code.
Fixes: 9125ae32cd ("Make objnum unsigned")
All releases to date have a bug where they treat
Dead_controlcen_object_num as an int, not an object number. Storing
object_none (0xffff) into the save file causes affected releases to
crash when treating object_none as a valid object number.
Current code correctly treats object_none as a non-object and works
correctly without this hack. The hack is only required to get past
releases to survive destroying the reactor after loading a saved game
written by current code.
Fixes: 9125ae32cd ("Make objnum unsigned")
Fixes bug where in the editor, you insert a robot with normal behaviour then play the level - it fails the check on the hide_segment index in init_ai_objects(). This is because hide_segment was written as the poisoned value of 0xfdfd if the behaviour of the robot is AIB_NORMAL - because hide_segment wasn't initialised. Therefore, always setting hide_segment to suppress this exception (it's an inexpensive operation seldom called).
zicodxx reported a problem where poison=overwrite builds caused robots
dropped by other robots not to spawn. I diagnosed it as a problem
caused by not setting `dying_start_time` and proposed using
`init_ai_object` to set this (and other) fields. Kreatordxx posted pull
request #311 to implement this for dropped robots. However, his pull
had the unfortunate side effect of zeroing the dropped robot's velocity.
This change is based on his pull, but with the `init_ai_object` call
moved higher so that the velocity is (unnecessarily) zeroed by
`init_ai_object`, then initialized to `new_velocity` by `drop_powerup`
(as it always was).
Reported-by: zicodxx <https://github.com/dxx-rebirth/dxx-rebirth/issues/293>
Patch-inspired-by: kreatordxx <https://github.com/dxx-rebirth/dxx-rebirth/pull/311>
This is where a client in a multiplayer game hitting a wall fails an assert. Initialise obj->mtype.phys_info.flags in multi_reset_player_object() instead of adding flags. (Tested and still works OK without specifying PF_THRUST.)
Initialise ConsoleObject->mtype.phys_info.flags in reset_player_object() instead of adding flags. The only place this was initialised properly was when reading the player object from disk.
Use std::equal_range to find the upper and lower bounds in a single
binary search, rather than relying on a linear search to find the first
sought element.