Skip to content

Commit

Permalink
Merge pull request scp-fs2open#6439 from Goober5000/weapon_script_enh…
Browse files Browse the repository at this point in the history
…ancements

add scripting support for weapon class "turret names"
  • Loading branch information
Goober5000 authored Dec 2, 2024
2 parents 5526f75 + 089c870 commit 2b84233
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 78 deletions.
79 changes: 1 addition & 78 deletions code/hud/hudtargetbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1639,78 +1639,6 @@ void HudGaugeExtraTargetData::endFlashDock()
flash_timer[0] = timestamp(0);
}

//from aicode.cpp. Less include...problems...this way.
extern flagset<Weapon::Info_Flags> turret_weapon_aggregate_flags(const ship_weapon *swp);
extern bool turret_weapon_has_subtype(const ship_weapon *swp, int subtype);

void get_turret_subsys_name(ship_weapon *swp, char *outstr)
{
Assert(swp != NULL); // Goober5000 //WMC

//WMC - find the first weapon, if there is one
if (swp->num_primary_banks || swp->num_secondary_banks) {
// allow the first weapon on the turret to specify the name
for (int i = 0; i < swp->num_primary_banks; ++i) {
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if (*(wip->altSubsysName) != '\0') {
sprintf(outstr, "%s", wip->altSubsysName);
return;
}
}
for (int i = 0; i < swp->num_secondary_banks; ++i) {
auto wip = &Weapon_info[swp->secondary_bank_weapons[i]];
if (*(wip->altSubsysName) != '\0') {
sprintf(outstr, "%s", wip->altSubsysName);
return;
}
}

// otherwise use a general name based on the type of weapon(s) on the turret
auto flags = turret_weapon_aggregate_flags(swp);

// check if beam or flak using weapon flags
if (flags[Weapon::Info_Flags::Beam]) {
sprintf(outstr, "%s", XSTR("Beam turret", 1567));
} else if (flags[Weapon::Info_Flags::Flak]) {
sprintf(outstr, "%s", XSTR("Flak turret", 1566));
} else {
if (turret_weapon_has_subtype(swp, WP_MISSILE)) {
sprintf(outstr, "%s", XSTR("Missile lnchr", 1569));
} else if (turret_weapon_has_subtype(swp, WP_LASER)) {
// ballistic too! - Goober5000
if (flags[Weapon::Info_Flags::Ballistic]) {
sprintf(outstr, "%s", XSTR("Turret", 1487));
}
// the TVWP has some primaries flagged as bombs
else if (flags[Weapon::Info_Flags::Bomb]) {
sprintf(outstr, "%s", XSTR("Missile lnchr", 1569));
} else {
sprintf(outstr, "%s", XSTR("Laser turret", 1568));
}
} else {
// Mantis #2226: find out if there are any weapons here at all
if (flags.none_set()) {
sprintf(outstr, "%s", NOX("Unused"));
} else {
// Illegal subtype
static bool Turret_illegal_subtype_warned = false;
if (!Turret_illegal_subtype_warned) {
Turret_illegal_subtype_warned = true;
Warning(LOCATION, "This turret has an illegal subtype! Trace out and fix!");
}
sprintf(outstr, "%s", XSTR("Turret", 1487));
}
}
}
} else if(swp->num_tertiary_banks) {
//TODO: add tertiary turret code stuff here
sprintf(outstr, "%s", NOX("Unknown"));
} else {
// This should not happen
sprintf(outstr, "%s", NOX("Unused"));
}
}

