Skip to content

Commit

Permalink
add "special warp physics" to custom warpin parameters
Browse files Browse the repository at this point in the history
Supercaps use a physics flag on warpin that makes them slow down faster than they would under the normal physics code.  This adds that flag as an option for custom warp parameters.

Since flags are not yet parsed when warp parameters are parsed, the code needs to skip ahead and peek at the flags in the same way as the weapon override.
  • Loading branch information
Goober5000 committed Aug 16, 2023
1 parent 03f0160 commit 6b3e50d
Show file tree
Hide file tree
Showing 13 changed files with 107 additions and 32 deletions.
2 changes: 1 addition & 1 deletion code/mission/missionparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2855,7 +2855,7 @@ bool p_object::has_display_name() {
return flags[Mission::Parse_Object_Flags::SF_Has_display_name];
}

extern int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, const char *info_type_name, const char *sip_name);
extern int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, const char *info_type_name, const char *sip_name, bool set_special_warp_physics = false);

/**
* Mp points at the text of an object, which begins with the "$Name:" field.
Expand Down
33 changes: 23 additions & 10 deletions code/parse/parselo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2844,20 +2844,35 @@ void stuff_boolean_flag(int *i, int flag, bool a_to_eol)
// Stuffs a boolean value pointed at by Mp.
// YES/NO (supporting 1/0 now as well)
// Now supports localization :) -WMC

void stuff_boolean(bool *b, bool a_to_eol)
{
char token[32];
stuff_string_white(token, sizeof(token)/sizeof(char));
char token[NAME_LENGTH];
stuff_string_white(token);
if(a_to_eol)
advance_to_eoln(NULL);

if( isdigit(token[0]))
if (!parse_boolean(token, b))
{
*b = false;
error_display(0, "Boolean '%s' type unknown; assuming 'no/false'", token);
}

diag_printf("Stuffed bool: %s\n", (b) ? NOX("true") : NOX("false"));
}

// Parses a token into a boolean value, if the token is recognized. If so, the boolean parameter is assigned the value and the function returns true;
// if not, the boolean parameter is not assigned and the function returns false.
bool parse_boolean(const char *token, bool *b)
{
Assertion(token != nullptr && b != nullptr, "Parameters must not be NULL!");

if(isdigit(token[0]))
{
if(token[0] != '0')
*b = true;
else
*b = false;
return true;
}
else
{
Expand All @@ -2870,6 +2885,7 @@ void stuff_boolean(bool *b, bool a_to_eol)
|| !stricmp(token, "HIja'") || !stricmp(token, "HISlaH")) //Klingon
{
*b = true;
return true;
}
else if(!stricmp(token, "no")
|| !stricmp(token, "false")
Expand All @@ -2882,15 +2898,12 @@ void stuff_boolean(bool *b, bool a_to_eol)
|| !stricmp(token, "ghobe'")) //Klingon
{
*b = false;
}
else
{
*b = false;
error_display(0, "Boolean '%s' type unknown; assuming 'no/false'",token);
return true;
}
}

diag_printf("Stuffed bool: %s\n", (b) ? NOX("true") : NOX("false"));
// token not recognized
return false;
}

// Stuff an integer value (cast to a ubyte) pointed at by Mp.
Expand Down
1 change: 1 addition & 0 deletions code/parse/parselo.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ extern void stuff_parenthesized_vec3d(vec3d *vp);
extern void stuff_boolean(int *i, bool a_to_eol=true);
extern void stuff_boolean(bool *b, bool a_to_eol=true);
extern void stuff_boolean_flag(int *i, int flag, bool a_to_eol=true);
extern bool parse_boolean(const char *token, bool*b);

template <class T>
int string_lookup(const char* str1, T strlist, size_t max, const char* description = nullptr, bool say_errors = false)
Expand Down
58 changes: 47 additions & 11 deletions code/ship/ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2641,7 +2641,7 @@ static int parse_and_add_briefing_icon_info()
*
* If we are creating a ship, we want to inherit the parameters of the ship class, then override on a field-by-field basis.
*/
int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, const char *info_type_name, const char *info_name)
int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, const char *info_type_name, const char *info_name, bool set_special_warp_physics)
{
Assert(info_type_name != nullptr);
Assert(info_name != nullptr);
Expand Down Expand Up @@ -2672,7 +2672,7 @@ int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, c
params.warp_type = j | WT_DEFAULT_WITH_FIREBALL;
}
else {
Warning(LOCATION, "Invalid %s '%s' specified for %s '%s'", str, buf, info_type_name, info_name);
error_display(0, "Invalid %s '%s' specified for %s '%s'", str, buf, info_type_name, info_name);
params.warp_type = WT_DEFAULT;
}
}
Expand All @@ -2694,7 +2694,7 @@ int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, c
if (t_time > 0.0f)
params.warpout_engage_time = fl2i(t_time*1000.0f);
else
Warning(LOCATION, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
error_display(0, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
}
}

