Skip to content

Commit

Permalink
Merge pull request #5561 from Goober5000/special_warp_physics
Browse files Browse the repository at this point in the history
add "special warp physics" to custom warpin parameters
  • Loading branch information
Goober5000 authored Oct 15, 2023
2 parents e132fcf + 6b3e50d commit a20f3ca
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 @@ -2865,7 +2865,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 @@ -2845,20 +2845,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 @@ -2871,6 +2886,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 @@ -2883,15 +2899,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 @@ -255,6 +255,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 @@ -2646,7 +2646,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 @@ -2677,7 +2677,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 @@ -2699,7 +2699,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 @@ -2711,7 +2711,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 @@ -2722,7 +2722,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 @@ -2733,7 +2733,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 @@ -2744,7 +2744,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 @@ -2753,6 +2753,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 @@ -2763,7 +2773,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 @@ -3507,17 +3517,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 @@ -2287,13 +2287,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 @@ -2305,15 +2305,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 @@ -3355,6 +3355,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 @@ -1228,6 +1228,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 @@ -3271,6 +3271,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 a20f3ca

Please sign in to comment.