Files
Goober5000andClaude Opus 4.6 3f85d6172a use std::move() for local variables that are copied but not reused (#7308)
* use std::move() for local variables that are copied but not reused

Addresses ~140 Coverity "Variable copied when it could be moved"
defects across 74 files.  Every std::move() targets a local variable
whose value is consumed by push_back, emplace, assignment, lambda
capture, or a function call and is never read again afterward.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* clang: use std::make_shared

* clang: use std::make_unique

* address feedback

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-05-07 14:40:38 +09:00

186 lines
5.6 KiB
C++

#include "cheats_table.h"
#include "parse/parselo.h"
void cheat_table_init() {
customCheats.clear();
if (cf_exists_full("cheats.tbl", CF_TYPE_TABLES)) {
parse_cheat_table("cheats.tbl");
}
parse_modular_table("*-cht.tbm", parse_cheat_table);
}
bool CustomCheat::canUseCheat() {
return !requireCheatsEnabled || Cheats_enabled;
}
void CustomCheat::runCheat() {
if (!canUseCheat()) return;
//Only try to send the message if we actually have one to send and are in a mission
if (!cheatMsg.empty() && (Game_mode & GM_IN_MISSION))
HUD_printf("%s", cheatMsg.c_str());
scripting::hooks::OnCheat->run(scripting::hook_param_list(scripting::hook_param("Cheat", 's', cheatCode)));
CheatUsed = cheatCode;
}
void SpawnShipCheat::runCheat() {
CustomCheat::runCheat();
if (canUseCheat() && (Game_mode & GM_IN_MISSION) && Player_obj != nullptr) {
extern void prevent_spawning_collision(object *new_obj);
ship_subsys *ptr;
char name[NAME_LENGTH];
int ship_idx, ship_class;
// if not found, then don't create it :(
ship_class = ship_info_lookup(shipClassName.c_str());
if (ship_class < 0)
return;
vec3d pos = Player_obj->pos;
matrix orient = Player_obj->orient;
pos.xyz.x += frand_range(-700.0f, 700.0f);
pos.xyz.y += frand_range(-700.0f, 700.0f);
pos.xyz.z += frand_range(-700.0f, 700.0f);
int objnum = ship_create(&orient, &pos, ship_class);
if (objnum < 0)
return;
ship *shipp = &Ships[Objects[objnum].instance];
shipp->ship_name[0] = '\0';
shipp->display_name.clear();
for (size_t j = 0; j < Player_orders.size(); j++)
shipp->orders_accepted.insert(j);
// Goober5000 - stolen from support ship creation
// create a name for the ship with a number. look for collisions until one isn't found anymore
ship_idx = 1;
do {
sprintf(name, "%s %d", shipName.c_str(), ship_idx);
if ( (ship_name_lookup(name) == -1) && (ship_find_exited_ship_by_name(name) == -1) )
{
strcpy_s(shipp->ship_name, name);
break;
}
ship_idx++;
} while(1);
shipp->flags.set(Ship::Ship_Flags::Escort);
shipp->escort_priority = 1000 - ship_idx;
// now make sure we're not colliding with anyone
prevent_spawning_collision(&Objects[objnum]);
// Goober5000 - beam free
for (ptr = GET_FIRST(&shipp->subsys_list); ptr != END_OF_LIST(&shipp->subsys_list); ptr = GET_NEXT(ptr))
{
// mark all turrets as beam free
if (ptr->system_info->type == SUBSYSTEM_TURRET)
{
ptr->weapons.flags.set(Ship::Weapon_Flags::Beam_Free);
ptr->turret_next_fire_stamp = timestamp(Random::next(50, 4000));
}
}
// Cyborg17 to prevent a nullptr...
ship_set_warp_effects(&Objects[objnum]);
// warpin
shipfx_warpin_start(&Objects[objnum]);
}
}
void parse_cheat_table(const char* filename) {
try {
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
optional_string("#CUSTOM CHEATS");
while (optional_string("$Cheat:")) {
SCP_string code, msg, shipClass, shipName;
bool requireCheats = false;
bool shipSpawn = false;
required_string("+Code:");
stuff_string(code, F_RAW);
//We are limited to the buffer size used for the traditional cheats. We can still use short cheats, though.
if (code.length() > CHEAT_BUFFER_LEN) {
Warning(LOCATION, "Cheat code %s is too long. It will be cut off to maximum length (%i characters).", code.c_str(), CHEAT_BUFFER_LEN);
code = code.substr(0, CHEAT_BUFFER_LEN);
}
if (optional_string("+Message:")) {
stuff_string(msg, F_MESSAGE);
}
if (optional_string("+RequireCheats:")) {
stuff_boolean(&requireCheats);
}
if (optional_string("+SpawnShip:")) {
shipSpawn = true;
required_string("+Name:");
stuff_string(shipName, F_NAME);
required_string("+Class:");
stuff_string(shipClass, F_NAME);
int shipClassInfo = ship_info_lookup(shipClass.c_str());
if (shipClassInfo < 0) {
shipSpawn = false;
Warning(LOCATION, "There is no ship class named '%s'. The '%s' cheat won't summon a ship.", shipClass.c_str(), code.c_str());
}
}
if (shipSpawn) {
std::unique_ptr<CustomCheat> shipCheat(new SpawnShipCheat(code, std::move(msg), requireCheats, std::move(shipClass), std::move(shipName)));
if(customCheats.count(code) == 1) {
Warning(LOCATION, "A cheat for code '%s' already exists. It will be replaced.", code.c_str());
customCheats[code] = std::move(shipCheat);
} else {
customCheats.emplace(code, std::move(shipCheat));
}
} else {
std::unique_ptr<CustomCheat> cheat(new CustomCheat(code, std::move(msg), requireCheats));
if(customCheats.count(code) == 1) {
Warning(LOCATION, "A cheat for code '%s' already exists. It will be replaced.", code.c_str());
customCheats[code] = std::move(cheat);
} else {
customCheats.emplace(code, std::move(cheat));
}
}
}
required_string("#END");
}
catch (const parse::ParseException& e) {
mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
return;
}
}
bool checkForCustomCheats(const char* buffer, int buffer_length) {
const char* check_buffer = buffer;
for (int i = 0; i < buffer_length; i++) {
if (*check_buffer == '\0') {
check_buffer++;
}
else {
break;
}
}
// Loop through our map of custom cheats and check if the code is within the buffer.
// We don't just check for equality, as the player may have typed other characters before the cheat.
for (auto &ccheat : customCheats) {
auto found = std::strstr(check_buffer, ccheat.first.c_str());
if (found != nullptr) {
ccheat.second->runCheat();
return true;
}
}
return false;
}