Expand All @@ -2706,7 +2706,7 @@ int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, c
if (speed > 0.0f)
params.speed = speed;
else
Warning(LOCATION, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
error_display(0, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
}

sprintf(str, "%s time:", prefix);
Expand All @@ -2717,7 +2717,7 @@ int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, c
if (t_time > 0.0f)
params.time = fl2i(t_time*1000.0f);
else
Warning(LOCATION, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
error_display(0, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
}

sprintf(str, "%s %s exp:", prefix, direction == WarpDirection::WARP_IN ? "decel" : "accel");
Expand All @@ -2728,7 +2728,7 @@ int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, c
if (accel_exp >= 0.0f)
params.accel_exp = accel_exp;
else
Warning(LOCATION, "%s specified as less than 0 on %s '%s'; value ignored", str, info_type_name, info_name);
error_display(0, "%s specified as less than 0 on %s '%s'; value ignored", str, info_type_name, info_name);
}

sprintf(str, "%s radius:", prefix);
Expand All @@ -2739,7 +2739,7 @@ int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, c
if (rad > 0.0f)
params.radius = rad;
else
Warning(LOCATION, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
error_display(0, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
}

sprintf(str, "%s animation:", prefix);
Expand All @@ -2748,6 +2748,16 @@ int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, c
stuff_string(params.anim, F_NAME, MAX_FILENAME_LEN);
}

// we might need to explicitly set this flag; but if so, the modder has the option of unsetting it
if (set_special_warp_physics)
params.special_warp_physics = true;

sprintf(str, "$Special warp%s physics:", (direction == WarpDirection::WARP_IN) ? "in" : "out");
if (optional_string(str))
{
stuff_boolean(&params.special_warp_physics);
}

if (direction == WarpDirection::WARP_OUT)
{
sprintf(str, "$Player warpout speed:");
Expand All @@ -2758,7 +2768,7 @@ int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, c
if (speed > 0.0f)
params.warpout_player_speed = speed;
else
Warning(LOCATION, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
error_display(0, "%s specified as 0 or less on %s '%s'; value ignored", str, info_type_name, info_name);
}
}

Expand Down Expand Up @@ -3502,17 +3512,43 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
}
}