void HudGaugeTargetBox::renderTargetShipInfo(object *target_objp)
{
ship *target_shipp;
Expand Down Expand Up @@ -1805,12 +1733,7 @@ void HudGaugeTargetBox::renderTargetShipInfo(object *target_objp)

maybeFlashElement(TBOX_FLASH_SUBSYS);

// get turret subsys name
if (Player_ai->targeted_subsys->system_info->type == SUBSYSTEM_TURRET && !ship_subsys_has_instance_name(Player_ai->targeted_subsys)) {
get_turret_subsys_name(&Player_ai->targeted_subsys->weapons, outstr);
} else {
sprintf(outstr, "%s", ship_subsys_get_name(Player_ai->targeted_subsys));
}
sprintf(outstr, "%s", ship_subsys_get_name_on_hud(Player_ai->targeted_subsys));

char *p_line;
// hence pipe shall be the linebreak
Expand Down
16 changes: 16 additions & 0 deletions code/scripting/api/objs/subsystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,22 @@ ADE_VIRTVAR(Name, l_Subsystem, "string", "Subsystem name", "string", "Subsystem
return ade_set_args(L, "s", ship_subsys_get_name(sso->ss));
}

ADE_VIRTVAR(NameOnHUD, l_Subsystem, "string", "Subsystem name as it would be displayed on the HUD", "string", "Subsystem name on HUD, or an empty string if handle is invalid")
{
ship_subsys_h *sso;

if (!ade_get_args(L, "o", l_Subsystem.GetPtr(&sso)))
return ade_set_error(L, "s", "");

if (!sso->isValid())
return ade_set_error(L, "s", "");

if (ADE_SETTING_VAR)
LuaError(L, "Setting the NameOnHUD is not allowed!");

return ade_set_args(L, "s", ship_subsys_get_name_on_hud(sso->ss));
}

ADE_VIRTVAR(NumFirePoints, l_Subsystem, "number", "Number of firepoints", "number", "Number of fire points, or 0 if handle is invalid")
{
ship_subsys_h* sso;
Expand Down
19 changes: 19 additions & 0 deletions code/scripting/api/objs/weaponclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,25 @@ ADE_VIRTVAR(AltName, l_Weaponclass, "string", "The alternate weapon class name."
return ade_set_args(L, "s", Weapon_info[idx].display_name);
}

ADE_VIRTVAR(TurretName, l_Weaponclass, "string", "The name displayed for a turret if the turret's first weapon is this weapon class.", "string", "Turret name (aka alternate subsystem name), or empty string if handle is invalid")
{
int idx;
const char* s = nullptr;
if(!ade_get_args(L, "o|s", l_Weaponclass.Get(&idx), &s))
return ade_set_error(L, "s", "");

if(idx < 0 || idx >= weapon_info_size())
return ade_set_error(L, "s", "");

if(ADE_SETTING_VAR && s != nullptr) {
auto len = sizeof(Weapon_info[idx].altSubsysName);
strncpy(Weapon_info[idx].altSubsysName, s, len);
Weapon_info[idx].altSubsysName[len - 1] = 0;
}

return ade_set_args(L, "s", Weapon_info[idx].altSubsysName);
}

ADE_VIRTVAR(Title, l_Weaponclass, "string", "Weapon class title", "string", "Weapon class title, or empty string if handle is invalid")
{
int idx;
Expand Down
79 changes: 79 additions & 0 deletions code/ship/ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16998,6 +16998,85 @@ bool ship_subsys_has_instance_name(const ship_subsys *ss)

void ship_subsys_set_name(ship_subsys* ss, const char* n_name) { strncpy(ss->sub_name, n_name, NAME_LENGTH - 1); }

//from aiturret.cpp. Less include...problems...this way.
extern flagset<Weapon::Info_Flags> turret_weapon_aggregate_flags(const ship_weapon *swp);
extern bool turret_weapon_has_subtype(const ship_weapon *swp, int subtype);

const char *get_turret_subsys_name(const ship_weapon *swp)
{
Assert(swp != nullptr); // Goober5000 //WMC

//WMC - find the first weapon, if there is one
if (swp->num_primary_banks || swp->num_secondary_banks) {
// allow the first weapon on the turret to specify the name
for (int i = 0; i < swp->num_primary_banks; ++i) {
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if (*(wip->altSubsysName) != '\0') {
return wip->altSubsysName;
}
}
for (int i = 0; i < swp->num_secondary_banks; ++i) {
auto wip = &Weapon_info[swp->secondary_bank_weapons[i]];
if (*(wip->altSubsysName) != '\0') {
return wip->altSubsysName;
}
}

// otherwise use a general name based on the type of weapon(s) on the turret
auto flags = turret_weapon_aggregate_flags(swp);

// check if beam or flak using weapon flags
if (flags[Weapon::Info_Flags::Beam]) {
return XSTR("Beam turret", 1567);
} else if (flags[Weapon::Info_Flags::Flak]) {
return XSTR("Flak turret", 1566);
} else {
if (turret_weapon_has_subtype(swp, WP_MISSILE)) {
return XSTR("Missile lnchr", 1569);
} else if (turret_weapon_has_subtype(swp, WP_LASER)) {
// ballistic too! - Goober5000
if (flags[Weapon::Info_Flags::Ballistic]) {
return XSTR("Turret", 1487);
}
// the TVWP has some primaries flagged as bombs
else if (flags[Weapon::Info_Flags::Bomb]) {
return XSTR("Missile lnchr", 1569);
} else {
return XSTR("Laser turret", 1568);
}
} else {
// Mantis #2226: find out if there are any weapons here at all
if (flags.none_set()) {
return NOX("Unused");
} else {
// Illegal subtype
static bool Turret_illegal_subtype_warned = false;
if (!Turret_illegal_subtype_warned) {
Turret_illegal_subtype_warned = true;
Warning(LOCATION, "This turret has an illegal subtype! Trace out and fix!");
}
return XSTR("Turret", 1487);
}
}
}
} else if(swp->num_tertiary_banks) {
//TODO: add tertiary turret code stuff here
return NOX("Unknown");
} else {
// This should not happen
return NOX("Unused");
}
}

const char *ship_subsys_get_name_on_hud(const ship_subsys *ss)
{
// get turret subsys name
if (ss->system_info->type == SUBSYSTEM_TURRET && !ship_subsys_has_instance_name(ss))
return get_turret_subsys_name(&ss->weapons);
else
return ship_subsys_get_name(ss);
}

/**
* Return the shield strength of the specified quadrant on hit_objp
*
Expand Down
2 changes: 2 additions & 0 deletions code/ship/ship.h
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,8 @@ const char *ship_subsys_get_name(const ship_subsys *ss);
bool ship_subsys_has_instance_name(const ship_subsys *ss);
void ship_subsys_set_name(ship_subsys* ss, const char* n_name);

const char *ship_subsys_get_name_on_hud(const ship_subsys *ss);

// subsys disruption
extern int ship_subsys_disrupted(const ship_subsys *ss);
extern int ship_subsys_disrupted(const ship *sp, int type);
Expand Down

0 comments on commit 2b84233

Please sign in to comment.