diff --git a/code/mod_table/mod_table.cpp b/code/mod_table/mod_table.cpp index cebd454ea26..c49f942be69 100644 --- a/code/mod_table/mod_table.cpp +++ b/code/mod_table/mod_table.cpp @@ -190,6 +190,7 @@ float Min_radius_for_persistent_debris; bool Zero_radius_explosions_skip_fireballs; bool Render_insignias_as_decals; bool Link_special_point_subsystems_to_destroyed_submodels; +bool Negate_warpout_jostle; #ifdef WITH_DISCORD @@ -1686,6 +1687,10 @@ void parse_mod_table(const char *filename) stuff_boolean(&Link_special_point_subsystems_to_destroyed_submodels); } + if (optional_string("$Negate warpout jostle:")) { + stuff_boolean(&Negate_warpout_jostle); + } + // end of options ---------------------------------------- // if we've been through once already and are at the same place, force a move @@ -1968,6 +1973,7 @@ void mod_table_reset() Zero_radius_explosions_skip_fireballs = false; Render_insignias_as_decals = false; Link_special_point_subsystems_to_destroyed_submodels = false; + Negate_warpout_jostle = false; } void mod_table_set_version_flags() @@ -1999,5 +2005,6 @@ void mod_table_set_version_flags() if (mod_supports_version(26, 0, 0)) { Zero_radius_explosions_skip_fireballs = true; Render_insignias_as_decals = true; + Negate_warpout_jostle = true; } } diff --git a/code/mod_table/mod_table.h b/code/mod_table/mod_table.h index ea1a9be939a..2189dfd08b9 100644 --- a/code/mod_table/mod_table.h +++ b/code/mod_table/mod_table.h @@ -210,6 +210,7 @@ extern float Min_radius_for_persistent_debris; extern bool Zero_radius_explosions_skip_fireballs; extern bool Render_insignias_as_decals; extern bool Link_special_point_subsystems_to_destroyed_submodels; +extern bool Negate_warpout_jostle; void mod_table_init(); void mod_table_post_process(); diff --git a/code/weapon/shockwave.cpp b/code/weapon/shockwave.cpp index 651a7443fc7..9be1da8ce97 100644 --- a/code/weapon/shockwave.cpp +++ b/code/weapon/shockwave.cpp @@ -16,6 +16,7 @@ #include "model/modelrender.h" #include "nebula/neb.h" #include "object/object.h" +#include "playerman/player.h" #include "options/Option.h" #include "render/3d.h" #include "render/batching.h" @@ -395,9 +396,31 @@ void shockwave_move(object *shockwave_objp, float frametime) } ship_apply_global_damage(objp, shockwave_objp, &sw->pos, damage, sw->damage_type_idx); - weapon_area_apply_blast(nullptr, objp, &sw->pos, blast, true); - break; + + bool is_warping = shipp->flags[Ship::Ship_Flags::Depart_warp]; + + // This covers the period when the ship is aligning and flying toward + // its warp-out point (AIM_WARP_OUT) but hasn't yet triggered the + // warp effect (Depart_warp). + // Note: AIS_DEPART_TO_BAY is excluded because it is a bay depart, not a warp. + if (Negate_warpout_jostle && !is_warping) { + if (shipp->ai_index >= 0) { + ai_info* aip = &Ai_info[shipp->ai_index]; + if (aip->mode == AIM_WARP_OUT && aip->submode != AIS_DEPART_TO_BAY) { + is_warping = true; + } + } + + if (!is_warping && objp == Player_obj && Player->control_mode == PCM_WARPOUT_STAGE1) { + is_warping = true; + } + } + + // Don't jostle the ship during warpout + if (!is_warping) { + weapon_area_apply_blast(nullptr, objp, &sw->pos, blast, true); } + } break; case OBJ_ASTEROID: weapon_area_apply_blast(nullptr, objp, &sw->pos, blast, true); asteroid_hit(objp, nullptr, nullptr, damage, nullptr);