// the first time we get to this point, initialize to the species parameter indexes (which may be -1)
bool is_supercap_for_warp_params = false;
if (first_time) {
// the first time we get to this point, initialize to the species parameter indexes (which may be -1)
sip->warpin_params_index = Species_info[sip->species].warpin_params_index;
sip->warpout_params_index = Species_info[sip->species].warpout_params_index;

// figure out whether this is a supercap by doing some parse gymnastics
// (flags are parsed several lines later, so we need to skip ahead, peek at the flags, and jump back)
pause_parse();
if (skip_to_string("$Flags:", "$Name:") == 1) {
// cache the flag definition so we don't have to keep looking it up
static auto supercap_flag_def = std::find_if(std::begin(Ship_flags), std::end(Ship_flags), [](const flag_def_list_new<Info_Flags> &item) {
return item.def == Ship::Info_Flags::Supercap;
});

// look up the flag in this flag list
if (supercap_flag_def != std::end(Ship_flags)) {
SCP_vector<SCP_string> flags;
stuff_string_list(flags);
auto supercap_string = std::find_if(flags.begin(), flags.end(), [](const SCP_string& item) {
return lcase_equal(item, supercap_flag_def->name);
});
if (supercap_string != flags.end()) {
is_supercap_for_warp_params = true;
}
}
}
unpause_parse();
}

// get ship parameters for warpin and warpout
// Note: if the index is not -1, we must have already assigned warp parameters, probably because we are now
// parsing a TBM. In that case, inherit from ourselves.
sip->warpin_params_index = parse_warp_params(sip->warpin_params_index >= 0 ? &Warp_params[sip->warpin_params_index] : nullptr, WarpDirection::WARP_IN, info_type_name, sip->name);
sip->warpout_params_index = parse_warp_params(sip->warpout_params_index >= 0 ? &Warp_params[sip->warpout_params_index] : nullptr, WarpDirection::WARP_OUT, info_type_name, sip->name);
// Note2: In retail, supercaps have the PF_SPECIAL_WARP_IN applied by default (but not PF_SPECIAL_WARP_OUT). So,
// if we are parsing a supercap for the first time, and this is a warpin, set the flag.
sip->warpin_params_index = parse_warp_params(sip->warpin_params_index >= 0 ? &Warp_params[sip->warpin_params_index] : nullptr, WarpDirection::WARP_IN, info_type_name, sip->name, first_time && is_supercap_for_warp_params);
sip->warpout_params_index = parse_warp_params(sip->warpout_params_index >= 0 ? &Warp_params[sip->warpout_params_index] : nullptr, WarpDirection::WARP_OUT, info_type_name, sip->name, false);

// get ship explosion info
shockwave_create_info *sci = &sip->shockwave;
Expand Down
12 changes: 8 additions & 4 deletions code/ship/shipfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3197,6 +3197,7 @@ bool WarpParams::operator==(const WarpParams &other)
&& time == other.time
&& accel_exp == other.accel_exp
&& warp_type == other.warp_type
&& special_warp_physics == other.special_warp_physics
&& warpout_engage_time == other.warpout_engage_time
&& warpout_player_speed == other.warpout_player_speed;
}
Expand Down Expand Up @@ -3507,9 +3508,12 @@ int WE_Default::warpStart()
compute_warpout_stuff(&effect_time, &pos);
effect_time += SHIPFX_WARP_DELAY;

if (sip->flags[Ship::Info_Flags::Supercap]) {
// turn off warpin physics in case we're jumping out immediately
objp->phys_info.flags &= ~PF_SPECIAL_WARP_IN;
// turn off warpin physics in case we're jumping out immediately
objp->phys_info.flags &= ~PF_SPECIAL_WARP_IN;

// maybe turn on warpout physics
if (params->special_warp_physics) {
objp->phys_info.flags |= PF_SPECIAL_WARP_OUT;
}
}

Expand Down Expand Up @@ -3628,7 +3632,7 @@ int WE_Default::warpFrame(float frametime)
this->warpEnd();

// notify physics to slow down
if (sip->flags[Ship::Info_Flags::Supercap]) {
if (params->special_warp_physics) {
// let physics know this is a special warp in
objp->phys_info.flags |= PF_SPECIAL_WARP_IN;
}
Expand Down
1 change: 1 addition & 0 deletions code/ship/shipfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class WarpParams
int time = 0; // in ms
float accel_exp = 1.0f;
int warp_type = WT_DEFAULT;
bool special_warp_physics = false;

// only valid for warpout
int warpout_engage_time = -1; // in ms
Expand Down
2 changes: 1 addition & 1 deletion code/species_defs/species_defs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "ship/shipfx.h"
#include "species_defs/species_defs.h"

extern int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, const char *info_type_name, const char *info_name);
extern int parse_warp_params(const WarpParams *inherit_from, WarpDirection direction, const char *info_type_name, const char *info_name, bool set_special_warp_physics = false);

