When a robot drops a robot, the dropped robot is not added to the
level's running accumulated_robots counter, but when the player destroys
that robot, the destruction will be counted. This imbalance allows the
expression counting the number of not-yet-destroyed robots to underflow,
which then confuses the matcen logic into not creating new robots.
Fix this by incrementing the accumulated_robots count as each dropped
robot is created.
Reported-by: ziplantil <https://github.com/dxx-rebirth/dxx-rebirth/issues/466>
As documented in zico's commit 38fabd7c49, robot smart mines have a
different ID number than player smart mines. Rename the test functions
to clarify that they only recognize player smart mines, but not robot
smart mines.
git grep -l is_proximity_bomb_or_smart_mine | xargs sed -i -e 's/is_proximity_bomb_or_smart_mine/is_proximity_bomb_or_player_smart_mine/g'
`explode_badass_player` can pass an OBJ_PLAYER, not an OBJ_WEAPON, as
`obj_explosion_origin`. Using `get_weapon_id` on a non-weapon is wrong
and provokes a diagnostic. The test tries to check if the passed object
is _not_ a flash missile. Players are not flash missiles, so maintain
the intended semantics by treating non-weapons as not-flash-missiles.
Reported-by: Johnsondr80 <https://github.com/dxx-rebirth/dxx-rebirth/issues/437>
`objp`, `obj`, and `obj0p` is not helpful when trying to reason about
the logic of this function. Rename them to `obj_explosion_origin`,
`obj_fireball`, and `obj_iter`, respectively.
This removes the need to walk all objects when creating a new one, since
each object can have a private generation counter, unaware of other
objects. For compatibility with demos, mix in the object's index when
writing the signature value.
In multiplayer, the host sends a destroy message for both sides of the
wall. `do_exploding_wall_frame` processes both, but
`num_exploding_walls` is only decreased by 1, causing an assertion
failure at the end. Remove the assertion, since the wall does not
explode instantly on join, despite being marked as WALL_EXPLODING.
digi_play_sample_once is supposed to cancel prior instances of the
sound, but that functionality was lost in
21082c6db2. As a result, the sound can be
stacked up to the limit of the engine. Even when the functionality
existed, its implementation was wrong.
- Change these sounds to be attached to the player generating them.
- Pass the cancellation flag to other players when sending a sound.
- Send the full value of `volume`, rather than truncating it.
- Implement cancellation by killing and restarting the earlier version of a cancelled sound.
- Delete an ugly hack that prevented the patched logic from ever running.
- Fix an ancient quirk in digi_mixer that caused it to report all sounds as not playing, which then caused digi_sync_sounds to instantly cancel the new sound.
Reported-by: Mako88 <https://github.com/dxx-rebirth/dxx-rebirth/issues/88>
Reported-by: ryusei117 <https://github.com/dxx-rebirth/dxx-rebirth/issues/88#issuecomment-269597361>
Fixes: 21082c6db2 ("Added own channel management to SDL_mixer sound interface since the builtin channel management of this lib cannot handle our needs; Little code cleanup")
This backports into Descent 1 the special-case that loads a Vulcan
cannon when it is dropped. It also fixes a longstanding bug that a
robot that drops more than one of the powerup would fill only one of
them.
Previously, valptridx used PREFIX for allow-invalid+mutable, c#PREFIX
for allow-invalid+const, v#PREFIX for require-valid+mutable, vc#PREFIX
for require-valid+const. Convert the types, factories, and all usage
sites to specify a qualifier for all four combinations:
im#PREFIX -> allow-invalid+mutable
ic#PREFIX -> allow-invalid+const
vm#PREFIX -> require-valid+mutable
vc#PREFIX -> require-valid+const
Changes to common/include/valptridx.h and common/include/fwd-valptridx.h
are manual. All other changes are generated by:
git grep -lz -e '\(obj\|seg\|clwall\|wall\|actdoor\|trg\)\(ptridx\|ptr\|idx\)\(_t\)\?\>' | xargs -0 sed -i -e 's/\<\(v\?\)\(\(obj\|seg\|clwall\|wall\|actdoor\|trg\)\(ptridx\|ptr\|idx\)\(_t\)\?\)\>/\1m\2/g'
for the 'm' prefix and:
git grep -lz -e '\(obj\|seg\|clwall\|wall\|actdoor\|trg\)\(ptridx\|ptr\|idx\)\(_t\)\?\>' | xargs -0 sed -i -e 's/\<\([cm]\(obj\|seg\|clwall\|wall\|actdoor\|trg\)\(ptridx\|ptr\|idx\)\(_t\)\?\)\>/i&/g'
for the 'i' prefix.
Rebirth built with `gcc -fsanitize=undefined` warns when binding a
reference to nullptr, even if that reference is never followed. This
could be reproduced using a guided missile against the first PIG in
Descent 2: Counterstrike level 1.
This object pointer is used only to test for address equality, so
nullptr is safe here. Switch to pass it as a pointer to prevent the
warning.
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>
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.