SCP_vector<species_info> Species_info;

Expand Down
12 changes: 7 additions & 5 deletions fred2/fred.rc
Original file line number Diff line number Diff line change
Expand Up @@ -2286,13 +2286,13 @@ BEGIN
PUSHBUTTON "IDB_PLAY",IDC_PLAY,235,62,17,15,BS_BITMAP,WS_EX_TRANSPARENT
END

IDD_WARP_PARAMS DIALOGEX 0, 0, 271, 252
IDD_WARP_PARAMS DIALOGEX 0, 0, 271, 271
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Warp Parameters"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,161,231,50,14
PUSHBUTTON "Cancel",IDCANCEL,214,231,50,14
DEFPUSHBUTTON "OK",IDOK,161,250,50,14
PUSHBUTTON "Cancel",IDCANCEL,214,250,50,14
LTEXT "Warp Type",IDC_STATIC,7,41,99,8
COMBOBOX IDC_WARP_TYPE,161,39,103,196,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Start Sound",IDC_STATIC,7,60,99,8
Expand All @@ -2304,15 +2304,17 @@ BEGIN
LTEXT "Acceleration Exponent (Hyperspace Only)",IDC_ACCEL_EXP_LABEL,7,155,143,8,WS_DISABLED
LTEXT "Radius",IDC_STATIC,7,174,99,8
LTEXT "Animation (Homeworld Only)",IDC_ANIM_LABEL,7,193,99,8,WS_DISABLED
LTEXT "Player Warpout Speed",IDC_PLAYER_WARPOUT_SPEED_LABEL,7,212,99,8,WS_DISABLED
LTEXT "Special Warp Physics",IDC_STATIC,7,212,99,8
LTEXT "Player Warpout Speed",IDC_PLAYER_WARPOUT_SPEED_LABEL,7,231,99,8,WS_DISABLED
EDITTEXT IDC_END_SOUND,161,77,103,12,ES_AUTOHSCROLL
EDITTEXT IDC_WARPOUT_ENGAGE_TIME,161,96,103,12,ES_AUTOHSCROLL
EDITTEXT IDC_SPEED,161,115,103,12,ES_AUTOHSCROLL
EDITTEXT IDC_TIME,161,134,103,12,ES_AUTOHSCROLL
EDITTEXT IDC_ACCEL_EXP,161,153,103,12,ES_AUTOHSCROLL
EDITTEXT IDC_RADIUS,161,172,103,12,ES_AUTOHSCROLL
EDITTEXT IDC_ANIM,161,191,103,12,ES_AUTOHSCROLL
EDITTEXT IDC_PLAYER_WARPOUT_SPEED,161,210,103,12,ES_AUTOHSCROLL
CONTROL "",IDC_SPECIAL_WARP_PHYSICS,"Button",BS_AUTOCHECKBOX,161,210,103,12
EDITTEXT IDC_PLAYER_WARPOUT_SPEED,161,229,103,12,ES_AUTOHSCROLL
LTEXT "All of these parameters are optional, and a mission designer will usually not need to override more than one or two. These parameters are the same as those found in ships.tbl.",IDC_STATIC,7,7,257,29
END

Expand Down
5 changes: 5 additions & 0 deletions fred2/missionsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3346,6 +3346,11 @@ int CFred_mission_save::save_warp_params(WarpDirection direction, ship *shipp)
fout("\n%s animation: %s", prefix, shipp_params->anim);
}

if (shipp_params->special_warp_physics != sip_params->special_warp_physics)
{
fout("\n$Special warp%s physics: %s", direction == WarpDirection::WARP_IN ? "in" : "out", shipp_params->special_warp_physics ? "YES" : "NO");
}

if (direction == WarpDirection::WARP_OUT && shipp_params->warpout_player_speed != sip_params->warpout_player_speed)
{
if (shipp_params->warpout_player_speed > 0.0f)
Expand Down
1 change: 1 addition & 0 deletions fred2/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,7 @@
#define IDC_SPIN_EM_FALLOFF 1695
#define IDC_SPIN_NOISE_COLOR_B 1696
#define IDC_NOISE_COLOR_B 1697
#define IDC_SPECIAL_WARP_PHYSICS 1698
#define IDC_NOISE_INTENSITY 1700
#define IDC_SPIN_NOISE_INTENSITY 1701
#define IDC_NOISE_RESOLUTION 1702
Expand Down
6 changes: 6 additions & 0 deletions fred2/warpparamsdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ warp_params_dlg::warp_params_dlg(CWnd* pParent) : CDialog(warp_params_dlg::IDD,
m_accel_exp = _T("");
m_radius = _T("");
m_anim = _T("");
m_special_warp_physics = FALSE;
m_player_warpout_speed = _T("");
//}}AFX_DATA_INIT
}
Expand All @@ -49,6 +50,7 @@ void warp_params_dlg::DoDataExchange(CDataExchange* pDX)
DDX_Text(pDX, IDC_ACCEL_EXP, m_accel_exp);
DDX_Text(pDX, IDC_RADIUS, m_radius);
DDX_Text(pDX, IDC_ANIM, m_anim);
DDX_Check(pDX, IDC_SPECIAL_WARP_PHYSICS, m_special_warp_physics);
DDX_Text(pDX, IDC_PLAYER_WARPOUT_SPEED, m_player_warpout_speed);
//}}AFX_DATA_MAP
}
Expand Down Expand Up @@ -124,6 +126,8 @@ BOOL warp_params_dlg::OnInitDialog()
if (strlen(params->anim) > 0)
m_anim = params->anim;

m_special_warp_physics = params->special_warp_physics ? TRUE : FALSE;

if (params->warpout_player_speed > 0.0f)
m_player_warpout_speed.Format(_T("%.2f"), params->warpout_player_speed);
}
Expand Down Expand Up @@ -229,6 +233,8 @@ void warp_params_dlg::OnOK()
if (m_anim.GetLength() > 0)
strcpy_s(params.anim, m_anim);

params.special_warp_physics = (m_special_warp_physics == TRUE);

if (!m_warp_in && m_player_warpout_speed.GetLength() > 0)
{
float speed = (float)atof(m_player_warpout_speed);
Expand Down
1 change: 1 addition & 0 deletions fred2/warpparamsdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class warp_params_dlg : public CDialog
CString m_accel_exp;
CString m_radius;
CString m_anim;
BOOL m_special_warp_physics;
CString m_player_warpout_speed;
//}}AFX_DATA

Expand Down
5 changes: 5 additions & 0 deletions qtfred/src/mission/missionsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3262,6 +3262,11 @@ int CFred_mission_save::save_warp_params(WarpDirection direction, ship *shipp)
fout("\n%s animation: %s", prefix, shipp_params->anim);
}

if (shipp_params->special_warp_physics != sip_params->special_warp_physics)
{
fout("\n$Special warp%s physics: %s", direction == WarpDirection::WARP_IN ? "in" : "out", shipp_params->special_warp_physics ? "YES" : "NO");
}

if (direction == WarpDirection::WARP_OUT && shipp_params->warpout_player_speed != sip_params->warpout_player_speed)
{
if (shipp_params->warpout_player_speed > 0.0f)
Expand Down

0 comments on commit 6b3e50d

Please sign in to comment.